(EXT) https://my.oschina.net/joymufeng/blog/139952
What is the output of this line of code?
Does the output of the following two lines of code be the same?
Try running the above two snippets in eclipse, and if you're surprised by the output, continue reading ... As you can see: The result of the 1th code fragment is:-1 The 2nd code fragment runs as follows: 65535 and 255 The two code snippets above are from the 6th small issue of Java puzzle, "Multiple Transformations", the original topic reads: public class multicast{ public static void Main (string[] args) {System.out.println (int) (char) (byte)-1); }} 3 consecutive type conversions in the code above, will the final result go back to-1? The answer, of course, is no, it outputs a result of 65535. Below I have compiled the relevant basic knowledge for everybody, I believe that everybody should know the reason after reading. How do I encode negative numbers in Java? Java uses "2 of the complement" (the second ' s complement) coding negative numbers, it is a numeric encoding method, two steps to complete: the first step, each bits is the opposite value, 0 becomes 1, 1 becomes 0. For example, +8 of the binary code is 00001000, after the reverse is 11110111. The second step is to add 1 to the value from the previous step. 11110111 becomes 11111000. So, 00001000 of the 2 of the complement is 11111000. In other words, 8 is represented in the computer (8-bit machine) with 11111000. For more information on the "2 complement", please refer to Nanyi's post, "about 2 complement", which is attached to the reference section of this article. Ii. what is symbol extension (sign Extension)? Symbol extensions (sign Extension) are used to extend the length of a bits when a numeric type is converted, to guarantee that the converted numeric value and the original value's symbol (positive or negative) and size are the same, typically for a narrower type, such as Byte, to convert to a wider type, such as Int. Extended bits length refers to a number of sign bits (0 indicates positive, 1 for negative) on the left side of the bits of the original value. For example, if you use 6 bit to represent the decimal Number 10, the binary code is "00 1010", if it is signed to 16bits length, the result is "0000 0000 0000 1010", that is, on the left side 10 0 (because 10 is a positive number, the symbol is 0), The size and symbol of the value before and after the symbol extension are unchanged, if the decimal number 15 is used in 10bits, the binary code is "11 1111 0001" After using the "2 complement" encoding, and if it is signed to 16bits, the result is "1111 1111 1111 0001 ", which is 6 1 on the left (because 15 is a negative number and the symbol is 1), the size and symbol of the value before and after the symbol extension remain unchanged. Iii. Java Type Conversion rule 1. There are several ways to write int literal literals in Java in the form of integer literals:-decimal notation, direct notation of decimal number-eight, format with 0, for example 012 for decimal 10-16 binary, format 0x, for example 0xFF for decimal 2 55 It is important to note that in Java, 012 and 0xff return the int type data, that is, the length is 32 bits. 2. Java numeric type conversion rules This rule is summed up in the Java FAQ: If the initial numeric type is signed, the symbol extension is executed, and if it is a char type, the 0 extension is performed regardless of what type it is being converted to. Another rule to remember is that if the length of the target type is less than the length of the source type, the length of the target type is directly intercepted. For example, the int type is converted to a byte type, and the right 8 bits of the int are intercepted directly. Iv. resolving the problem of "multiple transformations" the expression for a continuous three-time type conversion is as follows: (int) (char) (byte)-11. Int (32-bit), byte (8-bit)-1 is the literal of type int, according to the "2 complement" encoding rule, the encoding result is 0xFFFFFFFF, That is, 32 bits all set 1. When converting to byte type, the last 8 bits are intercepted directly, so the byte result is 0xFF and the corresponding decimal value is -1.2. Byte (8-bit), char (16-bit) because Byte is a signed type, Therefore, when converting to char (16-bit), a symbol extension is required, i.e. 8 1 (1 is the sign bit of 0xff) on the left side of the 0xFF, and the result is 0xffff. Since char is an unsigned type, the decimal number represented by 0xFFFF is 65535. 3. Char (16-bit), int (32-bit) because Char is an unsigned type, when converted to int type 0 expands, that is, on the left side of 0xFFFF consecutively 16 0, the result is 0x0000ffff, the corresponding decimal number is 65535. V. Examples of transformation in the case of type conversion, it is important to understand the meaning of the expression, not by feeling. The best way is to express your intentions clearly. When you convert a char-type value C to a wider-width type, and you do not want a symbol extension, you can encode the following: int i = c & 0xFFFF; As mentioned above, 0xFFFF is an int literal, so the compiler will automatically convert C to int after the & operation, that is, the C-Binary encoding before adding 16 0, and then 0xFFFF & operation, the intention is to force the first 16 0, the last 16 bits remain unchanged. Although this operation is not necessary, it clearly expresses the intention not to expand the symbol. If a symbol extension is required, it can be encoded as follows: int i = (short) C; Cast causes sign extension first converts C to the short type, which is the same width as char, and is a signed type, and then converts the short type to an int type, which automatically expands the symbol, that is, if short is a negative number, On the left, make up 16 1, otherwise fill 16 0. If you are transforming a byte value B into a char, and you do not want a symbolic extension, you must use a bitmask to limit it: char C = (char) (b & 0xff); (b & 0xff) The result is a 32-bit int type, the first 24 is forced 0, the last 8 bits remain unchanged, and then converted to a char type, directly intercept the post 16 bits. So whether B is positive or negative, when converted to char, it is equivalent to 8 0 on the left, that is, 0 expansion instead of symbol expansion. If a symbol extension is required, the code is as follows: char C = (char) b; Sign extension is performed the comment is required in order to explicitly express the intention to need a symbolic extension. Vi. Summary In fact, when the numeric type conversion, only when the negative number of the problem will occur, the root cause is that the negative numbers in Java is not encoded in an intuitive way, but instead of the "2 complement" approach, the advantage is that the addition and subtraction operations can be used at the same time the addition circuit to complete, However, there are a lot of strange problems in development, for example (byte) 128 result is-128, that is, a large positive number, truncated and then become negative. Section 3.2 refers to some of the transformation rules that can be applied to solve common transformation problems. Reference 1. Nanyi-about 2 of the complement HTTP://WWW.RUANYIFENG.COM/BLOG/2009/08/TWOS_COMPLEMENT.HTML2. Wikipedia-sign extensionhttp://en.wikipedia.org/wiki/sign_extension
View Code
(RPM) The transformation of negative numbers and basic types in Java