模数给出了错误的结果?
谁能告诉我为什么这两个模数计算产生两种不同的结果? 我只是需要责怪某人或某事而不是我,因为我找不到这个错误。
public void test1() { int stepAmount = 100; float t = 0.02f; float remainder = t % (1f / stepAmount); Debug.Log("Remainder: " + remainder); // Remainder: 0.01 float fractions = 1f / stepAmount; remainder = t % fractions; Debug.Log("Remainder: " + remainder); // Remainder: 0 }
使用VS-2017 V15.3.5
我最好的选择是,这是由于运行时必须以比所涉及的类型更高的精度执行浮点运算,然后在分配时将结果截断为类型的精度:
第12.1.3节中的CLI规范规定了浮点数(float和double)在存储位置使用时的精确精度。 但是,当在其他位置(如执行堆栈,参数返回值等)中使用浮点数时,它允许超出精度。使用的精度是运行时和底层硬件。 这种额外的精度会导致不同机器或运行时间之间浮点评估的细微差别。
来源于此 。
在第一个示例中, t % (1f / stepAmount)
可以完全以高于float
精度执行,然后在将结果分配给remainder
时截断,而在第二个示例中, 1f / stepAmount
被截断并分配给之前的fractions
模数运算。
至于为什么使用stepamount
一个const
使得两个模数运算一致,原因是1f / stepamount
立即成为一个常量表达式,在编译时被计算并截断为浮点精度,与写入0.01f
没有区别,这实际上使两个例子等效。