C 将int映射为float?

C 将int映射为float?,c,matlab,bit-manipulation,C,Matlab,Bit Manipulation,我想实现从整数到浮点的映射,但我的底层知识有点生疏。本文描述了映射: 3.2到整数的映射 我们可以通过浮点计算预测残差 减法,但这可能会导致不可逆的下溢 无法重建的信息丢失> 实际值。相反,如[7,22]中所述,我们映射了预测的 和实际浮点p和f的符号大小二进制 整数表示。关于实现signmagnity的平台 整数算术,我们现在可以简单地计算 通过减法得到的整数残差,但大多数当前平台 实现二的补码算法。解决 这样,我们将符号大小表示映射为无符号 通过翻转最高有效位(对于正 浮点)或所有位(用

我想实现从整数到浮点的映射,但我的底层知识有点生疏。本文描述了映射:

  • 3.2到整数的映射

    我们可以通过浮点计算预测残差 减法,但这可能会导致不可逆的下溢 无法重建的信息丢失> 实际值。相反,如[7,22]中所述,我们映射了预测的 和实际浮点p和f的符号大小二进制 整数表示。关于实现signmagnity的平台 整数算术,我们现在可以简单地计算 通过减法得到的整数残差,但大多数当前平台 实现二的补码算法。解决 这样,我们将符号大小表示映射为无符号 通过翻转最高有效位(对于正 浮点)或所有位(用于负浮点)。结果是一场灾难 浮点数到无符号整数的单调映射 浮点数差的排序和均匀线性 具有相同的符号和指数。这种方法也是可行的 与[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);
    
    因此,我的问题是:

  • 你能给我解释一下,最后三行他在干什么吗。我想从二进制的角度来理解它
  • 这是将浮点映射为整数的代码吗
  • 如何在matlab中进行映射
  • 谢谢,
    plasmido

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

    这是一个cast,
    floatnum
    的内容被解释为
    U32&

    ((U32&)floatnum) & 0x7F800000
    
    这是一个位AND,介于上一个表达式的结果和一个协方差之间,一个数字,但表示为十六进制值(这与十进制数相同,但程序员通常更喜欢将自身和常量表示为十六进制值)

    将表示上一个表达式结果的位移位23位,其效果是您将删除这23位中的所有内容,并从第24位开始计算位

    如果你想更多地了解这些运营商,那就去吧

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

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

      • 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))
        
        为什么不使用get
        raw
        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))