Dual-use float

Consider the following code snippet

float num = 281.583f;
int amount = (int) Math.round(num*100f);
float rounded = amount/100.0f;
double dblPrecision = rounded;
double dblPrecision2 = num;
System.out.println("num : " + num + " amount: " + amount + " rounded: " + rounded + " dbl: " + dblPrecision + " dbl2: " + dblPrecision2);

The output I get is

num : 281.583 amount: 28158 rounded: 281.58 dbl: 281.5799865722656 dbl2: 281.5830078125

Why is there an approximation when a floating-point number is assigned to a double variable?

+5
source share
6 answers

The approximation actually takes place when you convert the decimal to float. I might surprise you, but 281.583cannot be represented exactly as a floating point number in a PC. this is because floating point numbers are represented as the sum of binary fractions on a PC. 0.5, 0.25and 0.125can be converted accurately, but not 0.583.

( ) Σ( 1/2^i*Bi ), Bi - i- (0|1). 0.625 = 1/2 + 1/4 . , .

( - ).

i|  *2 and trim|    Bit value|  (2^-1)*bit
    0,583       
1   1,166   1   0,5
2   0,332   0   0
3   0,664   0   0
4   1,328   1   0,0625
5   0,656   0   0
6   1,312   1   0,015625
7   0,624   0   0
8   1,248   1   0,00390625
9   0,496   0   0
10  0,992   0   0
11  1,984   1   0,000488281
12  1,968   1   0,000244141
13  1,936   1   0,00012207
14  1,872   1   6,10352E-05
15  1,744   1   3,05176E-05
16  1,488   1   1,52588E-05
17  0,976   0   0
18  1,952   1   3,8147E-06
19  1,904   1   1,90735E-06
        SUM=    0,582998276
+5

. , 281.583f float IEEE 754.

, println

, , float.

, . , double, " double" , , float, .

. .

+3

. , double , .

281.583, , ( , ): 100011001.1001_0101_0011_1111_0111_1100_1110_1101_1001...

Float 23 , double - 52 . ( ) 100011001.1001_0101_0011_11, 281.582946777 .

7 16 . , 1 .

0

, , ...

float f = 281.583f;
System.out.println(f);
System.out.println((double) f);

...

281.583
281.5830078125

(hey, double !)

...

Feed 438ccaa0 ( , 281.583f, Integer.toHexString(Float.floatToRawIntBits(281.583f))), , , float 281.58301. (@Michael Borgwardt , .)

, 281.583 281.58301, float. 281.58301 double, , 281.58301, 281.583!

-, 281.58300781250000, , 281.5830078125 .

0

, float, . , , . double, .

double num = 281.583;
long amount = (long) (num*100);
double rounded = (double) amount/100;
double dblPrecision = rounded;
double dblPrecision2 = num;

num : 281.583 amount: 28158 rounded: 281.58 dbl: 281.58 dbl2: 281.583
0

; -. , :

System.out.printf("num:           %a\n",num);
System.out.printf("dblPrecision2: %a\n",dblPrecision2);

System.out.printf("rounded:       %a\n",rounded);
System.out.printf("dblPrecision:  %a\n",dblPrecision);

num:           0x1.19954p8
dblPrecision2: 0x1.19954p8
rounded:       0x1.19947ap8
dblPrecision:  0x1.19947ap8

num = dblPrecision2 and rounded = dblPrecision.

Now 0x1.19954p8 = 100011001.100101010100 = 281.5830078125 and 0x1.19947ap8 = 100011001.1001010001111010 = 281.579986572265625. All that happens is that when they are printed, they are rounded differently (floats are rounded to a smaller number of digits than doubled).

0
source

All Articles