計算 FP8 (E5M2)所能表示的所有數

立体风發表於2024-08-15

概述

E5M2 格式的分析

1. 符號位

  • 1 位,用於表示正負號。因此,正數和負數分別可以有各自的表示。

2. 指數位

  • 5 位,可以表示 (2^5 = 32) 個不同的指數值。

3. 尾數位

  • 2 位,可以表示 (2^2 = 4) 個不同的尾數值。

組合情況的基本計算

根據組合的乘法原理:

  • 不考慮符號的情況下,指數和尾數的組合情況總共是 (32 \times 4 = 128) 種。
  • 加上符號位,這些組合可以分別表示正數和負數,因此總共有 (128 \times 2 = 256) 種不同的二進位制組合。

特殊情況和規範化

但是,FP8(E5M2)格式中有一些特殊情況,這些情況會影響到實際能表示的數值:

  1. 規範化數 (Normalized Numbers)

    • 對於大部分指數值,數值是規範化的,即尾數的隱含位為 1。這會佔用大部分的表示範圍。
  2. 非規範化數 (Denormalized Numbers)

    • 當指數為最小值(通常是全 0)時,數值是非規範化的,這種情況下尾數部分不再有隱含的 1 位,這些表示的範圍有限且密集。
  3. 特殊值

    • 最大的指數值通常保留用於表示特殊值,如無窮大 (+∞, -∞) 和非數字 (NaN),這些組合不用於表示實際數值。

實際可表示的數值數量

由於這些特殊情況:

  • 指數為全 1 的情況通常表示 NaNInfinity,這會減少可表示數值的數量。
  • 指數為全 0 的情況可能表示非規範化數,而非規範化數的數量較少,精度也較低。

結論

雖然你計算的組合數量是正確的——在理論上 E5M2 格式可以表示 256 種不同的二進位制組合,但在實際應用中,這些組合並不全部用於表示不同的數值。部分組合被用於表示特殊的數值(如 NaNInfinity),並且規範化和非規範化數的存在也會使得實際可表示的數值數量有所變化。

因此,FP8(E5M2)可以表示的數值總數並不完全等於 256,而是略少於這個值。實際的可表示數值數量取決於如何處理這些特殊值和表示方式。

計算

列出 FP8(E5M2)所有可表示的浮點數涉及到指數、尾數的組合,並考慮到符號位、規範化數、非規範化數以及特殊值(如 NaN 和 Infinity)。我們可以逐步構建所有可能的浮點數值。

FP8(E5M2)的結構

  • 符號位 (1 bit):1 表示負數,0 表示正數。
  • 指數 (5 bits):5 位表示指數,值範圍為 0 到 31。
  • 尾數 (2 bits):2 位表示尾數,值範圍為 0 到 3。

規則

公式1
[
(-1)^{\text{sign}} \times 2^{\text{exp} - \text{bias}} \times (1 + \text{fraction} \times 2^{-2})
]
公式2
[
(-1)^{\text{sign}} \times 2^{1 - \text{bias}} \times (\text{fraction} \times 2^{-2})
]

列出所有可表示的浮點數

為了完整列出所有數值,我會編寫一個簡單的 Python 程式碼來生成這些數值。程式碼如下:

import numpy as np

def fp8_e5m2():
    bias = 15
    values = []
    
    # Iterate over all combinations of sign, exponent, and fraction
    for sign in [0, 1]:
        for exp in range(32):  # 5-bit exponent
            for frac in range(4):  # 2-bit fraction
                if exp == 0b11111:  # Special case for exponent all ones (NaN or Infinity)
                    if frac == 0:
                        value = float('inf') if sign == 0 else float('-inf')
                    else:
                        value = float('nan')
                elif exp == 0:  # Denormalized numbers (exponent all zeros)
                    value = (-1)**sign * 2**(1 - bias) * (frac * 2**-2)
                else:  # Normalized numbers
                    value = (-1)**sign * 2**(exp - bias) * (1 + frac * 2**-2)
                
                values.append(value)
    
    return np.array(values)

# Get all possible FP8 (E5M2) values
fp8_values = fp8_e5m2()

# Sort and print the unique values
for v in np.sort(np.unique(fp8_values)):
    print(v)

結果

這個程式碼會生成並列出 FP8(E5M2)格式所有可表示的浮點數。由於 FP8 的表示是有限的,這個列表應該可以顯示所有正數、負數以及特殊值。

不過,由於平臺、環境等原因,執行程式碼後,輸出的 NaN 和 Infinity 的顯示可能略有不同。

執行這個程式碼並檢視結果。它將會給出一個排序的、去重的所有 FP8(E5M2)格式可表示的數值列表,包括所有的正數、負數、非規範化數以及特殊值(NaN 和 Infinity)。

相關文章