2012-02-22 160 views
0

有一个问题!将浮点数转换为整数

我有一个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

我不明白你想要什么回答。 – 2012-02-22 10:04:44

回答

0

你想通过缩放将32位浮点数转换为16位整数。但是,您提供的示例使用了十进制缩放而不是二进制。我不确定是否要在没有浮点单位的系统上继续工作在二进制域中,或者如果您确实想要转换为数字的十进制表示形式。

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

由于我将继续使用二进制表示法,因此scale不能是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的小数来表示数字,则应为scaling提供值3。所有数字将乘以2^3 = 8,例如0.125 = 1/8被转换为1,0.25 = 2/8至2等

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