簡體   English   中英

如何以2個字節保存浮點數?

[英]How do I save a floating-point number in 2 bytes?

是的我知道IEEE-754半精度標准,是的,我知道在該領域所做的工作。 簡單地說,我試圖在2個字節內保存一個簡單的浮點數(如52.11.25 )。

我已嘗試過JavaC#中的一些實現,但是它們通過解碼不同的數字來破壞輸入值。 你輸入32.1 ,編碼解碼后得到32.0985

有沒有什么方法可以在不破壞輸入值的情況下以16位存儲浮點數?

非常感謝。

您可以在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;

您確定需要這樣的微優化,而不僅僅是使用floatdouble

通過存儲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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM