我正在执行一些数据类型转换,我需要在其中表示 uint
、long
、ulong
和 decimal
作为 IEEE 754 双浮点值。我希望能够在执行转换之前检测 IEEE 754 数据类型是否不能包含该值。
一个蛮力解决方案是将 try-catch 包裹在强制转换中以双重查找 OverflowException
。阅读某些CLR documentation意味着某些转换只是默默地更改值,没有任何异常(exception)。
有没有简单的方法来做这个检查?我正在寻找完整性而不是易于实现。我有一种感觉,我将仔细阅读 IEEE 754 规范并仔细检查 matissa 和指数......
我应该补充一点,我最关心的是准确表示整数,而浮点精度的损失是次要问题(但仍值得考虑)。
编辑: Int32 能够完全表达为 IEE-754。 Decimal
数据类型也是问题的重要组成部分。
重要更新:如果您指的是这个问题,您还应该阅读这个问题:IEEE-754 Double (64-bit floating point) vs. Long (64-bit Integer) Revisited
它注意到答案中的一个缺陷,即一些非常大的值也可以由 IEEE-754 准确表示。虽然这可能意味着该值将正确往返,但出于我最初的目的(它将往返到 JavaScript)它不会。
CLR System.Double 类型中似乎也存在错误,因为它不能正确地允许这些值往返。
最佳答案
简单的解决方案可能类似于(如果 x 是一个整数):
if ((int)(double)x != x) {
// won't convert
} else {
// will convert
}
等等等等
(double)x 会将 x 从 int 类型转换为 double 类型。 (int) 然后将其再次转换回来。所以 (int)(double)x 将 int 转换为 double 然后再转换回来。本质上,代码正在检查到 double 的转换是否可逆(因此 double 可以存储 int 的确切值)。
关于c# - 如何测试数值转换是否会改变值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1601646/