C 将int映射为float?
我想实现从整数到浮点的映射,但我的底层知识有点生疏。本文描述了映射: 3.2到整数的映射 我们可以通过浮点计算预测残差 减法,但这可能会导致不可逆的下溢 无法重建的信息丢失> 实际值。相反,如[7,22]中所述,我们映射了预测的 和实际浮点p和f的符号大小二进制 整数表示。关于实现signmagnity的平台 整数算术,我们现在可以简单地计算 通过减法得到的整数残差,但大多数当前平台 实现二的补码算法。解决 这样,我们将符号大小表示映射为无符号 通过翻转最高有效位(对于正 浮点)或所有位(用于负浮点)。结果是一场灾难 浮点数到无符号整数的单调映射 浮点数差的排序和均匀线性 具有相同的符号和指数。这种方法也是可行的 与[16]类似,但我们通过允许结转 在p和f为的情况下,从尾数传播到指数 接近但被指数边界分隔,这将 在[16]中被标记为严重预测失误 还有一些C示例代码,但我不太确定是否复制了正确的部分:C 将int映射为float?,c,matlab,bit-manipulation,C,Matlab,Bit Manipulation,我想实现从整数到浮点的映射,但我的底层知识有点生疏。本文描述了映射: 3.2到整数的映射 我们可以通过浮点计算预测残差 减法,但这可能会导致不可逆的下溢 无法重建的信息丢失> 实际值。相反,如[7,22]中所述,我们映射了预测的 和实际浮点p和f的符号大小二进制 整数表示。关于实现signmagnity的平台 整数算术,我们现在可以简单地计算 通过减法得到的整数残差,但大多数当前平台 实现二的补码算法。解决 这样,我们将符号大小表示映射为无符号 通过翻转最高有效位(对于正 浮点)或所有位(用
typedef float F32;
typedef int I32;
typedef unsigned int U32;
I32 exponentPred = (((U32&)floatnum) & 0x7F800000) >> 23;
I32 signPred = (((U32&)floatnum) & 0x80000000) == 0x80000000;
I32 mantissaPred = (((U32&)floatnum) & 0x007FFFFF);
因此,我的问题是:
plasmido我不知道matlab,但发生的事情(将其视为C代码)是: 这是一个cast,
floatnum
的内容被解释为U32&
((U32&)floatnum) & 0x7F800000
这是一个位AND,介于上一个表达式的结果和一个协方差之间,一个数字,但表示为十六进制值(这与十进制数相同,但程序员通常更喜欢将自身和常量表示为十六进制值)
将表示上一个表达式结果的位移位23位,其效果是您将删除这23位中的所有内容,并从第24位开始计算位
如果你想更多地了解这些运营商,那就去吧
但我认为,如果你想了解这个具体的例子,重要的是要概述以下事实:
类型通常是更具体类型的占位符,使用通用浮点表示或float
之间的区别在于,在第二种情况下,您有一个定义良好的表示,换句话说,给定32位宽的IEEE 754类型,您知道哪些位表示什么(有关位掩码,请参见wiki)IEEE 754
- 给定的十六进制常量仅代表特殊值,可帮助您提取或屏蔽所需的位(尝试将这些常量转换为二进制并应用
运算符)&
0x8000000
是1000000000000000000000000000000
0x7F800000
是0111111000000000000000000000000
0x007FFFFF
是00000000111111111
现在假设您有一个带有这些数字的浮点变量,每个字符代表一个二进制数字:
floatnum=seeeeeeeeeemmmmmmmmmmmmm
((U32&)floatnum)和0x7F800000
是0eeeeeeeeeee00000000000000000000
最后做一次右移>23
以获得
0000000000000000000000000 EEEEEE
((U32&)floatnum)和0x8000000
是s00000000000000000000000000000000000000000000000000000000
因此,选择标志
最后,最后一行选择尾数:
((U32&)floatnum)和0x007FFFFF
是00000000mmmmm
基本上,代码使用位掩码将浮点拆分为三个部分
//编辑删除的丑陋解决方案,在matlab中找到更好的解决方案:
raw = typecast( single(floatNum), 'uint32' )
exponentPred=bitget(raw,[31:-1:22])
signPred=bitget(raw,[32])]
mantissaPred=bitget(raw,[23:-1:1])
代码将按定义将分隔为其组件。在MATLAB中执行此操作的一种方法是使用
num2hex
将浮点拆分为4位的块,以便轻松转换为二进制字符串:
f = 1.23456;
h = num2hex(f);
b = reshape(dec2bin(hex2dec(h'),4).',1,[])
另一种方法是使用typecast
转换为适用于dec2bin
的整数类型,而不更改基础数据:
b = dec2bin(typecast(f,'uint64'),64);
然后您可以提取符号、指数和尾数。例如,double有1位符号(s
),11位指数(e
),52位有效位(m
):
然后,通过以下方式重新组装编号:
num = (-1)^s * (1+m) * 2^e
对于单个精度浮点(例如f=single(1.23456);
),以与上述相同的方式获取b
(如果使用类型转换
,则指定32位),然后通过以下方式提取零件:
s = b(1)
floatBias = 127;
e = bin2dec(b(2:9)) - floatBias
fbin = str2num(b(32:-1:10).').'
m = sum(fbin.*2.^-(23:-1:1))
为什么不使用getraw
?raw=typecast(single(floatNum),'uint32')
s = b(1)
doubleBias = 1023;
e = bin2dec(b(2:12)) - doubleBias
fbin = str2num(b(64:-1:13).').'
m = sum(fbin.*2.^-(52:-1:1))
num = (-1)^s * (1+m) * 2^e
s = b(1)
floatBias = 127;
e = bin2dec(b(2:9)) - floatBias
fbin = str2num(b(32:-1:10).').'
m = sum(fbin.*2.^-(23:-1:1))