刷新浮点数(也是PDF)、IEEE-754 并参与了关于在转换为字符串时进行浮点舍入的讨论,这让我想到了修补程序:如何获得二进制表示的给定浮点数的最大值和最小值是平等的。
免责声明:对于本次讨论,我喜欢使用 IEEE-754 描述的 32 位和 64 位浮点。我对扩展浮点(80 位)或四边形(128 位 IEEE-754-2008)或任何其他标准(IEEE-854)不感兴趣。
背景:计算机不擅长以0.1
二进制表示。在 C# 中,浮点数将其表示为3DCCCCCD
内部(C# 使用四舍五入),双精度数表示为3FB999999999999A
. 相同的位模式用于十进制0.100000005
(float) 和0.1000000000000000124
(double),但不用于0.1000000000000000144
(double)。
为方便起见,以下 C# 代码给出了这些内部表示:
string GetHex(float f)
{
return BitConverter.ToUInt32(BitConverter.GetBytes(f), 0).ToString("X");
}
string GetHex(double d)
{
return BitConverter.ToUInt64(BitConverter.GetBytes(d), 0).ToString("X");
}
// float
Console.WriteLine(GetHex(0.1F));
// double
Console.WriteLine(GetHex(0.1));
在 的情况下0.1
,没有用相同位模式表示的小十进制数,任何0.99...99
将产生不同的位表示(即,内部0.999999937
产生的浮点数3F7FFFFF
)。
我的问题很简单:如何找到内部存储在相同二进制表示中的给定浮点(或双精度)的最低和最高十进制值。
为什么:(我知道你会问)在 .NET 转换为字符串以及从字符串转换时查找舍入错误,以找到内部精确值并更好地理解我自己的舍入错误。
我的猜测是这样的:取尾数,去掉其余的,得到它的确切值,得到一个(尾数位)高,然后计算平均值:低于它的任何东西都会产生相同的位模式。我的主要问题是:如何将小数部分作为整数(位操作它不是我最强的资产)。Jon Skeet 的 DoubleConverter类可能会有所帮助。