Error in simple floating point calculations

I am having problems with:

int q = 150;
float s = 0.7f;
float z = q*s;
int z1 = (int) (q*s);
int z2 = (int) z;

The result is

  • z1 int with value 104
  • z2 int with value 105

Can anyone explain this? I do not understand these results.


To avoid closure, I (René Vogt) add this information:

  • q*sresults in a floatvalue 105.0f(or perhaps 104.999999, but the string representation ends as 105).
  • therefore zis floatof105

the question now is, why (int)zleads to 105, but (int)(q*s)leads to 104? I can reproduce this on my machine (i7, Win10, VS2015, .NET4.6.1)


And the IL code:

// Initialisation
// q = 150
ldc.i4 0x96  
stloc.0
// s = 0.7f
ldc.r4 0.69999999 
stloc.1

// calculating z 
ldloc.0 // load q
conv.r4 // convert to float
ldloc.1 // load s
mul     // q*s
stloc.2 // store float result to z

// calulating z1
ldloc.0 // load q
conv.r4 // convert to float
ldloc.1 // load s
mul     // q*s
conv.i4 // convert to int
stloc.3 // store int result in z1 => 104!

// calculating z2
ldloc.2 // loading float z
conv.i4 // converting to int
stloc.s // write to z2 (last local variable -> "s" as stack address)
        // => 105

, , z1 z2 , z2 float (z). ?

+4
3

0.7 float, s 0.699999988079071044921875.
int q float, , 150.

, 105:

q = 150
s = 0,699999988079071044921875
q * s = 104.999998211861

CLI Spec (ECMA-335) §12.1.3:

, / , , , . (NaN, + -). , . , - , (. (§12.6)). (conv.r4 conv.r8), .

, q * s , float. int:

var z1 = (int)(q * s);

float, int 104.

float float, 105.

+6

, x64?

, double. double float (, , , , 105.000000001)

mul     // q*s
stloc.2 // store float result to z (stored as float)

int double, , . 104.999999 int (104)

mul     // q*s
conv.i4 // convert to int

: float int #

: 1- , float, float. , int, .

0

( rember 2 charachters, deciaml 10).

1/3 = 0,33333333333333... (!)

, , 0,3333333 0,3333333333333.... ( ) ( )

, , Scientificfic, .

, - , : https://www.youtube.com/watch?v=PZRI1IfStY0

-1

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


All Articles