The function DFP_TO_INT() in gcc/config/dfp-bit.c has the job of converting decimal floating point values to integers. It does this by calling the decNumberFromString() function from the IBM decnumber library, but with an incorrect argument. Fortunately, the patch is just one character:
% diff -c gcc-4.3-20070209/gcc/config/dfp-bit.c /local/build/gcc/gcc-4.3-20070209/gcc/config *** gcc-4.3-20070209/gcc/config/dfp-bit.c Mon Jan 29 16:01:35 2007 --- /local/build/gcc/gcc-4.3-20070209/gcc/config/dfp-bit.c Thu Feb 15 12:41:12 2007 *************** *** 450,456 **** /* Rescale if the exponent is less than zero. */ decNumberToIntegralValue (&n2, &n1, &context); /* Get a value to use for the quantize call. */ ! decNumberFromString (&qval, (char *) "1.0", &context); /* Force the exponent to zero. */ decNumberQuantize (&n1, &n2, &qval, &context); /* Get a string, which at this point will not include an exponent. */ --- 450,456 ---- /* Rescale if the exponent is less than zero. */ decNumberToIntegralValue (&n2, &n1, &context); /* Get a value to use for the quantize call. */ ! decNumberFromString (&qval, (char *) "1.", &context); /* Force the exponent to zero. */ decNumberQuantize (&n1, &n2, &qval, &context); /* Get a string, which at this point will not include an exponent. */ Without this patch, the range of numbers that can be correctly converted to integers is sharply reduced: most conversions of large values are wrong. For example, the value x = 1048576.0DF is exactly representable as a _Decimal32 value and as a 32-bit int, but the bad code converts it to an int value of 2147483647, and a long int value of 9223372036854775807. With the patch, integer conversions are now correct for all floating-point values for which exact integer counterparts exist. The bug exists in all versions of dfp-bit.c in gcc-4.2 and gcc-4.3 distributions. As an aside, I now have a complete C99 library for decimal arithmetic working under gcc-4.2 and gcc-4.3 on AMD64, thanks to the prototype support for decimal arithmetic in gcc. I look forward to the decimal support working on other platforms. -- Summary: Scaling error in decimal floating-point arithmetic blows conversions to integers Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: beebe at math dot utah dot edu GCC build triplet: x86_64-unknown-linux-gnu GCC host triplet: x86_64-unknown-linux-gnu GCC target triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30992