#29064 [Asn]: Exact numeric/decimal/money datatypes lose precision
| From: | thekid@php.net | Date: | Sun, 11 Jul 2004 13:35:01 +0000 |
| Subject: | #29064 [Asn]: Exact numeric/decimal/money datatypes lose precision | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-62019@lists.php.net to get a copy of this message | ||
ID: 29064
Updated by: thekid@php.net
Reported By: daniel dot beet at accuratesoftware dot com
Status: Assigned
Bug Type: Sybase-ct (ctlib) related
Operating System: Windows 2000 Server
-PHP Version: 4.3.7
+PHP Version: 4.3.7 / HEAD
Assigned To: thekid
New Comment:
Testcase now available at:
http://sitten-polizei.de/php/bug29064.phpt
(place in ext/sybase_ct/tests and run make test TESTS=ext/sybase_ct, be
sure to edit ext/sybase_ct/tests/test.inc and supply correct DS_QUERY
and credentials there)
Previous Comments:
------------------------------------------------------------------------
[2004-07-11 15:29:26] thekid@php.net
Seeing that the PHP version in the Bug report was 4.3.7, I also made a
patch against the PHP4 branch.
http://sitten-polizei.de/php/float_precision-php4.diff
------------------------------------------------------------------------
[2004-07-11 13:56:26] thekid@php.net
Have a look at the following:
http://sitten-polizei.de/php/float_precision.diff
This accomplishes the "best-result"-semantics described in my above
comments. I use EG(precision) to check where we overflow - as I
understand, this value is the precision to which floats are still
"correct".
------------------------------------------------------------------------
[2004-07-11 13:26:01] thekid@php.net
Btw: Sybase-CT behaves like PHP itself (due to the afforementioned
reason):
$ php -r 'var_dump(12345678901234567890123456789012.123456);'
float(1.23456789012E+31)
(the above result depends on the precision set:
$ php -dprecision=20 -r
'var_dump((float)"12345678901234567890123456789012.123456");'
float(1.234567890123457E+31)
------------------------------------------------------------------------
[2004-07-11 13:19:19] thekid@php.net
Thank you for your bug report, first of all.
> /* numerics can overflow real and long types, return as a string */
I would not like to do that in general. I use the
convert_scalar_to_number() function (defined in Zend/zend_operators.c)
on numerics to achieve the "best" result, which is:
* If the scale is 0 and if it fits into an int, make it an int, make it
a float otherwise (this simulates PHP's behaviour when overflowing
LONG_MAX)
* If the scale is not 0, make it a float
Now what I forgot was that a float may not be able to hold the number
returned, therefore my suggestion would be to check for float overflow
and thus add this to the above list:
* If a float overflow is detected, make it a string
How's that?
------------------------------------------------------------------------
[2004-07-08 17:08:17] daniel dot beet at accuratesoftware dot com
Sorry, forgot the SQL to insert test data:
insert into test
(test_decimal, test_numeric, test_money, test_bigint, test_int,
test_smallmoney, test_smallint, test_tinyint, test_real, test_double)
values
(12345678901234567890123456789012.123456,
12345678901234567890123456.123456789012,
123456789012345.1234,
12345678901234567890123456789012345678,
1234567890,
123456.1234,
12345,
123,
123456789.12345679,
123456789.12345679
)
insert into test
(test_decimal, test_numeric, test_money, test_bigint, test_int,
test_smallmoney, test_smallint, test_tinyint, test_real, test_double)
values
(-12345678901234567890123456789012.123456,
-12345678901234567890123456.123456789012,
-123456789012345.1234,
-12345678901234567890123456789012345678,
-1234567890,
-123456.1234,
-12345,
255,
-123456789.12345679,
-123456789.12345679
)
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/29064
--
Edit this bug report at http://bugs.php.net/?id=29064&edit=1