php浮动计算的2小数点
-
05-07-2019 - |
题
得到了另一个数学计算的问题。
$a = 34.56
$b = 34.55
$a
做一些计算,以得到这个图
$b
是这样做的四舍五入最近的0.05得到这个图
发生什么事是
$c = $b - $a
据说我应该-0.01,但我的回音的 $c
是显示-0.00988888888888
我尝试使用number_format($c, 2)
, 但对输出为0.00,
我怎能确保 $a
和 $b
正是2小数,没有任何隐藏的号码在背面。
在我php知识number_format只能格式显示器,但价值不是真的2小数
我希望我可以得到帮助从这里开始。这真的很沮丧我。
解决方案
尝试 sprintf
(" ;%。2f“,$ c);
浮点数用IEEE表示法表示,基于2的幂,因此终止十进制数可能不是终止二进制数,这就是你获得尾随数字的原因。
正如可变长度编码器所建议的那样,如果你知道你想要的精度并且它没有改变(例如当你处理钱时),最好只使用定点数,即将数字表示为分数而不是比美元
$a = 3456;
$b = 3455;
$c = $b - $a;
sprintf ("%.2f", $c/100.0);
这样,如果在打印前进行大量计算,则不会出现任何舍入错误。
其他提示
使用 round()
:
$c = round($b - $a, 2);
注意:您也可以根据需要选择舍入模式。
编辑:好的我没有得到 sprintf()
正在做的 number_format()
不是:
$c = number_format($b - $a, 2);
VS
$c = sprintf("%.2f", $b - $a);
原生计算:
$a = 34.56;
$b = 34.55;
$c = $b - $a; // -0.010000000000005
按预期工作(!使用BC函数进行实数计算,问题适用于所有基于C的平台):
$a = '34.56';
$b = '34.55';
$c = bcsub($b, $a, 4); // -0.0100
我最近在使用浮点数进行计算时遇到了这个问题。例如,我有2个浮点数,当减去并格式化时,值为-0.00。
$floatOne = 267.58;
$floatTwo = 267.58;
$result = number_format($floatOne - floatTwo, 2);
print $result; //printed a string -0.00
我做的是:
$result = abs($floatOne - $floatTwo);// Made the number positive
print money_format('%i', $result); // printed the desired precision 0.00
在我的解决方案中,我知道floatOne永远不会小于floatTwo。 仅当系统具有strfmon功能时,才会定义 money_format 功能, Windows没有。
你遇到了其中一个浮点数陷阱;它们不能总是代表精确的小数部分。如果你想要精确的十进制值,你最好使用整数然后除以你想要的精度。
例如,如果您在花车中进行计算,代表美元(或您最喜欢的货币),您可能希望以整数美分进行计算。
只需使用bcmath库,您就可以非常巧妙地回避所有这些问题。
请记住阅读文档,并注意是否将参数作为字符串或数值数据类型传递。
如果仍然有人找到这一页,与类似的问题在哪里浮动数量减除会导致错误或奇怪的价值观。我想解释一下这个问题一点的更多细节。罪魁祸首是浮点数。和不同的操作系统和不同版本的程序语言可以表现不同。
为了说明问题,我会解释为什么一个简单的例子如下。
它没有直接关系到PHP及它是不是一个错误。然而,每一个程序员应该意识到这一问题。
这个问题,甚至采取了许多人的生命二十年前。
月25日1991年这个问题在浮动数量计算在MIM-104爱国者导弹电池防止它拦截来飞毛腿导弹在宰赫兰、沙特阿拉伯,造成死亡,28名士兵,从美国军队第14军需部队。
但是,为什么会发生?
其原因是,浮点值表示有限的精确度。因此,一个值可能 没有相同的串的表示之后的任何处理。它还 包括编写一个浮点值在你的脚本和直接 印它没有任何数学运算。
只是一个简单的例子:
$a = '36';
$b = '-35.99';
echo ($a + $b);
你会希望它打印0.01,对吗?但是,它将打印一个非常奇怪的答案一样0.009999999999998
像其他数、浮点数双漂浮或者是在存储器中存储一串0和1的.怎么浮点不同于整数是在我们如何解释0和1的时候,我们要看看他们。有许多标准,它们是如何储存。
浮点数通常装成一个计算机数据作为的标志位,指数领域,而有效数或尾数,从左到右。...
小数不是好的二进制表示由于缺乏足够的空间。因此,uou不能表达的1/3,正是因为它的0.3333333...,对吗?我们为什么不能代表0.01作为二进制的浮动数量是出于同样的原因。1/100是0.00000010100011110101110000.....重复10100011110101110000.
如果0.01是保持简化和系统截断形式的01000111101011100001010在二,当它回到小数点,将它读起来就像0.0099999....根据系统(64位的计算机将让您从更精确的比32bits)。操作系统的决定,在这种情况下是否打印,因为它认为或如何使更多的人阅读的方式。因此,它是机器依赖于他们如何希望表示它。但它可以在保护语言水平不同的方法。
如果你格式的结果,回number_format(0.009999999999998,2);它将打印0.01.
这是因为在这种情况下您的指示应如何读取以及如何精确。