preface

In this article, we will continue to look at conversion instructions in the bytecode instruction set to see how they operate on data conversion.

An overview of type conversion instructions


Type conversion instructions can convert two different numeric types to each other

These conversion operations are typically used to implement explicit type conversion operations in user code, or to deal with problems where data type-related instructions in a bytecode instruction set do not correspond to data types one-to-one.

There are two types of conversions: wide conversions and narrow conversions

Wide type conversion instruction


Java VIRTUAL machines directly support the following numeric conversion (safe conversion of small range types to large range types). That is, no instructions are required to execute, including:

  • From int to long, float, or double. The corresponding instructions are I2L, I2F and i2D.
  • From long to float and double. The corresponding commands are L2f and l2D
  • From float to double. The corresponding instruction is f2d

Int –> long –> float –> double

Let’s take a look at the following sample code for a basic test of broad type conversions

Public void upcast1(){int I = 10; public void upcast1(){int I = 10; long l = i; float f = i; double d = i; float fl = l; double d1 = l; double d2 - fl; }}

Let’s compile the code to see what instructions the method’s bytecode is cast with.

Accuracy loss problem

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Wide conversions do not lose information if they exceed the maximum value of the target type. For example, converting from int to long or from int to double does not lose any information. The values are exactly the same before and after the conversion.

When converting an int, a long to a float, or a long to a double, a loss of precision may occur: the least significant bits of the value may be lost, and the converted floating point value is the correct integer value according to the closest IEEE754 rounding mode.

Let’s look at the following sample code for a basic test for the accuracy loss problem

Public class classcastTest{// Example; @test public void upcast2(){int I = 123123123; float f = i; system.out.print1n(f); } // The result is as follows: 1.2312312E8

Now let’s see if we can convert long to double. Is that the same problem?

Public class classcastTest{// Example; @test public void upcast2(){long l = 123123123123L; double d = l; ystem.out.print1n(d); } // The result is as follows: 1.2312312312312e17

It is actually possible for a wide type conversion to lose precision, but this does not cause the Java Virtual Machine to throw a runtime exception

added

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Wide conversions from byte, char, and short to int are virtually nonexistent.

The virtual machine did not convert the byte type to int, but simply exchanged the two data through the operand stack

If i21 is used to convert byte to long, then i21 is used to convert byte to long. If i21 is used to convert byte to long, then i21 is used to convert byte to long.

On the one hand, it can reduce the actual data type. If a set of instructions is prepared for both short and byte, the number of instructions will increase greatly. However, the current design of virtual machine only wants to use one byte to express instructions, so the total number of instructions cannot exceed 256. It makes sense to treat short and byte as ints

On the other hand, since the slot in the local variation table is fixed to 32 bits, both byte and short stored in the local variation table will occupy 32 bits of space. From this point of view, there is no need to differentiate between these data types.

Narrow conversions of type conversion instructions


Transformation rules

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

The Java virtual machine also directly supports the following narrow type conversions:

  • Int to byte, short, or char. The corresponding instructions are: I2B, I2C, i2S
  • From long to int. The corresponding instructions are l2i
  • From float to int or long. The corresponding instructions are f2I and F21
  • From double to int, long, or float. The corresponding instructions are d2I, D2L and D2F

Let’s look at the following sample code for a basic test of narrow type conversions

Public void downcast1(){int I = 10; public void downcast1(){int I = 10; byte b = (byte)i; short s = (short)i; char c = (char)i; long 1 = 10L; int i1 = (int)l; byte b1 = (byte)l; }}

Let’s compile the code to see what instructions the method’s bytecode is cast with.

Accuracy loss problem

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Narrowing type conversions can result in conversions with identical signs and different orders of magnitude, so the conversion process is likely to result in numerical loss of accuracy.

Although data type narrowing conversions can cause upper limit overruns, lower limit overruns, and precision loss, the Java virtual Machine specification’s narrow conversions instructions that specifically specify numeric types can never cause a virtual machine to throw a runtime exception

Let’s look at the following sample code for a basic test for the accuracy loss problem

Public void downCast4(){int I = 128; public void downCast4(){int I = 128; byte b = (byte)i; system.out.printin(b); } // Run the following command: -128

The reason for this is that for 32-bit data, when the data is converted, the high level is cut down to the byte range, which becomes negative

added

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

When converting a floating point value to a narrow integer of type T(T is limited to either int or long), the following conversion rules are followed:

  • If the floating point value is a NaN, the result of the conversion is an int or a long of type 0
  • If the float value is not infinite, the float value is rounded to zero using IEEE 754 rounding mode to obtain the integer value V

If v is within the representation range of the target type T (int or long) then the result of the conversion is V. Otherwise it will be converted to the maximum or minimum that T can represent according to the sign of V

When narrowing a double to float, the following conversion rules are followed:

Round a number that can be represented using float type by rounding the nearest number to the rounding pattern. The final result is determined by the following rules:

  • If the absolute value of the result of the conversion is too small to be represented by a float, positive or negative zeros of the float type are returned.
  • If the absolute value of the result of the conversion is too large to be represented by a float, the positive or negative infinities of the float type are returned.
  • NaN values of type double are converted to NaN values of type float as specified.