我执行某些数据类型转换,我需要代表uint
, long
, ulong
和decimal
作为IEEE 754双浮点值。 我希望能够检测如果IEEE 754数据类型不能包含的价值之前,我进行了转换。
蛮力解决方案是环绕铸造一个try-catch翻番寻找OverflowException
。 通过一定的阅读CLR文件意味着,有些转换只是默默地改变数值没有任何异常。
是否有任何一个傻瓜证明的方式做这个检查? 我在寻找完整性超过易于实现。 我有一种感觉,我会密切读取IEEE 754规范和检查matissa并仔细李氏指数...
我要补充,我最关心的是准确地代表整数和浮点精度的损失是次要的(但仍然值得考虑)的。
编辑:的Int32能够得到充分的体现为IEE-754。 另外, Decimal
数据类型是问题的很大一部分。
重要更新:如果你指的是这个问题,你也应该看这个问题: 重访IEEE-754双精度(64位浮点)与长(64位整数)
它指出在一些非常大的价值,也能够通过IEEE-754精确表示,答案的一个缺陷。 虽然这可能意味着该值将正确地往返,我最初的目的(将它往返的JavaScript)不会。
也有似乎是在的CLR System.Double类型的错误,因为它不正确地允许将这些值往返。
简单的解决方案可能是这样的( 如果x是一个int):
if ((int)(double)x != x) {
// won't convert
} else {
// will convert
}
等长,等
(双)x将X转换从int到两倍。 该(INT)然后再转换回来。 所以(INT)(双)X转换形成一个int到双,然后返回。 实质上,代码检查转换到加倍是可逆的(因此,双可以存储INT的精确值)。
这主要取决于范围你和操作数。 只要你是15位(对于内双 ),你应该在安全方面为整数。
基本上,你需要考虑什么是显著位数。 所以只要你数比显著位数限制更小,它仍将准确; 如果它变得更大,你会失去精度(即使这些是整数)。
所以只要你的电话号码是<2 ^ 53,你平时好。
IEEE 754双有尾数52位,并正在从/转换成整数/长 ,所以很容易测试。 如果你的整数消耗少于52位,那么它应该是没有问题IEEE 754双敞篷车。
我认为(我肯定知道的情况下,Java的,但不是C#和懒惰检查)是int是32位,长为64位。 所以,可以肯定的INT能装双没有任何问题都标志和unsign。
对于ULONG,您只需如果比第52位更高的所有位是一个像((安龙&& 0xFFF0000000000000)== 0)。
对于长,你必须将其登录审议。 由于龙是第二次补,但IEEE754不是(只是有负位),它认为它是安全的,只是隐蔽负长正(* 1),并检查一样积极。 因此,如果长期为负,与-1第一次(什么都不做正)。 然后,检查它像ULONG。
希望这可以帮助。