[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#799953: gcc-4.9: incorrect double to integer conversion on i386



> What's the result type of float * int ? Definitively not double, but
> float. (Just the intermediate result in the x87 fpu has extended
> precision.)

True, according to C11 standard, section 6.3.1.8, the result type of
float * int is float.

> So I don't think the compiler is wrong considering d and g to
> contain the same information, since the same *float* value was
> assigned to both variables. Therefore it considers (int)d and int(g)
> to be the same, ignoring that there are some excess precision bits
> in the double representation which cause your trouble.

I think the compiler is wrong. C11 standard, section 6.5.1, says:

"The type of an assignment expression is the type the left operand
would have after lvalue conversion."

And section 6.5.16.1 states:

"In simple assignment (=), the value of the right operand is converted
to the type of the assignment expression and replaces the value stored
in the object designated by the left operand."

So value in d is double and value in g is float. The compiler should
use value in d in the conversion to an integer.

> And btw, it should be easy to fix:
> 
> $ gcc-5 -O1 -mfpmath=387 -std=c99 -o test test.c && ./test 100
> f = 9999999.000000
> d = 999999900.000000
> g = 999999872.000000
> fractional part of d is 0.000000

The results are correct when using C11 standard:

$ gcc-4.9 -std=c11 -O1 -o test test.c && ./test 100
f = 9999999.000000
d = 999999900.000000
g = 999999872.000000
fractional part of d is 0.000000

They are unexpected when using C11 with GNU extensions:

$ gcc-4.9 -std=gnu11 -O1 -o test test.c && ./test 100
f = 9999999.000000
d = 999999900.000000
g = 999999900.000000
fractional part of d is 28.000000

I couldn't find any GNU extensions that change arithmetic conversion
rules. The bug PR323 is caused by excess precision of some
values. Here, it's the opposite case. Value in d is double, but in the
expression "int i = d", GCC uses a floating approximation to this
value, which has obviously lower precision. I think it's clearly a
bug.

Cheers,
MU


Reply to: