模数给出错误的结果?

Modulus gives wrong outcome?

谁能告诉我为什么这两个模数计算会产生两个不同的结果?我只需要责怪某人或某物,但我却找不到这个错误的所有那些时间。

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

我最好的选择是,这是由于运行时必须自由地执行比所涉及的类型精度更高的浮点运算,然后在分配时将结果截断为类型的精度:

The CLI specification in section 12.1.3 dictates an exact precision for floating point numbers, float and double, when used in storage locations. However it allows for the precision to be exceeded when floating point numbers are used in other locations like the execution stack, arguments return values, etc … What precision is used is left to the runtime and underlying hardware. This extra precision can lead to subtle differences in floating point evaluations between different machines or runtimes.

来源here.

在您的第一个示例中,t % (1f / stepAmount) 可以完全以比 float 更高的精度执行,然后在将结果分配给 remainder 时被截断,而在第二个示例中,1f / stepAmount 在模数运算之前被截断并分配给 fractions

至于为什么让stepamount变成const使得两个取模运算一致,原因是1f / stepamount立即变成一个常量表达式,在编译时间 并且与编写 0.01f 没有什么不同,后者本质上使两个示例等效。