将整数转换为新的浮点格式
Posted
技术标签:
【中文标题】将整数转换为新的浮点格式【英文标题】:Convert integer in a new floating point format 【发布时间】:2021-08-18 17:31:54 【问题描述】:此代码旨在将带符号的 16 位整数转换为新的浮点格式(类似于正常的 IEEE 754 浮点格式)。我理解常规的 IEEE 754 浮点格式,但我不明白这段代码是如何工作的,以及这种浮点格式是什么样子的。我将不胜感激代码的概念分别是多少位用于表示有效数字以及多少位用于表示这种新格式的指数。
#include <stdint.h>
uint32_t short2fp (int16_t inp)
int x, f, i;
if (inp == 0)
return 0;
else if (inp < 0)
i = -inp;
x = 191;
else
i = inp;
x = 63;
for (f = i; f > 1; f >>= 1)
x++;
for (f = i; f < 0x8000; f <<= 1);
return (x * 0x8000 + f - 0x8000);
【问题讨论】:
这不是我所谓的好代码;它是以一种非常难以理解的方式编写的。你在哪些方面苦苦挣扎? 你有代码,运行一些测试用例,看看它输出什么...... 【参考方案1】:这两个技巧应该可以帮助您识别自定义浮点格式的参数(指数大小和尾数大小):
首先,这个浮点数长多少位?
我们知道符号位是任何负浮点数中设置的最高位。如果我们计算short2fp(-1)
,我们得到0b10111111000000000000000
,这是一个23位的数字。因此,此自定义浮点格式是 23 位浮点数。
如果我们想知道指数和尾数的大小,我们可以转换数字3
,因为这将设置最高指数位和最高尾数位。如果我们做short2fp(3)
,我们得到0b01000000100000000000000
,如果我们拆分这个数字,我们得到0 1000000 100000000000000
:第一位是符号,那么我们有7位指数,最后是15 位尾数。
结论:
Float format size: 23 bits
Exponent size: 7 bits
Mantissa size: 15 bits
注意:由于多种原因,这个结论可能是错误的(例如:浮点格式与 IEEE754 格式特别不同,short2fp()
函数无法正常工作,今天早上咖啡太多等),但在一般来说,这适用于 IEEE754 定义的每种二进制浮点格式(binary16、binary32、binary64 等),所以我相信这也适用于您的自定义浮点格式。
P.S.:short2fp()
函数写得很烂,如果你想研究函数的内部工作原理,可以尝试提高它的清晰度。
【讨论】:
【参考方案2】:x = 191;
和 x = 63;
两个语句将 x
设置为 1•128 + 63 或 0•128 + 63,根据数字是负数还是正数。因此 128 (27) 在这一点上有符号位。由于x
后来乘以 0x8000 (215),结果中的符号位为 222。
这些语句还将指数初始化为 0,由于偏差为 63,它被编码为 63。这遵循 IEEE-754 模式,即使用偏差 2n−1 -1 表示 n 位的指数字段。 (“单”格式有 8 个指数位,偏差为 27-1 = 127,“双”格式有 11 个指数位,偏差为 210−1 = 1023。)因此,我们期望一个 7 位的指数字段,偏差为 26-1 = 63。
这个循环:
for (f = i; f > 1; f >>= 1)
x++;
检测i
的大小(输入的绝对值),将检测到超过f
的每个2 的幂的指数加1。例如,如果输入是 4、5、6 或 7,则循环执行两次,将 x
加 2 并将 f
减为 1,此时循环停止。这证实了指数偏差;如果i
为1,则x
保持不变,因此初始值63 对应于指数0 和表示值20 = 1。
循环 for (f = i; f < 0x8000; f <<= 1);
以相反方向缩放 f
,将其前导位移动到 0x8000 位置。
在return (x * 0x8000 + f - 0x8000);
中,x * 0x8000
将符号位和指数字段从它们的初始位置(第 7 位和第 6 位到 0)移动到它们的最终位置(第 22 位和第 21 到 15 位)。 f - 0x8000
从f
中删除前导位,给出有效数字的尾随位。然后将其添加到最终值中,形成第 14 位到第 0 位中有效数字的主要编码。
因此,格式在第 22 位中具有符号位,在第 21 到 15 位中具有偏差为 63 的指数位,在第 14 到 0 位中具有尾随有效位。
该格式可以以通常的方式对次正规数、无穷大和 NaN 进行编码,但这在所示代码中无法辨别,因为它仅编码正常范围内的整数。
【讨论】:
【参考方案3】:正如评论所建议的那样,我将使用少量战略性选择的测试用例来对格式进行逆向工程。下面假设 IEEE-754-like 二进制浮点格式使用带有符号位、指数位和有效数(尾数)位的符号幅度编码。
short2fp (1) = 001f8000
而short2fp (-1) = 005f8000
。它们的异或是0x00400000
,这意味着符号位在第 22 位,这种浮点格式包含 23 位。
short2fp (1) = 001f8000
、short2fp (2) = 00200000
和 short2fp (4) = 00208000
。连续值之间的差是0x00008000
,所以指数字段的最低有效位是第15位,指数字段包括7位,指数偏差(0x001f8000 >> 15) = 0x3F
= 63。
这为有效数字留下了最低有效的 15 位。从short2fp (2) = 00200000
可以看出,有效数(尾数)的整数位没有被存储,也就是说,它是隐式的,就像在binary32
或binary64
这样的IEEE-754格式中。
【讨论】:
我特别喜欢符号位确定。以上是关于将整数转换为新的浮点格式的主要内容,如果未能解决你的问题,请参考以下文章
python 在Pandas(Python)中将整数转换为浮点格式