Php 铸造浮动是否具有破坏性?

Php 铸造浮动是否具有破坏性?,php,floating-point,escaping,floating-accuracy,Php,Floating Point,Escaping,Floating Accuracy,在PHP中,我知道如果没有像bcmath这样的东西,我们不应该在浮点上进行数学运算,但仅仅是将字符串转换为浮点的行为是否具有破坏性 像(float)'5.111'='5.111'这样的表达式总是真的吗?或者,转换数字时,演员阵容本身会将其更改为类似于5.1110000000000199837 主要原因是,正如我使用(int)对进入数据库的整数值进行转义一样,我希望以同样的方式使用(float),而不必依赖引号和转义函数。不应该使用(int)转义整数值。使用参数化查询并将输入类型设置为“int”。

在PHP中,我知道如果没有像bcmath这样的东西,我们不应该在浮点上进行数学运算,但仅仅是将字符串转换为浮点的行为是否具有破坏性

(float)'5.111'='5.111'
这样的表达式总是真的吗?或者,转换数字时,演员阵容本身会将其更改为类似于
5.1110000000000199837

主要原因是,正如我使用
(int)
对进入数据库的整数值进行转义一样,我希望以同样的方式使用
(float)
,而不必依赖引号和转义函数。

不应该使用(int)转义整数值。使用参数化查询并将输入类型设置为“int”。一个更好的方法

有关mysql/php中的示例,请参见:

这取决于小数部分是否可以用二进制精确表示(请参阅)。例如,0.5具有精确的二进制表示,但0.1没有。如果数字没有精确的表示形式,则再次打印时可能会看到不同的结果。

,对浮点进行强制转换几乎总是具有破坏性的

在您的示例中,以二进制表示的5.111是:

101.00011100011010100111111011111001110110110010001011010000111001...
浮点数将存储23位数字:

101.0001110001101010011 
(5.1109981536865234375)
double可以存储52位数字:

101.0001110001101010011111101111100111011011001000101
(5.1109999999999988773424774990417063236236572265625)
在这种情况下,不会有什么不同。但是,如果数字较大,则会影响显示内容

例如:

1025.4995

双重:

10000000001.011111111101111100111011011001000101101
(1025.499499999999898136593401432037353515625)
浮动:

10000000001.011111111101
(1025.499267578125)
您可以看到精度在大约8位数后开始急剧下降


双精度将四舍五入到1025.4995,而浮点数将1025.4993

将整数转换为
没有什么问题。虽然我确实同意参数化查询通常更好,但这并不是因为它更安全。唯一安全的方法就是强迫你逃跑。但是如果你逃避自己,它就像使用参数化查询一样安全。在附加到查询之前强制类型绝对没有错。当然,还有其他方法可能有好处,但这并不像你的措辞所暗示的那样隐含错误。如果我可以使用参数,我会,但我不能。因为这个问题并不是专门针对这一点的,所以我觉得没有必要详细说明为什么我没有使用mysqli/PDO。最好是使用引号。特别是因为你不必使用浮点,而是十进制。引号中并没有什么不好的地方,所有数据的处理方式都是一样的(就像字符串一样)。是的,将字符串转换为浮点数会改变它的值。谷歌要问的问题是:“为什么在所有编程语言的浮点运算中,
0.1
plus
0.2
不等于
0.3
?”答案是因为计算机无法在使用base-2二进制数的软件中精确表示0.2。这里有一个很好的视频来解释这个问题:我现在真的很担心,因为
number\u format
将输入转换为float,就像
money\u format
一样……我不认为我会将money转换为float。。。但这取决于你在做什么,以及它在实际意义上是否重要。如果你处理的是小于10000.00的数字,你只需要一分钱的精度,那可能没关系。此外,当您失去精度时,浇铸数将始终较小,而不是较大。