双精度浮点转定点_具有BCMathPHP中的定点数学,精度损失情况

本文探讨了在PHP中使用BCMath扩展处理定点数时遇到的问题,包括精度损失和指数表示。建议始终以字符串形式传递参数,并避免浮点数。同时,介绍了MySQL对定点数的支持,指出在PHP PDO扩展中固定点操作的局限性,推荐在PHP中完成所有数学运算,以确保精确性。
摘要由CSDN通过智能技术生成

双精度浮点转定点

When dealing with fixed point numbers, you have to be very careful – especially if you develop with PHP and MySQL. In this article, obstacles and subtleties of working with the PHP BCMath extension, MySQL fixed point expression handling and persisting fixed point data from PHP to MySQL are described. Despite the occurring barriers we try to figure out how to work with fixed point numbers and not to lose a digit.

处理定点数时,必须非常小心-特别是如果您使用PHP和MySQL开发。 在本文中,描述了使用PHP BCMath扩展,MySQL定点表达式处理以及将定点数据从PHP保留到MySQL的障碍和精妙之处。 尽管存在障碍,我们仍尝试找出如何使用定点数而不丢失数字。

BCMath的麻烦 (Troubles with BCMath)

BCMath documentation says:

BCMath文档说:

For arbitrary precision mathematics PHP offers the Binary Calculator which supports numbers of any size and precision, represented as strings.

对于任意精度数学,PHP提供了二进制计算器,该计算器支持任意大小和精度的数字,以string表示。

So BCMath function parameters should be represented as strings. Passing numeric values to bcmath can lead to wrong results, the same precision loss as when we treat double value as string

因此,BCMath函数参数应表示为字符串。 将数值传递给bcmath可能会导致错误的结果,与我们将double值视为字符串时的精度损失相同

情况1 (Case 1)

echo bcmul(776.210000, '100', 10) . PHP_EOL;
    echo bcmul(776.211000, '100', 10) . PHP_EOL;
    echo bcmul(776.210100, '100', 10) . PHP_EOL;

    echo bcmul(50018850776.210000, '100', 10) . PHP_EOL;
    echo bcmul(50018850776.211000, '100', 10) . PHP_EOL;
    echo bcmul(50018850776.210100, '100', 10) . PHP_EOL;

Results are:

结果是:

77621.00
    77621.100
    77621.0100
    5001885077621.00
    5001885077621.100
    5001885077621.00 //here we can see precision loss

Never pass numeric values to BCMath functions, only string values that represent numbers. Even when not dealing with floating points, BCMath can output strange results:

切勿将数字值传递给BCMath函数,仅将代表数字的字符串值传递给BCMath函数 。 即使不处理浮点,BCMath也会输出奇怪的结果:

情况二 (Case 2)

echo bcmul('10', 0.0001, 10) . PHP_EOL;
	echo bcmul('10', 0.00001, 10) . PHP_EOL;
	echo 10*0.00001 . PHP_EOL;

Results are:

结果是:

0.0010
	0 // thats really strange!!!
	0.0001

The reason for this is that BCMath converts its arguments to strings, and there are cases in which a number’s string representation has exponential notation.

原因是BCMath将其参数转换为字符串,并且在某些情况下,数字的字符串表示形式具有指数表示法。

情况3 (Case 3)

echo bcmul('10', '1e-4', 10) . PHP_EOL; //outputs 0 as well

PHP is a weakly typed language and in some cases you can’t control input in a strict way – you want to process as many reques

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值