Char unsigned number without signed or unsigned keywords? A signed number? The C standard stipulates implementation Defined!!!

Source: Internet
Author: User
Tags arithmetic error handling function definition scalar first row touch

Reprint Address:

Char and unsigned char are unsigned
Both are used words as words that are indistinguishable, but when integers are used differently:
Char integer range is-128 to 127 (0x80__0x7f),
The unsigned char integer range is 0 to 255 (0__0XFF)
In most cases, Char, signed char, unsigned char type data has the same characteristics however, when you assign a single byte number to a large integer field, you see the difference in the symbolic extension. Another difference is that when you assign a number between 128 and 255 to a signed char variable, the compiler must first convert the value, and a warning will also appear. It is convenient to use hexadecimal to assign values using unsigned char. Depending on the compiler's implementation, char is either equivalent to signed char or equivalent to unsigned char.

For code porting, be sure not to use char ... To use int8_t or uint8_t ...
ARM-LINUX-GCC Char to unsigned char ...
constants, expressed in hexadecimal (0x), represent unsigned numbers.
Char short when used, the compiler promotion to an int or unsigned int.

I always thought char represented a symbol, and unsigned char represented an unsigned one. It is now known that it would be fine to understand if you were to make a short or int, because the C standard is clearly defined. However, Char alone cannot understand this, because the C standard is impementation Defined, or undefined, and is clearly defined by the specific compiler.

The VC compiler, GCC on x86, defines Char as signed char, while ARM-LINUX-GCC defines char as unsigned char. As a result, there are problems with code porting. For the simplest example:

char a = 0xb6; if (a = = 0xb6) puts ("Hello world!");

In VC or x86 gcc, will not print out Hello world! Of Compiled with ARM-LINUX-GCC, on the arm board, it is possible to print out Hello world! Of  Isn't it amazing??? Let's change it again:

char a = 0xb6;
Short B = 0xb600;
int c = 0xb6000000;

if (a = = 0xb6) puts ("a");
if (b = = 0xb600) puts ("B");
if (c = = 0xb6000000) puts ("C");

In VC or x86 gcc, only the C is printed out. Compiled with ARM-LINUX-GCC, on the arm board, is able to print out a and c. What did you find out?

First, introduce the Integer promotion. In layman's terms, C is automatically promoted to int when processing an integer (char short int) (Promoted to unsigned int if the int range is not sufficient). For example, "a = = 0xb6", first 0xb6 will be an int to deal with, become 0x000000b6 (about the constant, followed by a careful explanation). A is promoted to int, and if char is defined as having a match, then A is a negative number because the highest bit is 1, so a will be promoted to 0XFFFFFFB6. If char is defined as unsigned, then A is promoted to 0X000000B6.

That is, in VC or x86 gcc, a = = 0xb6 will become 0xffffffb6 = = 0x000000b6, and in the ARM-LINUX-GCC, become 0x000000b6 = 0x000000b6.

For short, because the C standard explicitly stipulates that no keyword is added, it represents a signed number. Therefore, no matter what compiler on the b = = 0xb600 will become 0xffffb600 = = 0x0000b600.

for int, itself is int, also do not need Integer promotion, so c = = 0xb60000, c do not do any processing, directly from the memory read out, that is 0xb60000 = = 0xb60000.

Finally, let's say a little bit about constants. I will later reprint part of the information, interested to see, I now only say with the octal (0) or hexadecimal (0x beginning) of the constants, they will be treated as unsigned number. In addition, like char a = 0xb6, this sentence has two implementation Defined, one is char band without symbol, and the other is, if Char is compliant, 0XB6 will be int 0x000000b6 processing, this int to have a conforming C Har have overflow, there will be problems, 0xb6 is positive, the assignment to a has become a negative, specific how to deal with, C is also implementation Defined.

The following is reprint:

1. Integral type

We know that in C, a char occupies a byte of storage space, and a byte is usually 8 bit. If these 8 bits are interpreted as unsigned integers, the range of values is 0~255, if interpreted by a signed integer, using the 2 ' s complement notation, the range of values is -128~127. The C language prescribes the signed and unsigned two keywords, unsigned char represents an unsigned number, and signed Char represents a signed number.

