您想通过缩放将 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 或溢出,但也许您可以将其用作起点?