将float转换为整数

时间:2012-02-22 09:51:49

标签: casting floating-point integer-overflow type-conversion

有一个问题!

我有一个 IEEE 754 单精度(32位)浮点存储在两个连续的16位整数中。

我使用的处理器没有浮点数学或浮点数据类型!我想要做的是将浮点值转换为16位有符号整数。处理器具有标准整数数学和位操作(屏蔽,移位等)。

我除了从32位浮点数到16位整数之外我需要失去一些精度。整数还需要一些基于相关值范围的隐含比例因子。

这是一个让事情更清晰的简单例子。假设浮点数的范围为0.0010.00。在这种情况下,我希望整数的范围为0 to 1000。请注意隐含的缩放因子为100.在这种情况下,整数的隐含缩放比为100.

我知道 IEEE 754 包含1个符号位,8位用于指数(127位偏置)和23位用于尾数。

我知道从浮子的组成部分重建值的等式是:

  

浮点值=( - 1)^ Sign_bit *(1 +尾数)* 2 ^(指数-127)。

我能看到的主要问题是使用16位有符号整数(范围为-32768到+32767)并避免任何上溢或下溢。

1 个答案:

答案 0 :(得分:0)

您希望通过缩放将32位浮点数转换为16位整数。但是,您给出的示例使用十进制缩放而不是二进制。我不确定你是否想在没有浮点单元的系统上继续在二进制域中工作,或者你真的想要转换为数字的十进制表示。

这里我假设您的挑战是您无法访问浮点指令。你没有指定编程语言所以我决定用C#编写一些东西。这种语言很容易使用,但也许不是最适合小小的摆弄。您可能会发现在C或C ++中实现它更容易,更有效。

由于我将继续使用二进制表示,因此比例不能是10或100(10的整数幂)的数字,而是必须是2的整数幂。下面是一个IEEE的类754 binary32浮点数分开。

class Ieee754Binary32 {

  public Ieee754Binary32(Single value) {
    using (var memoryStream = new MemoryStream()) {
      var binaryWriter = new BinaryWriter(memoryStream);
      binaryWriter.Write(value);
      memoryStream.Seek(0, SeekOrigin.Begin);
      var binaryReader = new BinaryReader(memoryStream);
      var bits = binaryReader.ReadInt32();
      Fraction = bits & 0x7FFFFF;
      Exponent = ((bits >> 23) & 0xFF) - 127;
      Sign = (bits & 80000000) == 1 ? -1 : 1;
    }
  }

  public Int32 Fraction { get; private set; }

  public Int32 Exponent { get; private set; }

  public Int32 Sign { get; private set; }

  public Int16 ToScaledInt16(Int32 scaling) {
    if (Exponent == -127 && Fraction == 0)
      return 0;
    var mantissa = 0x8000 | (Fraction >> 8);
    var unscaledInt32 = Exponent >= 0 ? mantissa << Exponent : mantissa >> -Exponent;
    var scaledInt16 = unscaledInt32 >> (15 - scaling);
    return (Int16) (Sign*scaledInt16);
  }

}

方法ToScaledInt16是您想要使用的方法。如果您想使用8的分数表示数字,则应为3提供值scaling。所有号码将乘以2^3 = 8,例如0.125 = 1/8转换为1,0.25 = 2/8到2等。

代码不处理更复杂的东西,如舍入,NaN或溢出,但也许你可以用它作为起点?