Synology PHP 32+ bit cannot be formatted in local format
I am facing a problem where I have financial numbers stored like DECIMAL
in MariaDB that are experiencing data loss when processing PHP 7. When using mysqli_query()
DECIMAL
get, it returns as a string. The biggest problem is a platform that has 32-bit hardware and therefore 32-bit PHP, so mine PHP_INT_MAX
is 2147483647
. When I do this:
var_dump(9876543210); // interpreted FLOAT because value > PHP_INT_MAX
means that you cannot bypass the PHP interpreter, which converts large numbers to floats, so precision is lost when performing calculations using fractions:
number_format('9876543210.0123456789', 10, ',', '.'); // ret '9.876.543.210,0123462677'
Formatting also doesn't work, because number_format()
converting the value to an inline value if it is not already a float, which makes it number_format()
useless for "large" numbers like 64-bit BIGINT
or DECIMAL
or DOUBLE
that belongs to MySQL .
Of course I searched SO and found answers. Some say you use GMP , but while it's "all cuddly and fresh" it doesn't handle floats . Alternative BCMath is better for the job. But then there is no way to use number_format () with big numbers.
Someone even managed to let MySQL do the calculations . I find this to be a PHP workaround, which doesn't suit my needs. The result can be formatted in locale , but not with MariaDB found on any current Synology NAS.
How to solve this puzzle in an elegant way ...?
source to share
As my application uses Intl to be locale aware, I tried its NumberFormatter . After setting the template , the formatter function takes strings as they exit MariaDB and formats them without losing precision, locales know:
$fmt = new NumberFormatter('de', NumberFormatter::DECIMAL);
$fmt->setPattern('0000000000.1111111111');
print $fmt->format('9876543210.0123456789'); // output '9876543210,0123456789'
Thus, the combination of BCMath and Intl is my preferred choice.
source to share