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

Reply via email to