> 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