Then we used to use the char without signed or unsigned keyword is unsigned or signed number. C Standard This is implementation Defined, the compiler can define the char is unsigned, you can also define the char is signed, the compiler corresponding to the architecture of which implementation efficiency can be implemented, GCC of the x86 platform defines that the char type is signed. This is also one of the rationale of the C standard: priority is given to efficiency, while portability is still second. This requires programmers to be very clear about these rules, and if you want to write portable code, you have to know which ones are not portable and should be avoided. On the other hand, writing portable code is sometimes necessary, such as the Linux kernel code uses a lot of only GCC-supported syntax features for optimal execution efficiency, when writing this code is not intended to compile with another compiler, also do not consider the issue of portability. If you want to write code that is not portable, you must also know which parts of the code are not portable and why, and if it is not for efficiency, there is generally no reason to intentionally write the code that is not portable. From now on, we will be exposed to a lot of implementation defined features, C language and platform and compiler are inseparable, leaving the specific platform and compiler to discuss the C language, you can only discuss the extent of the first part of the book. Note that the ASCII value range is 0~127, so regardless of whether the char is signed or unsigned, saving an ASCII code is not a problem, and in general, if you use char to keep ASCII characters, you don't have to explicitly write signed or unsigned. If you use a char type to represent a 8-bit integer, you must specify whether it is signed or unsigned for portability. implementation-defined, unspecified and undefined

Where the C standard is not clearly defined, it is expressed in implementation-defined, unspecified or undefined, and in this book it is sometimes referred to as "undefined" in the three cases. What is the difference between these three kinds of situations?

We have just seen a implementation-defined case where the C standard does not specify whether char is signed or unsigned, but requires that the compiler explicitly specify this and write it in the compiler's document.

And for the unspecified situation, there are often several alternative ways of handling, the C standard does not specify which way to process, the compiler can decide for itself, and also do not have to write in the compiler's document, so that even with different versions of the same compiler can get different results, Because the compiler does not explicitly write what it does in the document, different versions of the compiler can choose a different approach, such as in the next chapter we'll talk about the order in which the arguments of a function call are evaluated in unspecified.

Undefined situation is completely uncertain, C standard does not prescribe how to deal with, the compiler is probably also no provision, and even did not make error handling, there are many undefined situation compiler is not to check out, will eventually lead to run-time errors, such as array access across the bounds is undefined.

Beginners see these rules often uncomfortable, feel that this is not learning to program but to chew the law, the result is more and more discouraged. Yes, C is not as perfect as a mathematical theorem, and things in the real world are not always perfect. But fortunately, C programmers have been very happy, as long as the strict adherence to the C standard to write code, do not touch those dark corners, the written code is very good portability. Think of the poor JavaScript programmers, they don't even have a standard to follow, a browser, or even a different version of the same browser, and programmers have to write separate code for each version of each browser.

In addition to the char type, the integral type includes a short int (or short), an int, a long int (or short long), a long long int (or short long long), and several [25]. These types can be combined with signed or unsigned keywords to denote signed or unsigned numbers. In fact, the representation of the number of symbols in the computer is sign and magnitude, 1 ' s complement or 2 ' s COMPLEMENT,C standard is also not clearly defined, but also implementation Defined. Most architectures use the 2 ' s complement notation, as are the x86 platforms, and from now on we'll only discuss the 2 ' s complement notation. It is also important to note that these types, other than char type, if not explicitly written signed or unsigned keywords all represent signed, this is clearly stipulated in the C standard, not implementation Defined.

Except that the char type explicitly stipulates a byte in the C standard, other integers are implementation Defined for several bytes. The usual compiler implementation adheres to the ILP32 or LP64 specification, as shown in the following table.

table 15.1. ILP32 and LP64

type ILP32 (number of digits) LP64 (number of digits)
Char 8 8
Short 16 16
Int 32 32
Long 32 64
Long Long 64 64
Pointer 32 64

ILP32 this abbreviation means that int (I), Long (L), and pointer (P) types all account for 32 bits, and typically the C compiler for a 32-bit computer uses this specification, as does GCC for x86 platforms. LP64 refers to Long (L) and pointers to 64 bits, which are typically used by the C compiler of 64-bit computers. The length of the pointer type is always consistent with the number of digits in the computer, as to what is the number of digits in the computer, and what kind of pointer is the type, we go to the 17th chapter of Computer Architecture and chapter 23rd pointers are explained in detail separately. From now on, the book makes the following conventions: In future presentations, the default platform is X86/LINUX/GCC, followed by ILP32, and Char is signed, and I won't explain it every time, but when it comes to other platforms I'll definitely point out what the platform is.

