Bug 41049 - conversion from integer to decimal float loses trailing zeros
Summary: conversion from integer to decimal float loses trailing zeros
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.3.5
: P3 normal
Target Milestone: ---
Assignee: Janis Johnson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-08-12 21:05 UTC by Janis Johnson
Modified: 2009-09-22 16:16 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Janis Johnson 2009-08-12 21:05:39 UTC
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.
Comment 1 Janis Johnson 2009-09-17 17:07:44 UTC
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

Comment 2 Janis Johnson 2009-09-18 17:04:45 UTC
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

Comment 3 Janis Johnson 2009-09-21 16:22:58 UTC
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

Comment 4 Janis Johnson 2009-09-22 16:16:17 UTC
Fixed in trunk, 4.4 branch, 4.3 branch.
Comment 5 Janis Johnson 2009-10-22 18:24:43 UTC
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