有一个问题!
我有一个 IEEE 754 单精度(32位)浮点存储在两个连续的16位整数中。
我使用的处理器没有浮点数学或浮点数据类型!我想要做的是将浮点值转换为16位有符号整数。处理器具有标准整数数学和位操作(屏蔽,移位等)。
我除了从32位浮点数到16位整数之外我需要失去一些精度。整数还需要一些基于相关值范围的隐含比例因子。
这是一个让事情更清晰的简单例子。假设浮点数的范围为0.00
到10.00
。在这种情况下,我希望整数的范围为0 to 1000
。请注意隐含的缩放因子为100.在这种情况下,整数的隐含缩放比为100.
我知道 IEEE 754 包含1个符号位,8位用于指数(127位偏置)和23位用于尾数。
我知道从浮子的组成部分重建值的等式是:
浮点值=( - 1)^ Sign_bit *(1 +尾数)* 2 ^(指数-127)。
我能看到的主要问题是使用16位有符号整数(范围为-32768到+32767)并避免任何上溢或下溢。
答案 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或溢出,但也许你可以用它作为起点?