スケーリングを使用して、32 ビット浮動小数点数を 16 ビット整数に変換します。ただし、指定した例では、2 進数ではなく 10 進数のスケーリングを使用しています。浮動小数点ユニットのないシステムで 2 進ドメインで作業を続けたいのか、実際に数値を 10 進表現に変換したいのか、私にはわかりません。
ここで、あなたの課題は、浮動小数点命令にアクセスできないことだと思います。プログラミング言語を指定していないので、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、オーバーフローなどのより複雑なものを処理しませんが、出発点として使用できますか?