以下の内容はhttps://rsk0315.hatenablog.com/entry/2025/03/01/192603より取得しました。


浮動小数点型の仮数部の桁数を知りたいとき

C++#include <limits> をして std::numeric_limits<__float128>::digits をすると 0 と返ってきました。

よって、__float128float にすら劣る桁数しかないことがわかりました。いかがでしたか?

コード

#include <math.h>
#include <stdio.h>

#define MAGIC 0x7EEE
#define PRECISION(F) lround(-log2((F)((F)1 - (F)((F)((F)1 / (F)MAGIC) * (F)MAGIC))))

int main(void) {
    printf("%ld\n", PRECISION(_Float16));    // 11
    printf("%ld\n", PRECISION(float));       // 24
    printf("%ld\n", PRECISION(double));      // 53
    printf("%ld\n", PRECISION(long double)); // 64
    printf("%ld\n", PRECISION(__float128));  // 113
}

雑談

浮動小数点型 _Float16, float, double, long double, __float128 に対して、それぞれの仮数部の桁数を $p$ bits として $$(1\oslash \roundp{\texttt{7EEE}_{(16)}})\otimes\roundp{\texttt{7EEE}_{(16)}} = 1 - 2^{-p}$$ が成り立つことを利用しています。 丸めモードは tiesToEven を前提としているのと、これ以外の仮数部の型については知りません。便宜上 long double仮数部が 64 bits であるかのように書いていますが、処理系によって 53 bits だったり 113 bits だったりすることもあります。

なお、_Float16 においては $1\oslash 16384$ 未満で (graceful) underflow してしまうことに注意しましょう。 今まではそういう状況を考慮する必要がなかったので、$\oslash$ などの演算子に対して「仮数部が $p$ bits で丸めモードが tiesToEven で、〜」とだけ思っていましたが、厳密には指数部の桁数も考慮する必要がありますね*1

promotion によって double 未満の型が double に変換されるため、いちいち (F) でキャストし直しています。 挙動を見た感じだと _Float16 は promote しないように見えました。float だけ?

_Float16 については 6.13 Half-Precision Floating Point を読むとよいかもしれません。__fp16 は使えたり使えなかったりしそうです。

おわり

おわりです。 この記事が役に立たないことを祈ります。

*1:カスの記事だとしても、書いているうちに気づきを得られる例。




以上の内容はhttps://rsk0315.hatenablog.com/entry/2025/03/01/192603より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14