c浮点数上的模运算符



下面的代码对数值0.01、0.02、0.03、…、0.99 运行模数0.01

var testVals = Enumerable.Range(1, 99).Select(n => double.Parse("0." + n.ToString("D2")));
var moduloTest = testVals.Select(v => v % 0.01).ToList();

(注意:解析字符串中的doubles是有意的,这样对float进行的唯一数学运算就是模数(

我希望这里的moduleTest列表包含几个非常接近0的浮点值。然而,列表中的许多值都非常接近0.1。

我知道浮点数学是不精确的,并引入了舍入误差,但这里的0.1甚至不接近0。

我知道浮点数学并不精确,但在这里的许多情况下,它似乎甚至不精确。

这里的模数并没有增加误差/不精确性,只是使先前不精确性的影响非常明显。


对于模数的高质量实现,不存在不精确性。请参见当y是整数时fmod((是否精确?。

问题在于,假设具有0.01等十进制值的数学总是表现得接近那些转换为最接近可表示浮点值的值。有限的浮点值都是精确的。正是这些运算形成了它们的值;错误";除了一些例外,比如模数。

以十六进制或足够的小数精度打印值(如17位有效的小数位数(通常足以显示预期的0.01不是作为0.01编码的浮点值,而是接近的值。对计算结果也要这样做,以获得更深入的见解。

模数运算的性质是锯齿形曲线,就像这里的绿线。

给定在0.01转换和/中产生的误差(不是模量(,OP值的模量的结果是,预期仅在不连续的两侧:大约0.0或接近0.01。

当我输入这个时,我意识到了答案。它确实是由于浮动的不精确性而发生的。只是对于模运算,与大多数数学运算不同,值的一个小的不精确性可能会导致结果的大差异。

例如,0.03在浮点中最接近地表示为0.299999999999999,如果你在上做模数0.01,就会得到0.0999999999999 这样的数字

最新更新