将int映射到float?

时间:2013-12-02 22:43:38

标签: c matlab bit-manipulation

我想实现从整数到浮点的映射,但是我的低级知识有点生疏。该映射在本文中描述:

  1. http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.124.8968&rep=rep1&type=pdf
  2. http://www.cs.unc.edu/~isenburg/lcpfpv/
  3.   

    3.2映射到整数

         

    我们可以通过浮点计算预测残差   减法,但这可能导致下溢不可逆转   丢失不能重建的信息。   实际价值。相反,如[7,22],我们映射预测   并且实际浮动p和f到它们的符号幅度二进制   整数表示。在实现signmagnitude的平台上   整数运算,我们现在可以简单地计算   通过减法求整数残差,但是大多数当前平台   实现二进制补码算法。讲话   这个,我们将符号幅度表示映射到无符号   通过翻转最重要的位来表示整数(对于正数   浮点数)或所有位(负浮点数)。结果是   浮点数单调映射到保留的无符号整数   浮动的差异的排序甚至线性   具有相同的符号和指数。这种方法也是   类似于[16],但我们通过允许携带来获益   在p和f为的情况下,从尾数传播到指数   关闭但由指数边界隔开,这将是   在[16]中被称为大错误预测。

    还有一些C示例代码,但我不太确定,如果我复制了正确的部分:

    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);
    

    所以我的问题是:

    1. 你能解释一下,他在最后3行中做了什么。我想在二进制级别上理解它。
    2. 这是将浮动映射到整数的代码吗?
    3. 我如何在matlab中进行映射?
    4. 谢谢, plasmido

3 个答案:

答案 0 :(得分:3)

0x800000001000000 00000000 00000000 00000000

0x7F8000000111111 10000000 00000000 00000000

0x007FFFFF0000000 01111111 11111111 11111111

现在假设您有一个带有这些数字的浮点变量,每个char代表一个二进制数字:

floatnum = SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM

((U32&)floatnum) & 0x7F8000000EEEEEEE E0000000 0000000 00000000

最后右移>>23来获取

0000000 0000000 0000000 EEEEEEEE

((U32&)floatnum) & 0x80000000S0000000 00000000 0000000 00000000

选择标志。

最后,最后一行选择尾数:

((U32&)floatnum) & 0x007FFFFF00000000 0MMMMMMM MMMMMMMM MMMMMMMM

基本上,代码使用位掩码将float分成三部分。

//编辑丑陋的解决方案,在matlab中找到了更好的解决方案:

raw = typecast( single(floatNum), 'uint32' )
exponentPred=bitget(raw,[31:-1:22])
signPred=bitget(raw,[32])]
mantissaPred=bitget(raw,[23:-1:1])

答案 1 :(得分:1)

我不知道matlab但是发生的事情(将其视为C代码)是:

(U32&)floatnum

它是演员,floatnum的内容被解释为类型U32&

((U32&)floatnum) & 0x7F800000

这是前一个表达式的结果与costant,一个数字之间的按位AND,但表示为十六进制值(它与十进制数字相同,但通常程序员喜欢将自己和常量表示为HEX价值观)

(((U32&)floatnum) & 0x7F800000) >> 23

将表示前一个表达式结果的位移位23个位置,结果是你将丢弃这23个位中的所有内容,然后从第24个位开始计数位。

如果您想了解有关这些运营商的更多信息,请转到for the wiki

但我认为,如果你想了解这个具体的例子,重要的是要概述:

  • 一个float类型它通常是一个占位符,用于更具体的IEEE 754类型,使用通用浮点表示或IEEE 754之间的区别在于,在第二种情况下,您有一个定义良好的表示,换句话说,给定一个32位宽的IEEE 754类型,你知道什么位代表什么(参见维基的位掩码)
  • 给定的HEX常量只是表示特殊值,可以帮助您提取或屏蔽掉您想要的位(尝试将这些常量转换为二进制并应用&运算符)

答案 2 :(得分:0)

代码将single precision floating point number分隔为IEEE 754 standard定义的组件。在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) :

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

对于精度float(例如f=single(1.23456);),请按上述方式获取b(如果使用typecast则指定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))