RE: Float conversion bug?
Posted in 2000
Topics: Stored Procedures & SPL, Data Types & Schema Design, Third-Party Tools & Monitoring, Versions, Editions & End-of-Life
I have in the past discussed this type of issue with Informix tech.
support. The answer I got was that the data type decimal should be used
and not float's. The 8.199999999999 is a side effect in the way CPU
hardware implement floating point values.
Wayne E. Martin
Informix Database Administrator
Kmart Corp.
-----Original Message-----
From: R Schweigard [mailto:rschweigard@sec-systemhaus.de]
Sent: Monday, December 04, 2000 8:20 AM
To: informix-list@iiug.org
Subject: Re: Float conversion bug?
I have the same returns in IDS 7.31 TC7 for NT 4.0.
"Wolf P'ter" <peter.wolf@capsys.hu> schrieb im Newsbeitrag
news:90g5co$91o$1@news.xmission.com...
>
> I found an interesting "feature" in IDS 7.31 UC6!
>
> execute procedure float_conversion( 8.2 ) ;>
> returns:
>
> 8.2 8.20000000000000 8.1999999999999990 8.20000000000000
>
> If seems to be a bug. Isn't it?
>
>
> --------------------------------------------------------------------------
> -- FLOAT_CONVERSION :
> --------------------------------------------------------------------------
> drop procedure float_conversion;
> create procedure float_conversion( be varchar(255) ) returning varchar(> 255), float, varchar( 255 ), float;
>
> define f1,f2 float;
> define vc varchar(255);
>
> let f1 = be; -- to float
> let vc = f1; -- to varchar
> let f2 = vc; -- and the varchar back to float
>
> return be, f1, vc, f2;
>
> end procedure;
>
>
>
"Martin, Wayne E." wrote:
> I have in the past discussed this type of issue with Informix tech.
> support. The answer I got was that the data type decimal should be used
> and not float's. The 8.199999999999 is a side effect in the way CPU
> hardware implement floating point values.
It's pretty weird; just for the record, with SQLCMD and ESQL/C 9.40 and
Foundation 2000 9.21.UC1, I get:
8.2|8.2|8.1999999999999993|8.2
The explanation is long and complex. The issue arose in a mildly
different guise last week on an internal mail alias, with the value in
question being 2.525 and
the formula involved rounding.
--- Last Week's Discussion (some names disguised) ---
Date: Fri, 1 Dec 2000 11:20:38 -0800 (PST)
From: Jonathan Leffler <jleffler@informix.com>
To: Unidentified Recipients Within Informix
Subject: Re: decimal convert problem in ESQL/C 9.30.FC1 in AIX 4.3.3
On Fri, 1 Dec 2000, B@@@@ S@@@@@@ wrote:
>Fair enough. I think this is still a bug though for the sole reason
>that it does not behave as it's documented, unless I stand corrected.
Maybe...even probably.
>When we call deccvfd() to convert the double to a null terminated
>string via ecvt() from deccvdbl(), we are setting numchars to 17.
>I see a #ifdef LINUX in there, which sets numchars to 15.
This accounts for the difference in behaviour, for sure. I don't know
where who got the idea that a 64-double can support 17 decimal digits;
16 is the maximum I've seen claimed and 15 is more normally correct --
so Linux is correct and others are not, in my view.
>Shouldn't all cases be 15, which seems to be a reasonable limit for the
>precision of a double across various platforms?
Subject to double being a 64-bit quantity, and using IEEE 754 or
thereabouts, then yes. For some systems (IBM S390 chips, for instance),
the underlying implementation of double precision floating point is
different - but still 64-bits - and the number of significant digits
might be different.
>On Thu, 30 Nov 2000, Jonathan Leffler wrote:
>| On Wed, 29 Nov 2000, B@@@@ S@@@@@@ wrote:
>| >Yeah, could be AIX related.
>|
>| FWIW, the problem also reproduces on Solaris 7 (32-bit) with ESQL/C
>| 9.40.UC2, once you fix the include notation for decimal.h in the test
>| case.
>|
>| >The source doesn't point to any 64 bit
>| >issues, but the AIX C compiler is a bit quirky, and I suspect it does not
>| >like some of the code related to "form a (+/-) .5 with the correct exponent"
>| >in decconv.c::decround().
>|
>| I believe that it comes down to the internal binary representation of
>| 2.525, which is represented as a number just a shade under 2.525 (say
>| 2.524999999999999), which is therefore correctly rounded down, even
>| though when it gets printed to the default precision.
>|
>| I added the following lines to the test case:
>|
>| char buffer[64];
>|
>| /* After first printf() */
>| printf ("%.15lf\\n", da);
>| printf ("%.18lf\\n", da);
>|
>| /* Before decround */
>| dectoasc(&sa, buffer, sizeof(buffer)-1, 30);
>| printf("%s\\n", buffer);
>|
>| And I got the output:
>|
>| 2.525000
>| 2.525000000000000
>| 2.524999999999999911
>| 2.524999999999999900000000000000
>| 2.520000
>|
>| Trying to print 19 digits (18 decimal places) is over-stretching the
>| internal representation of a double, and the decimal value is indeed
>| just less than 2.525, so that decround() is operating correctly. The
>| trouble is that the a C double simply cannot represent 2.525 exactly --
>| unlike a DECIMAL.
>|
>| >BTW, I ran this with ESQL/C 9.30.UC1 on SuSE Linux, and I got the
>| >correct results.
>| >
>| >2.525000
>| >2.530000
>| >
>| >
>| >On Wed, 29 Nov 2000, Y@@@@@@@ W@@ wrote:
>| >| Following program running in ESQL/C 9.30.FC1 in AIX 4.3.3 has
>| >| a conversion problem:
>| >|
>| >| #include <stdio.h>
>| >| #include decimal.h;
>| >|
>| >| main()
>| >| {
>| >| double da, da1;
>| >| dec_t sa;
>| >|
>| >| da=2.525;
>| >| printf ("%lf\\n", da);
>| >|
>| >| deccvdbl(da, &sa);
>| >| decround(&sa, 2);
>| >| dectodbl(&sa, &da1);
>| >|
>| >| printf ("%lf\\n", da1);
>| >| }
>| >|
>| >| The result is:
>| >| 2.525000
>| >| 2.520000
>| >|
>| >| Is this a bug of our product?
--- End of Last Week's Discussion ---
> -----Original Message-----
> From: R Schweigard [mailto:rschweigard@sec-systemhaus.de]
> Sent: Monday, December 04, 2000 8:20 AM
> To: informix-list@iiug.org
> Subject: Re: Float conversion bug?
>
> I have the same returns in IDS 7.31 TC7 for NT 4.0.
>
> "Wolf Péter" <peter.wolf@capsys.hu> schrieb:
> > I found an interesting "feature" in IDS 7.31 UC6!
> > execute procedure float_conversion( 8.2 ) ;> >
> > returns:
> >
> > 8.2 8.20000000000000 8.1999999999999990 8.20000000000000
> >
> > If seems to be a bug. Isn't it?
> >
> >
> > --------------------------------------------------------------------------
> > -- FLOAT_CONVERSION :
> > --------------------------------------------------------------------------
> > drop procedure float_conversion;
> > create procedure float_conversion( be varchar(255) ) returning varchar(> > 255), float, varchar( 255 ), float;
> >
> > define f1,f2 float;
> > define vc varchar(255);
> >
> > let f1 = be; -- to float
> > let vc = f1; -- to varchar
> > let f2 = vc; -- and the varchar back to float
> >
> > return be, f1, vc, f2;
> >
> > end procedure;
--
Yours,
Jonathan Leffler (Jonathan.Leffler@Informix.com) #include <disclaimer.h>
Guardian of DBD::Informix v1.00.PC1 -- http://www.perl.com/CPAN
"I don't suffer from insanity; I enjoy every minute of it!"
Related threads
- the longer you surf, the MORE $$$ you earn !!
- Store procedure
- emulation for Vt100
- extent size questions again ...