为什么这个条件错了?

时间:2016-11-03 14:38:20

标签: php string floating-point comparison

我的代码中发生了一些奇怪的事情。有人可以解释一下,为什么这个条件是假的?

当我使用php的函数from PyQt5 import QtWidgets class MyWizard(QtWidgets.QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # vertical layout, wraps content layout and buttons layout vertical_layout = QtWidgets.QVBoxLayout() self.setLayout(vertical_layout) # content widget and layout self.content_layout = QtWidgets.QVBoxLayout() # could be almost any layout actually self.content = QtWidgets.QLabel('Page1') # customize with your content self.content_layout.addWidget(self.content) vertical_layout.addLayout(self.content_layout) # back, forward buttons wraped in horizontal layout button_layout = QtWidgets.QHBoxLayout() button_layout.addStretch() back_button = QtWidgets.QPushButton('Back') back_button.clicked.connect(self.back_button_clicked) button_layout.addWidget(back_button) forward_button = QtWidgets.QPushButton('Forward') forward_button.clicked.connect(self.forward_button_clicked) button_layout.addWidget(forward_button) vertical_layout.addLayout(button_layout) def back_button_clicked(self): """ The back button is clicked. """ pass def forward_button_clicked(self): """ The forward button is clicked. """ # remove old content self.content_layout.removeWidget(self.content) self.content.deleteLater() # create new content self.content = QtWidgets.QLabel('Another Page') # add new content self.content_layout.addWidget(self.content) app = QtWidgets.QApplication([]) wizard = MyWizard() wizard.setWindowTitle('MyWizard Example') wizard.setFixedSize(600, 400) wizard.show() app.exec_() 输出对象的成员时,我得到了这个:

var_dump()

来自一个对象,这是从另一个对象输出的:

string(6) "105.63"
float(105.63)

然后我做这样的比较:

string(6) "667.69"
float(667.69)

如果我们像上面的例子中那样编写代码,它肯定会输出2次if(105.63 == "105.63"){ echo "true"; } else { echo "false"; } if(667.69 == "667.69"){ echo "true"; } else { echo "false"; } 。但在我的课堂上,它表现得与众不同。在第一个true我获得if,在第二个false我获得if。然后我用true函数更深入地查看了数据,看起来我实际上有以下数据:

var_export()

'105.63'
105.6300000000000096633812063373625278472900390625

所以我决定检查我的条件是否适用于那些数据......而且他们不这样做。实际上,只有第一个没有。为什么我会在以下代码中获得输出'667.69' 667.69000000000005456968210637569427490234375 false

true

我知道如何解决这个问题。但我很感兴趣,为什么条件会在第一个if(105.6300000000000096633812063373625278472900390625 == "105.63"){ echo "true"; } else { echo "false"; } if(667.69000000000005456968210637569427490234375 == "667.69"){ echo "true"; } else { echo "false"; } 失败。

修改

当我们使用if比较运算符时,Php会输入类型! 看看这个:

==

输出:

var_export((float) "105.63");
var_export((string) 105.6300000000000096633812063373625278472900390625);
var_export((float) "667.69");
var_export((string) 667.69000000000005456968210637569427490234375);

这不应该意味着第一个条件是真的而第二个条件是假的吗?但是我先是假的,第二次是真的。对不起,如果我不清楚。

1 个答案:

答案 0 :(得分:3)

查看手册:http://php.net/manual/en/language.types.float.php

有一个关于比较浮点数的重要警告部分:

警告

  

浮点精度

     

浮点数的精度有限。虽然这取决于   在系统中,PHP通常使用IEEE 754双精度格式,   由于订单的舍入,这将产生最大的相对误差   1.11e-16。非基本算术运算可能会更大   错误,当然,必须考虑错误传播   几个操作复杂化。另外,理性的数字   可以完全表示为基数10中的浮点数,例如   0.1或0.7,没有精确表示为基数2中的浮点数,它在内部使用,无论大小如何   尾数。因此,它们无法转换为内部二进制文件   对应物没有精确的损失。这可能会导致   令人困惑的结果:例如,楼层((0.1 + 0.7)* 10)通常会   返回7而不是预期的8,因为内部表示   将是像7.9999999999999991118 ....所以永远不要相信   浮点数结果为最后一位数,并且不比较浮点数   点数直接表示相等。如果需要更高的精度,   任意精度数学函数和gmp函数都是   可用。有关“简单”的解释,请参阅»浮点指南   这也标题为“我的数字为什么不加起来?”

Why dont my numbers add up?