Re: Floating point rounding issue
Posted in 2004
> Look after , if you have a envinronment variable DBMONEY=, or > DBMONEY=. or neither .... > If you have , then I guess you are using a variable 'integer' to store > the value when you're executing the INSERT statement. Good suggestion about the env variable...hadn't thought of that. The maintainer of the DB driver sent us a patch (see below) that fixed the issue, so I wasn't able to re-run the test and check for the env var. Also, about the 'integer' type variable, perl (by default) doesn't have different integer and floating point variable types. Therefore, it should work w/o us pre-declaring variable types. > Try to run a INSERT statement in DBACCESS tool and compare if the > result is the same ..... IIRC, using DBACCESS worked just fine, which indicated that the problem was in perl somewhere (I probably should've mentioned that in the original post). Below is the patch that Jonathan Leffler sent us, that seems to fix the problem completely. --- dbdimp.ec 2002/12/14 00:29:41 100.36 +++ dbdimp.ec 2003/07/16 00:56:06 100.36.1.2 @@ -1,7 +1,8 @@ /* - * @(#)$Id: dbdimp.ec,v 100.36 2002/12/14 00:29:41 jleffler Exp $ + * @(#)$Id: dbdimp.ec,v 100.36.1.2 2003/07/16 00:56:06 jleffler Exp $ * - * @(#)$Product$ -- implementation details + * @(#)$Product$ + * @(#)Implementation details * * Copyright 1994-95 Tim Bunce * Copyright 1995-96 Alligator Descartes @@ -11,7 +12,7 @@ * Copyright 1999 Bill Rothanburg <brothanb@fll-ro.dhl.com> * Copyright 2000-01 Informix Software Inc * Copyright 2000 Paul Palacios, C-Group Inc - * Copyright 2001-02 IBM + * Copyright 2001-03 IBM * Copyright 2002 Bryan Castillo <Bryan_Castillo@eFunds.com> * * You may distribute under the terms of either the GNU General Public @@ -21,7 +22,7 @@ /*TABSTOP=4*/ #ifndef lint -static const char rcs[] = "@(#)$Id: dbdimp.ec,v 100.36 2002/12/14 00:29:41 jleffler Exp $"; +static const char rcs[] = "@(#)$Id: dbdimp.ec,v 100.36.1.2 2003/07/16 00:56:06 jleffler Exp $"; #endif #include <stdio.h> @@ -1185,6 +1186,21 @@ } EXEC SQL SET DESCRIPTOR :nm_ibind VALUE :index TYPE = :type, DATA = :blob; } + else if (type == SQLINT8 || type == SQLSERIAL8) + { + /** + ** JL 2003-07-01: partial fix for handling big INT8 fields for + ** Steve Vornbrock <stevev@wamnet.com>. Need to treat this as a + ** string - in case it is out of range of INTEGER. + */ + dbd_ix_debug(2, "%s -- INT8 or SERIAL8\\n", function); + type = SQLCHAR; + string = SvPV(val, len); + length = len + 1; + EXEC SQL SET DESCRIPTOR :nm_ibind VALUE :index + TYPE = :type, LENGTH = :length, + DATA = :string; + } else if (!SvOK(val)) { /* It's a null! */ @@ -1214,7 +1230,12 @@ } #endif } - else if (SvIOKp(val)) + /** + ** JL 2003-07-15: SvIOK() and SvNOK() fix problem with float to integer + ** conversion for Darryl Priest <darryl.priest@piperrudnick.com>, a + ** change in behaviour between Perl 5.005_03 and 5.8.0. + */ + else if (SvIOK(val) && SvIOKp(val)) { dbd_ix_debug(2, "%s -- integer\\n", function); type = SQLINT; @@ -1222,7 +1243,7 @@ EXEC SQL SET DESCRIPTOR :nm_ibind VALUE :index TYPE = :type, DATA = :intvar; } - else if (SvNOKp(val)) + else if (SvNOK(val) && SvNOKp(val)) { dbd_ix_debug(2, "%s -- numeric\\n", function); type = SQLFLOAT; @@ -1883,7 +1904,8 @@ /* Convert DECIMAL to convenient string */ /* Patches problems with Informix conversion routines in pre-7.10 versions */ /* Don't forget that decimals are stored in a base-100 notation */ -static char * +#if ESQLC_VERSION < 710 +static char * decgen(dec_t *val, int collen) { char *str; @@ -1906,6 +1928,29 @@ return str; } +#else + +static char * +decgen(dec_t *val, int collen) +{ + static char buffer[170]; + char *str; + int dp = PRECDEC(collen); /* Decimal places */ + int sf = PRECTOT(collen); /* Significant digits */ + + if (dp == 0xFF) + dp = -1; + dectoasc(val, buffer, sizeof(buffer), dp); + str = buffer; + while (*str == ' ') + str++; + /* Chop trailing blanks */ + str[byleng(str, strlen(str))] = '\\0'; + return str; +} + +#endif /* ESQLC_VERSION < 710 */ + /* ** Fetch a single row of data. **