模数给出了错误的结果?

Mad*_*nyo 14 c# modulus

谁能告诉我为什么这两个模数计算产生两种不同的结果?我只需责怪别人或其他东西而不是我,因为我找不到这个错误.

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
}
Run Code Online (Sandbox Code Playgroud)

使用VS-2017 V15.3.5

InB*_*een 8

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

第12.1.3节中的CLI规范规定了浮点数(float和double)在存储位置使用时的精确精度.但是,当浮点数用于其他位置(如执行堆栈,参数返回值等)时,它允许超出精度.使用的精度是运行时和底层硬件的精度.这种额外的精度可能导致不同机器或运行时之间浮点评估的细微差别.

来源于此.

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

至于为什么使stepamount一个const使两个模运算一致的,其原因是,1f / stepamount立即成为恒定表达式,它是评估和截短在漂浮精度编译时和没有从写入不同0.01f,其基本上使得等效这两个例子.