…
Максимально и минимально представимые значения q:
\(n\) | \(r\) | Тип | \(q_{\mathrm{max}}\) | \(q_{\mathrm{min}}\) | \(a_ \mathrm{min}^+\) | \(a_ \mathrm{max/min}\) |
---|---|---|---|---|---|---|
5 | 10 | Нет | 15 | -14 | 5.96e-8 | ±6.55e4 |
8 | 23 | float | 127 | -126 | 1.40e-45 | ±3.4e38 |
11 | 52 | double | 1023 | -1022 | 4.94e-324 | ±1.8e308 |
15 | 631 | long double2 | 16383 | -16382 | 3.65e-4951 | ±1.2e4932 |
15 | 112 | Нет3 | 16383 | -16382 | 6.47e-4966 | ±1.2e4932 |
В общем случае, формат с плавающей запятой хранится следующим образом:
\(s\) | \(q_{n-1}\) | \(\ldots\) | \(q_0\) | \(m_{r-1}\) | \(\ldots\) | \(m_0\) |
\(s\) | \(0\) | \(\ldots\) | \(0\) | \(m_{r-1}\) | \(\ldots\) | \(m_0\) |
-Другие специальные значения включают “бесконечность” и “не число”.
\(s\) | \(1\) | \(\ldots\) | \(1\) | \(0\) | \(\ldots\) | \(0\) |
\(s\) | \(1\) | \(\ldots\) | \(1\) | \(m_{r-1}\) | \(\ldots\) | \(m_0\) |
\(10_2 \times 1010_2\)
s | q₄ | q₃ | q₂ | q₁ | q₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
s | q₄ | q₃ | q₂ | q₁ | q₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
s | i₄ | i₃ | i₂ | i₁ | i₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
s | i₄ | i₃ | i₂ | i₁ | i₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
s | i₄ | i₃ | i₂ | i₁ | i₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | |||||||||||
0 | 0 | 0 | 1 | 1 | |||||||||||
0 | 0 | 1 | 0 | 0 |
s | q₄ | q₃ | q₂ | q₁ | q₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 0 | 1 | 1 |
(m₁₀) | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ | |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
× | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
(m₁₀) | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||
+ | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Результат:
s | i₄ | i₃ | i₂ | i₁ | i₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Приведение порядков работает следующим образом:
Допустим, мы складываем \(10_2\) и \(1010_2\).
В нормализованном виде \(1\cdot2^1 + 1,010\cdot 2^3\)
храним только дробную часть, приведём число с меньшим порядком \(1\cdot2^1\) к большему порядку. Для этого, перенесём запятую влево:
\(0,01\cdot2^3 + 1,010\cdot 2^3\)
\((0,01 + 1,010)\cdot 2^3\)
\((1,100)\cdot 2^3\)
s | q₄ | q₃ | q₂ | q₁ | q₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
s | q₄ | q₃ | q₂ | q₁ | q₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
s | q₄ | q₃ | q₂ | q₁ | q₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |||||
0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
s | q₄ | q₃ | q₂ | q₁ | q₀ | m₉ | m₈ | m₇ | m₆ | m₅ | m₄ | m₃ | m₂ | m₁ | m₀ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Особые операции
Операция | Результат |
---|---|
x / ±∞ | ±0 |
±∞ × ±∞ | ±∞ |
±x / 0 | ±∞ |
∞ + ∞ | ∞ |
±0 / ±0 | NaN |
∞ - ∞ | NaN |
±∞ / ±∞ | NaN |
±∞ × 0 | NaN |
Итого,
\[ N = 2\cdot 2^r \cdot (2^n - 1) -1 \]
(линейный масштаб)
(логарифмический масштаб)
Зависимость плотности от величины числа для формата одинарной точности
это такое максимальное число \(\varepsilon>0\), что, при вычислениях с плавающей запятой, \(1+\varepsilon = 1\)
Приведем типичные значения \(\varepsilon\):
бит | \(r\) | Тип | \(\varepsilon\approx\) |
---|---|---|---|
16 | 10 | Нет | 9.766e-4 |
32 | 23 | float | 1.192e-7 |
64 | 52 | double | 2.220e-16 |
80 | 63 | long double | 1.084e-19 |
128 | 112 | Нет | 1.926e-34 |
Так же можно написать несложную функцию для вычисления машинного эпсилон:
Машинный эпсилон интересен тем, что относительная погрешность округления ограничена им сверху:
\[ \left| \frac{a-a'}{a} \right| < \varepsilon \]
Или, если используется корректное округление
\[ \left| \frac{a-a'}{a} \right| < \frac{1}{2}\varepsilon \]
“половина” округляется к ближайшему чётному.
Например, для 10-битной мантиссы:
\(1,0000000001(00000\ldots)\) округляется до \(1,0000000001\)
\(1,0000000001(10000\ldots)\) округляется до \(1,0000000010\)
\(1,0000000000(10000\ldots)\) округляется до \(1,0000000000\)
\(1,0000000010(10000\ldots)\) округляется до \(1,0000000010\)
\(1,0000000010(11000\ldots)\) округляется до \(1,0000000011\)
\(1,0000000010(10000\ldots 1\ldots)\) округляется до \(1,0000000011\)
\(1,0000000001(10000\ldots 1\ldots)\) округляется до \(1,0000000010\)
так же связано с машинным эпсилон: если сложить очень большое и очень маленькое числа, последнее при приведении порядков обратится в ноль, и результат не изменится.
63+15+1 = 79. Причина в том, что один бит в этом формате отводится под целую часть мантиссы. Причины у этого исторические.↩︎
Реально формат long double зависит от компилятора. MSVC использует его как синоним для double, ICC требует специального ключа.↩︎
На самом деле, тоже зависит от компилятора – например, gcc предоставляет расширение __float128
↩︎