![](/img/trans.png)
[英]How to read a single-precision floating-point number from four bytes serialized by .NET's BinaryWriter
[英]How do I save a floating-point number in 2 bytes?
您可以在BCD中存儲三位數字,並將剩余的四位用於小數點位置:
52.1 = 521 * 10 ^ -1 => 0x1521
1.25 = 125 * 10 ^ -2 => 0x2125
這將為您提供從0.0000000000000001到999的范圍。您當然可以為小數點添加偏移量,以獲得例如0.0000000001到999000000的范圍。
用於小數點放置的四位的簡單實現,其余用於值。 沒有任何錯誤檢查,並沒有徹底檢查。 (使用!=
比較雙精度時,可能會出現某些值的精度問題。)
public static short Encode(double value) {
int cnt = 0;
while (value != Math.Floor(value)) {
value *= 10.0;
cnt++;
}
return (short)((cnt << 12) + (int)value);
}
public static double Decode(short value) {
int cnt = value >> 12;
double result = value & 0xfff;
while (cnt > 0) {
result /= 10.0;
cnt--;
}
return result;
}
例:
Console.WriteLine(Encode(52.1));
Console.WriteLine(Decode(4617));
輸出:
4617
52.1
C#沒有內置功能,但您可以嘗試使用定點方法。
8,8固定點的例子(逗號前8,后8):
float value = 123.45;
ushort fixedIntValue = (ushort)(value * 256);
這樣,數字存儲如下:XXXXXXXX,XXXXXXXX
並且您可以使用以下方法再次檢索浮動:
float value = fixedIntValue / 256f;
您確定需要這樣的微優化,而不僅僅是使用float
或double
?
通過存儲short
並理解,例如,它除以100來得到實際數字,你會得到更好的服務嗎? (例如52.1和1.25的示例可以存儲為5210和125)我認為這可能是最適合您的解決方案。
如果您使用的是實際浮點數,則可以將解碼后的數字取整並將其四舍五入為有效數字(從您的示例中為3),這通常會使您返回與您開始時相同的數字(請注意是的,這是故意模糊的 - 你不能保證獲得原件,除非你存儲原件)。
問題是您無法在任何二進制浮點類型中精確表示32.1
。
在單精度中,最接近的可表示值是32.099998。 半精度,顯然是32.0985。
您可以考慮使用十進制浮點類型,但此解決方案並非半精度唯一。
有4,278,190,080個32位浮點值,不包括NaN和無窮大。 兩個字節中的16位有65,536個值。 顯然,不可能以兩個字節唯一地編碼所有浮點值。
你想編碼哪些?
即使對於符號和指數的單個值(例如,所有浮點值從4到8,不包括8),也有8,388,608個浮點值,因此您甚至無法對這兩個字節進行編碼。
您必須將自己限制為要編碼的一小部分值。 完成后,人們可能會對如何編碼它們提出建議。 您要解決的實際問題是什么?
從您的示例中,您要存儲3位數和小數點。 您可以簡單地將11個符號的“字母”編碼為4位代碼,並以2個字節存儲4 x 4位。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.