https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93112
Bug ID: 93112 Summary: Incorrect rounding for float to uint64 on x86 (32bit) with -fexcess-precision=standard Product: gcc Version: 9.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: stefan.bru...@rwth-aachen.de Target Milestone: --- The following program yields 1034567 for all 4 cases on x86_64, arm64, armv7, ... and x86 with -fexcess-precision=fast, but yields 1034566 for the 1st case on x86 with -fexcess-precision=standard: --- #include <stdint.h> #include <stdio.h> #include <inttypes.h> #define MHZ(x) ((x) * UINT64_C(1000000)) uint64_t t1(uint64_t x) { printf("r: %" PRIu64 "\n", x); } void t2(float x) { printf("r: %f\n", x); } int main(int argc, char** argv) { if (argc < 2) { t1(MHZ(1.034567)); // 1034567 or 1034566 t1(1034567.0); // always 1034567 t2(MHZ(1.034567)); // always 1034567.0 t2(1034567.0); // always 1034567.0 } return 0; } --- 1'034'567 can be represented exactly as float value. 1.034567 can't be represented exactly, but rounding towards nearest should yield the correct result (the error is about 2^-20, float precision is about 2^-23). The error only happens if the multiplication result is cast to int. Error happens with both GCC 9.2.1 and 7.5.0 - gcc-7 (SUSE Linux) 7.5.0 - gcc-9 (SUSE Linux) 9.2.1 20191209 [gcc-9-branch revision 279114]