【问题标题】:C/C++ - How to convert from a signed 32bit integer to a float and backC/C++ - 如何将带符号的 32 位整数转换为浮点数并返回
【发布时间】:2012-10-19 01:02:03
【问题描述】:

我需要能够将 C SInt32 整数转换为 [-1, 1] 范围内的浮点数并返回。我看过关于 24 位整数的这个问题的讨论:

C/C++ - Convert 24-bit signed integer to float

我也尝试过类似的方法:

 // Convert int - float
 SInt32 integer = 1;
 Float32 factor = 1;
 Float32 f = integer / (0x7FFFFFF + 0.5);

 // Perform some processing on the float
 Process(f);

 // Scale the float
 f = f * factor;

 // Convert float - int
 integer = f * (0x7FFFFFF + 0.5);

但是这不起作用。我知道它不起作用,因为我正在做的工作涉及音频编程并且转换会导致嘶嘶声。

我很确定这是一个转换问题,因为当我通过将因子设置为 0.0001 来减小浮点数时,噼啪声消失了。也许反向转换使 int 超出了它的限制并导致它被截断。

任何建议将不胜感激。

【问题讨论】:

    标签: c++ c floating-point int


    【解决方案1】:
    const float recip = 1.0 / (32768.0*65536.0);
    // hope that compiler will calculate this in advance
    // From the expression an semi-advanced programmer can also immediately spot
    // where the value comes from
    float value = int_value * recip;
    int value2 = value * (32768.0*65536.0);
    

    这个过程是不可逆的:一个人可能会损失多达 7 位的准确性。

    【讨论】:

    • 乘以这些值并不是 OP 想要的:两者都包括 +-1,其中整数范围为 [-2^n .. 2^n-1],但乘以或除以(2^n -1) 会产生更多的噪音。
    • 该问题表明浮点数可能具有值 1。(“[-1, 1]”表示闭合区间;它包括其端点。)value2 的计算将转换为 1在value 到 2,147,483,648,溢出有符号的 32 位整数。
    • @EricPostpischil - 是的,我注意到了。幸运的是,浮点 1.0 * 2^31 作为整数不会溢出,但根据 IEEE-754 标准,它会饱和到 MAX_INT。我认为剪裁稀有样本比向所有其他样本引入量化噪声是更好的设计选择。
    • IEEE 754-2008 在第 7.2 节中说,当源超出目标范围时转换为整数会导致无效操作异常。 2011 C 标准在第 F.4 节中说,引发了无效操作异常并且结果未指定。如果 C 实现不支持附件 F(许多不支持),则第 6.3.1.4 条表示行为未定义。
    • -1,这不仅会丢失 7 位.. 它可能会丢失所有位。假设int为32bit,float = 1.0 * (32768.0*65536.0),会溢出,值会变成负数:INT32_MIN。
    【解决方案2】:

    阅读IEEE floating point formatsIEEE 32-bit float 只支持 24 位有效位,所以如果你转换一个 32 位整数,你会丢失低 8 位。

    【讨论】:

    • 谢谢,所以我需要使用 24 位整数。
    • @BenSmiley 或转换为 double,这会给你 53 位的精度(通常)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    相关资源
    最近更新 更多