Php 为什么0.5 mod 0.1在不同的编程语言中会产生不同的结果?

Php 为什么0.5 mod 0.1在不同的编程语言中会产生不同的结果?,php,.net,modulo,Php,.net,Modulo,我有一个关于模的问题。模运算找到一个数除以另一个数的余数。我希望0.5%0.1的结果等于0。但当我在PHP或.net中运行时,我得到了0.1 我运行的php代码是: var_dump(fmod(0.5, 0.1)); 在.net中,我尝试了以下结果: Console.WriteLine(0.5%0.1); 我还试过一个在线计算器 这三种方法的答案都是0.1 但是当我在谷歌上输入这个时,我得到了我期望的结果 这是.net/php中的错误还是google知道正确答案?有人能解释为什么会出现这些差

我有一个关于模的问题。模运算找到一个数除以另一个数的余数。我希望0.5%0.1的结果等于0。但当我在PHP或.net中运行时,我得到了0.1

我运行的php代码是:

var_dump(fmod(0.5, 0.1));
在.net中,我尝试了以下结果:

Console.WriteLine(0.5%0.1);
我还试过一个在线计算器

这三种方法的答案都是0.1

但是当我在谷歌上输入这个时,我得到了我期望的结果


这是.net/php中的错误还是google知道正确答案?有人能解释为什么会出现这些差异吗?

0是整数答案,0.1是正确的浮点结果


另外看看wolframalpha:

如果你想计算
0.5%0.1
,你可能(也应该)使用整数算术。例如,如果你在计算涉及货币的东西,通常最好将美分数存储为整数,而不是将金额存储为浮点数。

不,这不是错误,因为模运算也可以在浮点数上定义。在PHP代码中,你可以明确地使用<代码> fMODER()/>代码>而不是<代码> %>代码>,在.NET中,<代码> %s/COD>运算符在每个数值类型()

> P>上定义,在PHP或C++、Python或Python中得到的数字或当你要求0.1时,都是双精度浮点数,这意味着它是一个有限的“十进制”。--有53个有效位,包括第一个1位--在基2中。事实上,你得到的是最接近于0.1的可精确表示的数字,我认为正好是0.10000000000000055115123125782702118158340451015625

另一方面,0.5是有限的“双映像”;当您请求该值时,得到的值正好是0.5

因此,0.5只是略小于“0.1”的5倍,因此“0.5 mod 0.1”实际上给出了略小于0.1的值。事实上,我认为它正好是0.099999999997779553950749686919152736663818359375

现在,当您要求PHP或C#或任何东西显示这个数字时,它将显示一些有限的数字。你真的不想让它展示整个可怕的东西。(考虑一下:假设你只要求显示0.1;你是想要一个无数位数的怪物,还是想要“0.1”?我想是的。)而这个数字实际上非常接近0.1;除非您要求超过15位的精度,否则正确的显示方式仅为“0.1”

观察(这是Python,我碰巧有它):

所以:不是虫子;这并不是说浮点不适合“精确计算”(有时是合适的,有时不是;问题是要理解它在做什么和需要什么);根据您的实际需要,可能表示您使用整数会做得更好,也可能不表示您使用整数会做得更好

关于这件事,你可能想知道的更多,看一看


至于为什么谷歌的计算器会给出预期的答案0,我不知道。也许他们正在使用十进制算术——实数以10为基数——来最小化意外的惊喜。(这通常比使用本机浮点运算慢得多,但谷歌有很多可用的CPU,我敢打赌他们的搜索处理机器所做的工作中只有一小部分与计算器有关。)

如果你感兴趣,你会得到JS中的
0.09999999999998
(不同的语言,但问题——浮点错误——是相同的)“0是整数答案”,您的意思是“0是有理数答案”。
>>> for n in range(10,20): print (("%%.%dg"%n)%(0.5%0.1))

0.1
0.1
0.1
0.1
0.1
0.1
0.09999999999999998
0.099999999999999978
0.0999999999999999778
0.0999999999999999778