Convert Long.MAX_VALUE to Float

I enjoy the mess by converting Integer to Float, Float to Long, Long to Int, after which I am embarrassed by this behavior below.

When I convert String s representing Long.MAX_VALUE (63 1s), I got a NumberFormatException that was expected. because Long is 64 bits and Integer is 32 bits, so there are an additional 31 1s. (This is my guess, maybe this is another reason, please correct me if I am wrong)

However, I'm not sure why I did not get a NumberFormatException when converting Long to Float . Long again is 64 bits, and Float is 32 bits, like Integer . I know that bits are interpreted differently as Float (IEEE 754 floating point "single format"), but what happened to all the other 31 extra bits? I really got lost here ...

Also, how do I get 9.223372E18, which is a 1011111000000000000000000000000 bit string? where are these 0s from?

 public static void main(String[] args){ String s = String.valueOf(Long.MAX_VALUE); print(s); //prints 9223372036854775807 print(Long.toBinaryString(Long.MAX_VALUE)); //prints 111111111111111111111111111111111111111111111111111111111111111 //Integer.valueOf(s) this throws NumberFormatException because Long is 64 bits and Integer is 32 so s is too large to be an Integer print(Float.valueOf(s)); //prints 9.223372E18 Why no NumberFormatException? and how did it result 9.223372E18? float f = Float.valueOf(s); int intBits = Float.floatToIntBits(f); print(Integer.toBinaryString(intBits)); //1011111000000000000000000000000 How come? s was a String of 1s now there are 0s? } public static <T> void print(T arg){ System.out.println(arg); } 
+5
source share
3 answers

First, confirm that the conversion was correct.

Long.MAX_VALUE - 9223372036854775807 (19 digits). As you can see, the value roughly matches what you typed: 9.223372E18 .

The accuracy of a long always 1 . However, the accuracy of a float depends on the value of the number.

In IEEE, a single-precision floating-point number in which the float has only 24 bits of precision in the mantissa, or β€œfraction” of the storage part. Thus, the actual value represented by the float is the approximate value of the actual value of Long.MAX_VALUE .

Float.floatToIntBits

As you understand, the Float.floatToIntBits method gives different bits than the original long representation.

Returns a representation of a given floating-point value according to the IEEE 754 floating-point floating-point mask. Bit 31 (the bit selected by mask 0x80000000) represents the sign of a floating-point number. The exponent metrics are bits 30-23 (bits selected by mask 0x7f800000). Bits 22-0 (bits that are selected by mask 0x007fffff) represent significant (sometimes called mantissa) floating point numbers.

(notch)

Returns : bits that represent a floating point number.

This method does not convert it to an int value, it only gives a bit representation of the float , which is stored in int . The value represented by this int is not expected to equal the float value.

Conversion

These zeros are the mantissa of the floating point number. The actual conversion of long to float involves finding the sign for the most significant bit, determining the value of the value to determine the exponent, and converting the rest of the value to the mantissa.

Since the precision of the float on the Long.MAX_VALUE scale Long.MAX_VALUE limited, some precision is lost. The end result is that the float value is slightly rounded. Since Long.MAX_VALUE 1 is less than power 2, rounding gives power 2, which is displayed as all zeros in the mantissa.

You can see the precision of the floating point value on a number scale with Math.ulp (the unit in last place).

 Math.ulp(f) 

what gives

 1.09951163E12 

As you can see, the difference is quite large for the float for Long.MAX_VALUE . (ULP for the corresponding double 2048.0 . Large, but much smaller than ulp for the float here.) But it matches the expected value of almost 10 19 - about 7 digits of precision for the float .

+1
source

Regarding print(Float.valueOf(s)); //prints 9.223372E18 Why no NumberFormatException? and how did it result 9.223372E18? print(Float.valueOf(s)); //prints 9.223372E18 Why no NumberFormatException? and how did it result 9.223372E18? :

Floats are presented in different ways. The number in question is in the Float range, according to the Java Language Specification .

The exact conversion, including rounding, is described in JavaDoc

Regarding `print (Integer.toBinaryString (intBits)); // 1011111000000000000000000000000 How did it happen? s was a string from 1s, now there are 0s? ':

Float.floatToIntBits(f) does not return "same number as integer". Its semantics are described in JavaDoc

0
source

A float is represented in four bytes (32 bits), and long is represented in 8 bytes (64 bits). When you convert long to float , you lose half of your data, since you cannot put 64 bits into 32 bits. For this reason you have lost many bits.

float uses a 23-bit mantissa, so integers greater than 2 ^ 23 will be truncated.

That's why you can cast, and the cast has a result.

0
source

Source: https://habr.com/ru/post/1274072/


All Articles