为什么PHP似乎不正确地评估这种情况? [英] Why does PHP appear to evaluate this condition incorrectly?

查看:117
本文介绍了为什么PHP似乎不正确地评估这种情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在PHP中有以下代码,其中我试图通过将变量类型转换为整数来避免浮点错误,通过将所有值乘以100,然后进行比较,以删除2个十进制

I have the following code in PHP, where I've attempted to overcome the stated issue by type-casting the variables into Integers and also avoiding floating-point errors by multiplying all values by 100 before comparison in order remove the 2 decimal places.

但是,以下代码仍然将表达式计算为true,并将文本颜色为红色而不是绿色,但是当我回显$ eq_left和$ eq_right的两个值

However, the following code still evaluates the expression to true and colours the text in red instead of green but when I echo the two values of $eq_left and $eq_right, they are identical with no decimal point.

以下是代码:

$eq_left    = (int) ($eq_bal_CurrentAssets*100) + ($eq_bal_NonCurrentAssets*100) ;
$eq_right   = (int) ($eq_bal_Liabilities*100) + ($eq_bal_Taxation*100) + ($eq_bal_Equity*100) ;

if ($eq_left !== $eq_right) {
    $color = 'red';
    $diff   = abs($eq_left - $eq_right);
} else {
    $color = 'green';
}

echo "<div style=\"color: $color; font-weight:bold;\">\n";
echo "  " . number_format(($eq_left/100),2,".",",") . " = " . number_format(($eq_right/100),2,".",",") . "<br />\n";
if ($diff) {
    echo "      Difference = " . number_format(($diff/100),2,".",",") . "\n";
}
echo "</div>\n";
echo $eq_left . " | " . $eq_right

任何想法?

推荐答案

如果你想要精确的小数表示,我同意对浮点的建议。

I agree with the recommendation against floating point if you want exact decimal fraction representation.

原因是许多小数分数只能在float或double中近似。它们基于二进制,而不是小数。一般来说,当且仅当b的所有素因子也是b的素因子时,在基数r表示中可以精确地表示在a和b中没有公因子的有理数a / b。例如,十进制1/5中为0.2,但1/3为0.333333333 ...在二进制系统中,1/5导致与十进制中的1/3相同的问题。

The reason is that many decimal fractions can only be approximated in float or double. They are based on binary, not decimal, fractions. In general, a rational number a/b, with no common factors in a and b, can be expressed exactly in a radix r representation if, and only if, all prime factors of b are also prime factors of b. For example, in decimal 1/5 is 0.2, but 1/3 is 0.333333333... In a binary system, 1/5 causes the same problem as 1/3 in decimal.

在你的代码中,我建议在乘以100后舍入到小数点后第0位。(int)向0舍入,这不是你需要的。如果输入甚至略小于正整数n,则转换的结果是n-1。 round的结果为n。

In your code, I suggest rounding to zero decimal places after doing the multiplication by 100. The (int) cast rounds towards zero, which is not what you need. If the input is even slightly less than a positive integer n, the result of the cast is n-1. The result of round is n.

不能精确表示的小数分数的浮点表示可能稍低或稍高于原始小数。如果您以0.29,将其转换为最接近的IEEE 754 64位浮点数,并乘以100,则实际得到的浮点数等于28.999999999999996447286321199499070644378662109375

The floating point representation of a decimal fraction that cannot be represented exactly may be either slightly lower or slightly higher than the original decimal fraction. If you start with e.g. 0.29, convert it to the nearest IEEE 754 64 bit float, and multiply by 100 you will actually get the floating point equivalent of 28.999999999999996447286321199499070644378662109375

将其转换为int,给出28,而不是29.将其四舍五入到最近的int将得到29。

Converting that to int with rounding towards zero gives 28, not 29. Rounding it to the nearest int would give 29.

这篇关于为什么PHP似乎不正确地评估这种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