IEEE 754 says that the preferred exponent of the result of a conversion from an integer to a decimal float value is zero. In all active branches of GCC a compile-time conversion discards trailing zeros and then adds one back, and a runtime conversion for the densely-packed decimal format adds an extra trailing zero. Runtime conversions for the BID format are correct, as are runtime conversions for DPD using hardware DFP. This test demonstrates the problem: ---------------------------- #include <stdio.h> int main () { volatile _Decimal32 d; volatile long long ll; d = 5.DF; printf ("5.DF constant 0x%x want this\n", *(int *)&d); d = 5.0DF; printf ("5.0DF constant 0x%x not this\n", *(int *)&d); d = 5; printf ("5 constant 0x%x\n", *(int *)&d); d = 5LL; printf ("5LL constant 0x%x\n", *(int *)&d); ll = 5LL; d = ll; printf ("5LL variable 0x%x\n", *(int *)&d); printf ("\n"); d = 50.DF; printf ("50.DF constant 0x%x want this\n", *(int *)&d); d = 50.0DF; printf ("50.0DF constant 0x%x not this\n", *(int *)&d); d = 50; printf ("50 constant 0x%x\n", *(int *)&d); d = 50LL; printf ("50LL constant 0x%x\n", *(int *)&d); ll = 50LL; d = ll; printf ("50LL variable 0x%x\n", *(int *)&d); printf ("\n"); d = 500.DF; printf ("500.DF constant 0x%x want this\n", *(int *)&d); d = 5.0E2DF; printf ("5.0E2DF constant 0x%x not this\n", *(int *)&d); d = 500.0DF; printf ("500.0DF constant 0x%x not this\n", *(int *)&d); d = 500; printf ("500 constant 0x%x\n", *(int *)&d); d = 500LL; printf ("500LL constant 0x%x\n", *(int *)&d); ll = 500LL; d = ll; printf ("500LL variable 0x%x\n", *(int *)&d); return 0; } ---------------------------- With DPD on either powerpc64-linux or i686-linux the results are: laptop% /home/janis/tools/gcc-trunk-dpd/bin/gcc bug3.c && ./a.out 5.DF constant 0x22500005 want this 5.0DF constant 0x22400050 not this 5 constant 0x22400050 5LL constant 0x22400050 5LL variable 0x22400050 50.DF constant 0x22500050 want this 50.0DF constant 0x22400280 not this 50 constant 0x22500050 50LL constant 0x22500050 50LL variable 0x22400280 500.DF constant 0x22500280 want this 5.0E2DF constant 0x22600050 not this 500.0DF constant 0x22401400 not this 500 constant 0x22600050 500LL constant 0x22600050 500LL variable 0x22401400 For BID on i686-linux the results are: laptop% /home/janis/tools/gcc-trunk-bid/bin/gcc bug3.c && ./a.out 5.DF constant 0x32800005 want this 5.0DF constant 0x32000032 not this 5 constant 0x32000032 5LL constant 0x32000032 5LL variable 0x32800005 50.DF constant 0x32800032 want this 50.0DF constant 0x320001f4 not this 50 constant 0x32800032 50LL constant 0x32800032 50LL variable 0x32800032 500.DF constant 0x328001f4 want this 5.0E2DF constant 0x33000032 not this 500.0DF constant 0x32001388 not this 500 constant 0x33000032 500LL constant 0x33000032 500LL variable 0x328001f4 I'm working on fixes to the compiler and to the DPD runtime.
Subject: Bug 41049 Author: janis Date: Thu Sep 17 17:07:24 2009 New Revision: 151806 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=151806 Log: gcc/ PR c/41049 * real.c decimal_from_integer, decimal_integer_string): New. (real_from_integer): Use them as special case for decimal float. * config/dfp-bit.c (_si_to_sd, _usi_to_sd): Use default rounding. (_di_to_sd, _di_to_dd, _di_to_td, _udi_to_sd, _udi_to_dd, _udi_to_td): Do not append zero after the decimal point in string to convert. gcc/testsuite/ PR c/41049 * dfp/pr41049.c: New test. Added: trunk/gcc/testsuite/gcc.dg/dfp/pr41049.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/dfp-bit.c trunk/gcc/real.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 41049 Author: janis Date: Fri Sep 18 17:03:55 2009 New Revision: 151857 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=151857 Log: PR c/41049 * real.c decimal_from_integer, decimal_integer_string): New. (real_from_integer): Use them as special case for decimal float. * config/dfp-bit.c (_si_to_sd, _usi_to_sd): Use default rounding. (_di_to_sd, _di_to_dd, _di_to_td, _udi_to_sd, _udi_to_dd, _udi_to_td): Do not append zero after the decimal point in string to convert. * dfp/pr41049.c: New test. Added: branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/dfp/pr41049.c Modified: branches/gcc-4_4-branch/gcc/ChangeLog branches/gcc-4_4-branch/gcc/config/dfp-bit.c branches/gcc-4_4-branch/gcc/real.c branches/gcc-4_4-branch/gcc/testsuite/ChangeLog
Subject: Bug 41049 Author: janis Date: Mon Sep 21 16:22:43 2009 New Revision: 151934 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=151934 Log: PR c/41049 * real.c decimal_from_integer, decimal_integer_string): New. (real_from_integer): Use them as special case for decimal float. * config/dfp-bit.c (_si_to_sd, _usi_to_sd): Use default rounding. (_di_to_sd, _di_to_dd, _di_to_td, _udi_to_sd, _udi_to_dd, _udi_to_td): Do not append zero after the decimal point in string to convert. * gcc.dg/dfp/pr41049.c: New test. Added: branches/gcc-4_3-branch/gcc/testsuite/gcc.dg/dfp/pr41049.c Modified: branches/gcc-4_3-branch/gcc/ChangeLog branches/gcc-4_3-branch/gcc/config/dfp-bit.c branches/gcc-4_3-branch/gcc/real.c branches/gcc-4_3-branch/gcc/testsuite/ChangeLog
Fixed in trunk, 4.4 branch, 4.3 branch.
Subject: Bug 41049 Author: janis Date: Thu Oct 22 18:24:31 2009 New Revision: 153468 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153468 Log: Backport from 4.3 branch: 2009-09-21 Janis Johnson <janis187@us.ibm.com> PR c/41049 * real.c decimal_from_integer, decimal_integer_string): New. (real_from_integer): Use them as special case for decimal float. * config/dfp-bit.c (_si_to_sd, _usi_to_sd): Use default rounding. (_di_to_sd, _di_to_dd, _di_to_td, _udi_to_sd, _udi_to_dd, _udi_to_td): Do not append zero after the decimal point in string to convert. * gcc.dg/dfp/pr41049.c: New test. Added: branches/ibm/gcc-4_3-branch/gcc/testsuite/gcc.dg/dfp/pr41049.c Modified: branches/ibm/gcc-4_3-branch/gcc/ChangeLog.ibm branches/ibm/gcc-4_3-branch/gcc/config/dfp-bit.c branches/ibm/gcc-4_3-branch/gcc/real.c branches/ibm/gcc-4_3-branch/gcc/testsuite/ChangeLog.ibm