刷新 浮点数(也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's DoubleConverter类可能有所帮助。