In the 2nd section, "Constants," the C-language constants have integer constants, Word constants, enumerated constants, and floating-point constants of four kinds, in fact the type of constants and enumerated constants are int, so the first three types of constants are integral. There are many kinds of integer constants, not all int, and we discuss the integer constants in detail below.

We used to use only decimal integer constants, but we can also use octal and hexadecimal integer constants [26] in the C language. Octal integer constants start with 0, followed by 0~7, for example, 022, so the decimal integer constant cannot begin with 0, otherwise it cannot be distinguished from octal. hexadecimal integer constants begin with a 0x or 0X, followed by 0~9, A~f, and A~f. In section 6th, "character type and character encoding", an escape sequence, represented by \ or \x plus octal or hexadecimal digits, is equivalent to replacing 0 of the beginning of octal and hexadecimal integer constants with \.

An integer constant can also have u or u at the end to denote "unsigned", plus L or L means "long", and ll or ll means "long long", such as 0x1234u,98765ull. But in fact the suffixes of the U, L and ll are not one by one corresponding to the unsigned, long and long long keys mentioned above. This correspondence is more complex and accurately described in the following table (from [C99] clause

table 15.2. Types of Integer Constants

suffix Decimal Constants octal or hexadecimal constants

Long int
Long Long int

unsigned int
Long int
unsigned long int
Long Long int
unsigned long int

U or U

unsigned int
unsigned long int
unsigned long int

unsigned int
unsigned long int
unsigned long int

L or L

Long int
Long Long int

Long int
unsigned long int
Long Long int
unsigned long int

both u or u, and L or L

unsigned long int
unsigned long int

unsigned long int
unsigned long int

ll or LL

Long Long int

Long Long int
unsigned long int

both u or u, and ll or LL

unsigned long int

unsigned long int

Given an integer constant, such as 1234U, it should belong to the column "decimal constant" in the "U or U" line, which lists three types of unsigned int, unsigned long int, unsigned long int, To find the first long enough type to represent the number 1234, then it is the type of the integer constant, and unsigned int can be represented if the int is 32 bits.

Another example is 0xffff0000, which should belong to the second column of "None" in the first row, "octal or hexadecimal constant," which has six types of int, unsigned int, long int, unsigned long int, long long int, unsigned Long int, the first type int means no 0xffff0000 so large, we write this hexadecimal constant to represent a positive number, and its MSB (31st bit) is 1, and if the signed int type is interpreted as negative, the second type unsigned int can represent this number, so the type of this hexadecimal constant should be counted as unsigned int. So notice that the two constants, 0x7fffffff and 0xffff0000, look similar, but the former is int and the latter is the unsigned int.


tells an interesting question. We know that the range of int on the x86 platform is -2147483648~2147483647, then use printf ("%d\n",-2147483648), and there is no problem printing the lower bound of the int type. If you compile with GCC main.c-std=c99 there will be a warning message: Warning:format '%d ' expects type ' int ', but argument 2 has type ' long int '. This is because, although the value of 2147483648 can be expressed in int, but in C, you cannot write an int constant of that value, the C compiler will use it as an expression of an integer constant 2147483648 and a minus sign operator, The integer constant 2147483648 already exceeds the range of int, and the value range of int and long on the x86 platform is the same, so this constant also exceeds the Long value range, which should be long based on the first column decimal constant "None" in the first row of the table above. Long, preceded by a minus sign, the expression is still long, and printf's%d conversion description requires the following argument to be an int, so the compiler warns. The reason to compile the command to add the-STD=C99 option is because C99 previously for the type of integer constants and the table has some discrepancies, even if not add this option will also report a warning, but the warning information is inaccurate, the reader can try. If changed to printf ("%d\n",-2147483647-1), the compiler will not report a warning, the-number operator two operands-2147483647 and 1 are int, the result should also be int, and its value does not exceed the value range of int type or change to printf ("%lld\n",-2147483648), or you can, the conversion instructions%LLD tell printf that the arguments are long long, and some of the conversion instructions are not yet mentioned, as described in section  2.9  "Formatting i/ o function ".

How about, the integer constant is not as simple as you originally thought. Let's look at a simple question. Long i = 1234567890 * 1234567890; there is a warning message at compile time: warning:integer overflow in expression. 1234567890 is an int, the expression that multiplies the two int is still the int, and the product has exceeded the range of the int, prompting the result to overflow. If you change to long long i = 1234567890LL * 1234567890; One of the constants is long, and the other constant is converted to long long and multiply, and the expression of two numbers is long long, The compiler will not report a warning. The rules for type conversions are described in detail in section 3rd, "type conversions."

[25] We also introduce a special type of integer--bit-field in the 4th section, "Structural bodies and consortia".

[26] Some compilers (such as GCC) also support binary integer constants, starting with 0b or 0 B, such as 0b0001111, but the binary integer constant never enters the C standard, but is an extension of some compilers, it is not recommended, because binary and octal, hexadecimal correspondence is very obvious, Using octal or hexadecimal constants is perfectly possible in place of binary constants.

2. Floating point type

C-Standard floating-point types have float, double, long double, as well as integral type, neither specify the number of bytes per type, nor specify which representation to use. The implementation of floating point number is very different on various platforms, some processors have floating-point operation units (fpu,floating Point unit), known as hard floating-point (hard-float) implementation, some processors do not have floating-point operation units, can only do integer operations, need to use integer operations to simulate floating-point operations, Called a soft floating-point (soft-float) implementation. Most platform floating-point implementations follow the IEEE 754,float type, which is usually 32-bit, and the double is usually 64-bit.

Long double is usually a more precise type than double, but the implementations of each platform vary considerably. On the x86 platform, most compiler-implemented long double is 80-bit because the x86 floating-point unit has 80-bit precision, and GCC implements a long double of 12 bytes (96 bits) to align to a 4-byte boundary (in section 4th, "structs and Consortia" The problem of alignment is discussed in detail, and some compilers implement a long double and a double with the same precision, and do not take full advantage of the precision of the x86 floating-point operation unit. The accuracy of floating-point operations in other architectures differs from compiler implementations, such as the long double on PowerPC, which is usually 128-bit.

We used to use only the simplest floating-point constants, such as 3.14, and now look at the floating-point constants. Since the representation of floating point numbers in the computer is based on scientific notation, floating point numbers can also be written in the form of scientific notation, where the mantissa and the exponent are separated by E or E, for example, 314e-2 means 314x10-2, noting that the cardinality of the representation is 10[27], If there are no digits to the left or right of the decimal point of the mantissa, this part is zero, such as 3.e-1,.987, and so on. Floating point numbers can also add a suffix, for example 3.14f,. 01L, the corresponding relationship between the suffix of a floating-point number and the type is simpler, the floating-point constant with no suffix is double, and the floating-point constant with the suffix F or f is float, and the floating-point constant with the suffix L or l is long. Double type.

[s] C99 introduces a new hexadecimal floating-point number, the cardinality is 2, which is not detailed in this book.
3. Type conversion

If someone asks which part of the C grammar rule is the most complex, I would say it is a type conversion. As you can see from the above two sections, there are many types of signed, unsigned integers and floating-point numbers, each of which defines a conversion rule, and the number of conversion rules is naturally huge, not to mention that because of the different architectures for integers and floating-point numbers, Many types of conversions are in obscure corners where the C standard is not explicitly defined. Although we do not intentionally touch these dark corners while writing code, sometimes we inadvertently make mistakes, so it is necessary to understand some unspecified conditions, and it is easier to analyze the cause of the error in case of error. This section is divided into sections that first describe what type conversions are occurring, what types will be converted into what types, and then how the compiler handles such type conversions. 3.1. Integer Promotion

In an expression, you can also use a signed or unsigned char, short, and bit-field wherever you can use the int or unsigned int type to do the right value. If the value range of the original type is represented by an int, the type is promoted to int, and if the range of the original type is not represented by an int, it is promoted to the unsigned int, which is called an integer promotion. Doing an integer promotion only affects the above types of values and has no effect on other types. C99 specifies that the integer promotion applies to the following situations:

1. If the parameter type of a function is unknown, for example using the old style C-style function declaration (see section 2nd "Custom Function"), or the function's argument list has ..., then the function is called to do an integer promotion of the corresponding argument, in addition, The corresponding argument, if it is a float, is also promoted to double, which is called the default Argument promotion. We know that the parameter list in printf has ..., except for the first parameter, the types of other formal parameters are unknown, such as the code:

char ch = ' A ';
printf ("%c", ch);

CH is promoted to int and then passed to printf.

2, the type conversion in arithmetic operation. Signed or unsigned char, short, and Bit-field have to do an integer promotion before they can participate in the calculation before doing arithmetic operations. For example:

unsigned char c1 = 255, C2 = 2;
int n = c1 + C2;

The process of calculating the expression C1 + C2 is actually to promote C1 and C2 to int and then add (unsigned char's range is 0~255, can be expressed in int, so it can be promoted to int, no elevation to unsigned int), The value of the entire expression is also int, and the final result is 257. Without this ascension process, the C1 + C2 will overflow, and the overflow will result in undefined, which will be truncated on most platforms and the result should be 1.

Besides the + number, what operators need to do integer promotion before they can be computed. We'll introduce the usual arithmetic conversion rules in the next section and then answer the question. 3.2. Usual arithmetic conversion

Two operands of an arithmetic type do arithmetic operations, such as a + B, if the two operands are of different types, the compiler will automatically do the type conversion, so that the two sides of the same type after the operation, which is called usual arithmetic conversion. The conversion rules are as follows:

If one side of the type is a long double, the other side is also converted to a long double.

Otherwise, if one side of the type is double, the other side is also converted to double.

Otherwise, if one side of the type is float, the other side is also converted to float.

Otherwise, both sides should be integral types, first by the rules in the previous section to do an integer promotion of A and B, and then if the type is still different, you need to continue the conversion. First we specify the conversion level (Integer conversion Rank) of char, short, int, long, long long and one higher, with the same Rank for signed and unsigned numbers of the same type. The conversion rules are as follows:

If both sides are signed, or are unsigned, then the lower rank type is converted to a higher rank type. For example, unsigned int and unsigned long are converted to unsigned long when doing arithmetic operations.

Otherwise, if one side is an unsigned number on the other and the unsigned number rank is not less than rank of the signed number, then the signed number is converted to the unsigned type on the other side. For example, unsigned long and int are converted to unsigned long,unsigned long and long when arithmetic operations are also converted to unsigned long.

The rest of the situation is that there is no sign on the other side of the symbol, and the number of unsigned rank is below the rank of the signed number. This is divided into two cases, if the signed number of types can override the range of the unsigned number type, the unsigned number to the other side of the signed type. For example, unsigned int and long, which follow the LP64 platform, are converted to long in arithmetic operations.

Otherwise, that is, the signed number type is not sufficient to overwrite the range of the unsigned number type, then turn both sides to the unsigned type of rank corresponding to the signed number. For example, on platforms that follow ILP32, unsigned int and long are converted to unsigned long in arithmetic operations.

The conversion rules for visible signed and unsigned integers are complex, although they are clearly defined and do not fall into the dark corner, but they should not be relied upon to write code for the readability of the program. I'm not talking about these rules for you, it's about getting you to understand that there's a lot of trouble with signed numbers and unsigned numbers, so you don't have to touch the rules, and remember to look for a reason when the program goes wrong. So these rules need not be kept in mind, but know that there is such a thing, so that when you use it, you can find this section of my book.

So far we've learned +-*/% > < >= <= = =!= operators All need to do usual arithmetic conversion, because both sides of the operands are required to be the same type, the next chapter will introduce several new operators also need to do usual Arithmetic conversion. Monocular operator +-~ Only one operand, shift operator << >> on both sides of the operand type does not require consistency, these operations do not need to do usual arithmetic conversion, but also need to do integer promotion, operator ~ << >> will be introduced in the next chapter. 3.3. Type conversions from Assignment

If the type of the equals sign is different when assigned or initialized, the compiler converts the type on the right side of the equal sign to the type on the left of the equals sign and assigns the value. For example int c = 3.14, the compiler turns the double on the right to an int and assigns it to the variable C.

As we know, the process of calling a function call is equivalent to defining a formal parameter and initializing it with an argument, and the function returns a procedure that is equivalent to defining a temporary variable and initializing it with a return expression, so the type conversion generated by the assignment also applies to both cases. For example, the prototype of a function is int foo (int, int), and the Call to Foo (3.1, 4.2) automatically turns the argument of two double types to an int to give the formal parameter, if there is a return statement in the function definition returns 1.2; The return value of 1.2 is automatically converted to an int and then returned.

Type conversions that occur during function calls and returns are often overlooked because function prototypes and function calls are not written together. For example, char C = GetChar (); Seeing this sentence often takes for granted that the return value of GetChar is char, whereas the GetChar return value is int, so the assignment causes a type conversion and can produce a bug, and we are in section 2.5, "in bytes i/ o Function "discusses this issue in detail. 3.4. Force type Conversions

The above three cases are generally referred to as implicit type conversions (implicit conversion, or coercion), and the compiler automatically converts one type to another according to its own set of rules. In addition, programmers can also use the type conversion operator (cast Operator) to specify the type to which an expression is to be converted, which is called an explicit type conversion (EXPLICIT conversion) or coercion type cast. For example, evaluate expressions (double) 3 + I, first cast integer 3 to double (value 3.0), then add to integer variable i, then apply usual arithmetic conversion rule, first turn I to double, then add the two, Finally, the entire expression is also a double type. Here (double) is a type conversion operator, which consists of a type name set () bracket, which is a single operator, followed by the operand of this operator. 3. Note that the type of the operand must be a scalar type, and the type after the conversion must be a scalar type or a void type. 3.5. How the compiler handles type conversions

The preceding sections describe the scenarios in which type conversions occur and what types are converted into each of these cases, and this section describes how the compiler handles conversions between any two types. Now to convert an M-bit type (value x) to an n-bit type, all possible scenarios are shown in the following table.

table 15.3. How to do type conversion

types to be converted M > N Situation the case of M = = N M < n situation
Signed integer to signed integer If x is in the range of the target type, the value is unchanged, otherwise the implementation-defined Value does not change Value does not change
unsigned integer to signed integer If x is in the range of the target type, the value is unchanged, otherwise the implementation-defined If x is in the range of the target type, the value is unchanged, otherwise the implementation-defined Value does not change
Signed integer to unsigned integer X% 2N X% 2N X% 2N
unsigned integer to unsigned integer X% 2N Value does not change Value does not change
Floating-point to signed or unsigned integer Truncate toward Zero If the integer part of x exceeds the range of the target type undefined
Signed or unsigned integer to floating-point If x is in the range of the target type, the value is the same, but it is possible to lose the precision if x exceeds the range of the target type undefined
Floating-point to floating-point If x is in the range of the target type, the value is the same, but it is possible to lose the precision if x exceeds the range of the target type undefined Value does not change Value does not change

Notice the "x 2N" in the table above, which I would like to say is "add x or subtract an integer multiple of 2N, cause the result to fall into the range of [0, 2n-1], when X is negative, the result of the operation is also positive, that is, the result of the operation is the same number as the divisor rather than the dividend, which is different from the definition of the C language% operation. Do not intentionally use the rules in the table above, especially do not touch the implementation-defined and undefined situation, but the program error can use the table to analyze the cause of the error.

Here are a few examples to illustrate the use of the table above. For example, the double type is converted to the short type, the corresponding table "floating-point to signed or unsigned integer", if the original value between (-32769.0, 32768.0) to intercept the fractional part of the conversion results, Otherwise an overflow occurs, resulting in undefined, for example, for short s = 32768.4; This statement GCC will report a warning.

For example, the int to convert to the unsigned short type, the corresponding table "signed integer to unsigned integer", if the original value is positive, then divide it by 216 modulo, in fact, it is to take its low 16 digits, if the original value is negative, Then add a 216 integer multiple, causing the result to fall between [0, 65535].

For example, the int type is converted to the short type, the corresponding table "signed integer to signed integer", if the original value between [-32768, 32767] The value unchanged, otherwise overflow, The result is implementation-defined, for example, for short s =-32769; This statement GCC will report a warning.

The last example converts the short type to int, corresponding to the "signed integer to signed integer" In the table, and the value is unchanged after the conversion. How does that keep the value unchanged? is not at the high level to fill 16 0 on the line. If the original value is-1, the hexadecimal representation is FFFF, the 1 to be converted to int is required to become ffffffff, so it is necessary to fill 16 1 instead of 16 0 in the high position. In other words, to maintain the value unchanged, a high 1 or a complement of 0 depends on the original sign bit, which is called the symbolic extension (Sign Extension).

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.