这两种C#方法是否完全确定 - 因为它们在所有平台上产生相同的结果?
Fix64
struct
rawValue
字段long
。
ONE
是一个常量定义,如const long ONE = 1L << 32;
功能1 :
public static explicit operator Fix64(double value) {
return new Fix64((long)(value * ONE));
}
接收Fix64
值的 long
构造函数只会将其分配给rawValue
字段。这里讨论的操作是乘法。 ONE
将转换为double
。然后两个double
值将成倍增加。根据C#规范,这可以以更高的精度发生。然后,long
强制转换结果。如果在不同平台上使用不同的精度进行乘法,那么得到的long
值的最低有效位是否有可能不同?或者这种方法是完全确定的吗?
功能2 :
public static explicit operator double(Fix64 value) {
return (double)value.rawValue / ONE;
}
这与第一个例子类似。就在这里,我们在double
之间进行了除法运算,并将结果作为double
返回。是否有可能如果我们将此方法的结果与另一个double
进行比较,编译器可以在比较期间使结果double
更高精度?
另一个演员是否会确保此比较始终是确定性的?
(double)((double)value.rawValue / ONE)
编辑:这两个函数在FixedPoint64类型和double类型之间转换。这里的论点是,通过仅执行单个操作,我们不使用扩展中间浮点值进行其他操作。因此,通过立即将结果截断为标准精度,计算应该是确定性的。或者这个逻辑有什么缺陷吗?
答案 0 :(得分:0)
答案是肯定的,两者都是确定性的。解释我从这个库的作者那里得到的是:
对于乘法/除法,如果其中一个FP数是两个数(2 ^ x)的幂,则有效/尾数在计算期间不会发生变化。只有指数会改变(点会移动)。所以四舍五入永远不会发生。结果将是确定性的。
示例:像2 ^ 32这样的数字表示为(指数:32,尾数:1)。如果我们将它与另一个浮点数(exp,man)相乘,则结果为(exp + 32,man * 1)。对于除法,结果是(expo - 32,man * 1)。将尾数乘以1并不会改变尾数,因此它与它有多少位并不重要。