80位浮点数和次正规数
80-bit floating point and subnormal numbers
我正在尝试将80位扩展精度浮点数(在缓冲区中)转换为双精度。这个缓冲区基本上包含了一个x87寄存器的内容。
这个问题帮助我开始,因为我不太熟悉IEEE标准。无论如何,我正在努力寻找80位格式的次常态(或非规范化)数字的有用信息。我所知道的是,与float32或float64不同,它在尾数中没有隐藏位(没有隐含的1.0添加),因此了解数字是否规范化的一种方法是检查尾数中的最高位是否设置。这给我留下了以下问题:
维基百科告诉我,float32和float64表示一个次正规数,指数为0,尾数非零。
- 这在80位浮点数中告诉我什么?
- 可以使用尾号<1.0有非零指数吗?
- 或者,指数为0的80位浮点数甚至有尾数>= 1.0吗?
我可以期望FPU消毒x87寄存器中的指数和最高尾数位吗?
如果不是,转换结果应该是什么样的数?在这种情况下,我应该完全忽略指数吗?还是qNaN?
编辑:我阅读了英特尔手册(英特尔®64和IA-32架构软件开发人员手册,卷1:基本架构)中的FPU部分,这比我担心的要少得多。结果是以下值没有定义:
- 指数== 0 +尾数与最高位集
- 指数!= 0 +尾数,没有最高位集
它没有提到这些值是否可以在野外出现,也没有提到它们是否可以在内部转换。因此,我实际上重新使用Ollydbg并手动设置x87寄存器中的位。我精心设计了ST(0),以包含指数中设置的所有位和尾数0。然后我让它执行
FSTP QWORD [ESP]
FLD QWORD [ESP]
存储在[ESP]
的值转换为信令NaN。在FLD
之后,ST(0)
包含一个安静的NaN。
不管怎样,案子解决了。谢谢,每一个人。
尝试SoftFloat库,它有floatx80_to_float32
, floatx80_to_float64
和floatx80_to_float128
。检测本地格式,并相应地执行
查找亚正常80位数字信息的问题可能是因为8087没有对它们使用任何特殊的非规范化。在msdn的float (C)类型页面上发现:
本表所列值仅适用于规范化浮点数;非规范化浮点数有较小的最小值。注意在80x87寄存器中保留的数字总是以80位规范化形式表示;数字只能是在32位或64位存储时以非规范化形式表示浮点变量(float和long类型的变量)。
编辑
对于微软如何使用fpu寄存器,上述可能是正确的。
FPU数据类型:
80x87 FPU通常以规范化格式存储值。当一个浮点数归一化后,H.O.位总是1。在32位和64位浮点格式,80x87实际上没有存储这个位,80x87总是假定它是1。因此,3264位浮点数总是标准化的。扩展精度80位浮点格式,80x87没有假设尾数的h。o。位是1,h。o
规格化值提供给定数量的最大精度位。然而,存在大量的非规范化值我们可以用80位的格式表示。这两个值非常接近到零,并表示尾数h。o。位不是的值的集合零。80x87 fpu支持一种特殊的80位形式,称为非规范化值。
- 使用英特尔内联函数将打包的 8 位整数乘以浮点数向量
- 在数学上将浮点数四舍五入到 N 位小数
- 位设置为浮点数或双精度值 c++
- 浮点数为 32 位和 64 位二进制表示形式
- 使用 int 指针的浮点数的位表示形式
- OpenCV矩阵奇怪的加法,乘法与浮点数和8位值
- 使用按位 AND 和 popcount 而不是实际的 int 或浮点数乘法进行大 (0,1) 矩阵乘法
- 如何在C++中进行32位十进制浮点数乘法?
- 如何在 c++ 中使用 FFT 从 32 位浮点数组中提取频率
- 将 32 位浮点数和不强制转换的 32 位整数与双精度进行比较,当其中一个值可能太大而无法完全适合另一种类型时
- 为什么 std::setprecision 显示不存在的精度位以及如何查看实际浮点数
- 在 C/C+ 中从 16 位线性 PCM 音频转换为 32 位浮点数的最佳方法
- 小数点后4位的随机浮点数
- 尚未操作的 32 位规范化浮点数在任何平台/编译器上是否相同?
- 移植将 32 位浮点数与使用 64 位进行比较的代码,此值表示什么
- 将浮点数 32 位变量类型转换为无符号整数 32 位时进行了哪些位级更改
- 无符号短至自定义浮点数 16 位
- 如何将浮点数转换为保留位值的整数
- 清除单个精度浮点数的位
- 80位浮点数和次正规数