IEEE 754 浮動小数点数 詳細表示 (binary 16/32/64/128)

[こちらは倍精度のみ](https://qiita.com/ikiuo/items/d986ef5797baf9e78687)だったので様々な精度に対応したものを作ってみた。

- binary16
  - シェーディング言語など
- binary32
  - C/C++ の float 型
- binary64
  - C/C++ の double 型
  - Python の float 型
  - JavaScript の Number 型
- binary128
  - 普及するのは何時だろう？

拡張倍精度(80ビット)は非対応です。

<p class="codepen" data-height="680" data-default-tab="result" data-slug-hash="bNGpaVa" data-pen-title="IEEE 754 浮動小数点数 詳細表示" data-user="ikiuo" style="height: 680px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ikiuo/pen/bNGpaVa">
  IEEE 754 浮動小数点数 詳細表示</a> by Ikiuo (<a href="https://codepen.io/ikiuo">@ikiuo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

# HTML単体版

<details><summary>HTML ファイル(長いので折りたたみ)</summary><div>

```HTML:sample.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>IEEE 754 浮動小数点数 詳細表示</title>
    <style>
     table {
         border: none;
         border-collapse: collapse;
         overflow-x: auto;
     }
     th, td {
         border: 1px solid #dfdfdf;
         padding: 2px 4px;
     }

     .left { text-align: left; }
     .center { text-align: center; }
     .right { text-align: right; }
     .vtop { vertical-align: top; }

     .large { font-size: large; }
     .small { font-size: small; }
     .xsmall { font-size: x-small; }
     .xxsmall { font-size: xx-small; }

     .ctext:hover {
         cursor: pointer;
         background-color: #e2e2e2;
     }
     .ftext { color: #006; }
     .htext { color: #600; }
     .ntext {
         word-break: break-all;
     }

     .eline { background: #edefef; }
     .oline { background: #f5f6f6; }

     .inpdata { background: #f5ffff; }
    </style>
  </head>
  <body>

    <script>

     const LOG10_2 = 0.3010299956639812;

     const gAbs = ((a, b) => a >= b ? a - b : b - a);

     function power5n(n) {
         var a = 1n;
         var b = 5n;
         while (n) {
             if (n & 1)
                 a *= b;
             b *= b;
             n >>= 1;
         }
         return a;
     }
     const power10n = (n => power5n(n) << BigInt(n));

     const BitLength = (x => x ? x.toString(2).length : 0);

     const toString16N = ((v, n) => {
         const l = Number(n);
         return ('0'.repeat(l) + v.toString(16)).slice(-l);
     });
     const toString16B = ((v, b) => toString16N(v, (b + 3n) >> 2n));

     /*
      * 分数表現型
      */
     class FractionBI {
         #S;

         nan;         // 非数のとき true
         finite;      // 有限値のとき true
         sign;        // 負のとき true
         numerator;   // 分子 (BigInt)
         denominator; // 分母 (BigInt)

         constructor(value) {
             const S = FractionBI;
             this.#S = S;

             switch (typeof value) {
                 case 'bigint':
                     this.#fromBigInt(value);
                     break;
                 case 'number':
                     this.#fromNumber(value);
                     break;
                 case 'string':
                     this.#fromString(value);
                     break;
                 default:
                     if (FractionBI.prototype.isPrototypeOf(value)) {
                         this.#fromRational(value);
                         break;
                     }
                     throw new Error("invalid type", {cause: value});
             }
         }

         // 非数を設定
         #setNaN(sign) {
             this.nan = true;
             this.finite = false;
             if (sign != null)
                 this.sign = sign;
             this.numerator = null;
             this.denominator = null;
         }

         // 無限大を設定
         #setInfinity(sign) {
             this.nan = false;
             this.finite = false;
             if (sign != null)
                 this.sign = sign;
             this.numerator = null;
             this.denominator = null;
         }

         // 有限値を設定
         #setFinite(sign, numerator, denominator) {
             if (!denominator)
                 throw new Error("invalid denominator", {cause: denominator});

             this.nan = false;
             this.finite = true;
             if (sign != null)
                 this.sign = sign;

             let fnum = numerator;
             let fden = denominator;
             if (fnum) {
                 while ((fnum % 5n) == 0n &&
                        (fden % 5n) == 0n) {
                     fnum /= 5n;
                     fden /= 5n;
                 }

                 const t = (fnum | fden);
                 const s = BigInt(BitLength(t & -t) - 1);
                 fnum >>= s;
                 fden >>= s;
             }
             this.numerator = fnum;
             this.denominator = fden;
         }

         // 0 を設定
         #setZero(sign) {
             this.nan = false;
             this.finite = true;
             if (sign != null)
                 this.sign = sign;
             this.numerator = 0n;
             this.denominator = 1n;
         }

         // FractionBI のコピー
         #fromRational(value) {
             this.nan = value.nan;
             this.finite = value.finite;
             this.sign = value.sign;
             this.numerator = value.numerator;
             this.denominator = value.denominator;
         }

         // BigInt 型を変換
         #fromBigInt(value) {
             this.nan = false;
             this.finite = true;
             this.sign = (value < 0n);
             this.numerator = (value < 0n) ? -value : value;
             this.denominator  = 1n;
         }

         // Number 型を変換
         #fromNumber(value) {
             const mb64 = (1n << 64n) - 1n;
             const mexp = ((1n << 11n) - 1n);
             const mman = ((1n << 52n) - 1n);

             const view = new DataView(new ArrayBuffer(8));
             view.setFloat64(0, value, true);

             const bin = mb64 & view.getBigInt64(0, true);
             const sign = (1n & (bin >> 63n));
             const exp = mexp & (bin >> 52n);
             const man = mman & bin;

             const fsign = sign != 0n;
             if (exp == 0n && man == 0n) {
                 this.#setFinite(fsign, 0n, 1n);
                 return;
             }
             if (exp == mexp) {
                 if (mman != 0)
                     this.#setNaN(fsign);
                 else
                     this.#setInfinity(fsign);
                 return;
             }

             const nnum = man | (exp ? (1n << 52n) : 0n);
             const nden = 1n << (exp ? 52n : 51n);
             const fnum = nnum << (exp > 1023n ? exp - 1023n : 0n);
             const fden = nden << (exp < 1023n ? 1023n - exp : 0n);
             this.#setFinite(fsign, fnum, fden);
         }

         // 文字列から変換
         #fromString(text) {
             const S = this.#S;

             text = text.trim().toLowerCase();

             let fsign = false;
             let fnum = 0n;
             let fden = 1n;

             let tpos = 0;
             if (tpos >= text.length) {
                 this.#setNaN(fsign);
                 return;
             }

             switch (text[tpos]) {
                 case '-':
                     fsign = true;
                     // FALLTHROUGH
                 case '+':
                     if (++tpos < text.length)
                         break;
                     this.#setNaN(fsign);
                     return;
             }

             switch (text.slice(tpos)) {
                 case 'nan':
                     this.#setNaN(fsign);
                     return;

                 case 'inf':
                 case 'infinity':
                     this.#setInfinity(fsign);
                     return;
             }

             const dtab = S.#base10Table;
             let btab = dtab;
             let base = 10n;

             if (tpos >= text.length) {
                 this.#setNaN(fsign);
                 return;
             }
             if (text[tpos] == '0') {
                 if (++tpos >= text.length) {
                     this.#setFinite(fsign, fnum, fden);
                     return;
                 }
                 switch (text[tpos]) {
                     case 'b':
                         btab = S.#base2Table;
                         base = 2n;
                         break;
                     case 'o':
                         btab = S.#base8Table;
                         base = 8n;
                         break;
                     case 'x':
                         btab = S.#base16Table;
                         base = 16n;
                         break;
                 }
                 if (base != 10n) {
                     if (++tpos >= text.length) {
                         this.#setNaN(fsign);
                         return;
                     }
                 }
             }

             let dot = false;
             for (;; tpos++) {
                 if (tpos >= text.length) {
                     this.#setFinite(fsign, fnum, fden);
                     return;
                 }

                 const c = text[tpos];
                 const n = btab[c];

                 if (n != null) {
                     fnum = fnum * base + n;
                     if (dot)
                         fden *= base;
                     continue;
                 }
                 if (c == '_' || c == ',')
                     continue;
                 if (c != '.')
                     break;
                 if (dot) {
                     this.#setNaN(fsign);
                     return;
                 }
                 dot = true;
             }

             let expm = base;
             switch (text[tpos]) {
                 case 'p':
                     if (expm == 10n) {
                         this.#setNaN(fsign);
                         return
                     }
                     expm = 2n;
                     // FALLTHROUGH
                 case 'e':
                     if (++tpos < text.length)
                         break;
                     // FALLTHROUGH
                 default:
                     this.#setNaN(fsign);
                     return;
             }

             let esign = false;
             switch (text[tpos]) {
                 case '-':
                     esign = true;
                     // FALLTHROUGH
                 case '+':
                     if (++tpos < text.length)
                         break;
                     this.#setNaN(fsign);
                     return;
             }

             let xnum = 0n;
             for (; tpos < text.length; tpos++) {
                 const c = text[tpos];
                 const n = dtab[c];
                 if (n == null) {
                     this.#setNaN(fsign);
                     return;
                 }
                 xnum = xnum * 10n + n;
             }
             if (xnum >= 65536n) {
                 if (esign)
                     this.#setZero(fsign);
                 else
                     this.#setInfinity(fsign);
                 return;
             }

             let expv = 1n;
             while (xnum) {
                 if ((xnum & 1n))
                     expv *= expm;
                 expm *= expm;
                 xnum >>= 1n;
             }
             if (esign)
                 fden *= expv;
             else
                 fnum *= expv;

             this.#setFinite(fsign, fnum, fden);
         }

         static #base2Table = {
             '0': 0n, '1': 1n,
         }
         static #base8Table = {
             '0': 0n, '1': 1n, '2': 2n, '3': 3n,
             '4': 4n, '5': 5n, '6': 6n, '7': 7n,
         }
         static #base10Table = {
             '0': 0n, '1': 1n, '2': 2n, '3': 3n, '4': 4n,
             '5': 5n, '6': 6n, '7': 7n, '8': 8n, '9': 9n,
         }
         static #base16Table = {
             '0': 0n, '1': 1n, '2': 2n, '3': 3n,
             '4': 4n, '5': 5n, '6': 6n, '7': 7n,
             '8': 8n, '9': 9n, 'a': 10n, 'b': 11n,
             'c': 12n, 'd': 13n, 'e': 14n, 'f': 15n,
         }
     }

     /*
      * IEEE 754 要素
      */
     class IEEE754Parameter {

         //
         // 2進形式
         //

         static #makeBinary(exponentBits, mantissaBits) {
             const mantissaMask = (1n << mantissaBits) - 1n;
             const exponentMask = (1n << exponentBits) - 1n;
             const signPosition = exponentBits + mantissaBits;
             return {
                 mantissaBits,
                 mantissaMask,
                 mantissaPosition: 0n,
                 mantissaInt: 1n << mantissaBits,

                 exponentBits,
                 exponentMask,
                 exponentPosition: mantissaBits,
                 exponentBias: exponentMask >> 1n,

                 signBit: 1n << signPosition,
                 signPosition,

                 totalBits: signPosition + 1n,

                 getMantissa: (data => data & mantissaMask),
                 getExponent: (data => (data >> mantissaBits) & exponentMask),
                 getSign: (data => (data >> signPosition) & 1n),
             }
         }
         static #binaryCache = {
             16n: IEEE754Parameter.#makeBinary(5n, 10n),
             32n: IEEE754Parameter.#makeBinary(8n, 23n),
             64n: IEEE754Parameter.#makeBinary(11n, 52n),
             128n: IEEE754Parameter.#makeBinary(15n, 112n),
         }
         static getBinary(n) {
             const S = IEEE754Parameter;
             const bn = BigInt(n);
             const cache = S.#binaryCache
             const cached = cache[bn];
             if (cached != null)
                 return cached;
             if (bn % 32n)
                 return null;
             const nn = Number(n);
             const p = BigInt(nn - Math.round(Math.log2(nn) * 4) + 13);
             const param = S.#makeBinary(bn - p - 1n, p);
             cache[n] = param;
             return param;
         }

     }

     /*
      * IEEE 754 - 2進形式
      */
     class IEEE754Binary extends FractionBI {
         #S;
         #P;
         #round0;
         exponent;
         mantissa;

         get data() {
             const P = this.#P;
             return (this.sign ? P.signBit : 0n) |
                    (this.exponent << P.exponentPosition) |
                    this.mantissa;
         }

         get exponent2() {
             const dexp = this.exponent;
             return (dexp ? dexp : 1n) - this.#P.exponentBias;
         }

         get mantissaBits() { return this.#P.mantissaBits; }
         get exponentBits() { return this.#P.exponentBits; }
         get dataBits() { return this.#P.totalBits; }

         constructor(data_bits, value, round0) {
             super(value);
             this.#S = IEEE754Binary;
             this.#P = IEEE754Parameter.getBinary(data_bits);
             this.#round0 = Boolean(round0);
             this.#initialize();
         }

         #initialize() {
             const P = this.#P;

             if (!this.finite) {
                 this.exponent = P.exponentMask;
                 this.mantissa = this.nan ? P.mantissaInt >> 1n : 0n;
                 return;
             }

             let fnum = this.numerator;
             let fden = this.denominator;

             if (!fnum) {
                 this.exponent = 0n;
                 this.mantissa = 0n;
                 return;
             }

             const bnum = BitLength(fnum);
             const bden = BitLength(fden);
             let exp = BigInt(bnum - bden);

             if (exp >= 0)
                 fden <<= exp;
             else
                 fnum <<= -exp;
             if (fnum < fden) {
                 fnum <<= 1n;
                 exp -= 1n;
             }

             exp += P.exponentBias;
             if (exp <= 0n) {
                 fden <<= 1n - exp;
                 exp = 0n;
             }

             const xnum = fnum << P.mantissaBits;
             const xdiv = xnum / fden;
             const xrem = xnum % fden;

             const xcmp = (xrem << 1n) - fden;
             const xrnd = !this.#round0 && ((xcmp > 0n) || ((xcmp == 0n) && (xdiv & 1n))) ? 1n : 0n;

             let man = xdiv + xrnd;

             const mshift = exp > 0n ? 1n : 0n;
             if (man >= (P.mantissaInt << mshift)) {
                 man >>= mshift;
                 exp += 1n;
             }

             if (exp < P.exponentMask) {
                 this.exponent = exp;
                 this.mantissa = man & P.mantissaMask;
             } else {
                 this.finite = false;
                 this.exponent = P.exponentMask;
                 this.mantissa = 0n;
             }
         }

         #getMantissaEx() {
             return this.mantissa | (this.exponent ? this.#P.mantissaInt : 0n);
         }

         isZero() {
             return this.exponent == 0n && this.mantissa == 0n;
         }

         isPRN() {
             return this.finite && !this.isZero();
         }

         toHexData() {
             return '0x' + toString16B(this.data, this.dataBits);
         }

         #toStringSign(plus) {
             return this.sign ? '-': plus ? '+' : '';
         }

         #toStringNPRN(plus) {
             if (this.nan) return 'NaN';
             const vsign = this.#toStringSign(plus);
             if (!this.finite) return `${vsign}Infinity`;
             if (this.isZero()) return `${vsign}0`;
             return '';
         }

         static #toStringBN(dval, nexp, base) {
             const dstr = dval.toString(base);
             const mstr = '0'.repeat(Math.max(0, nexp - dstr.length)) + dstr;
             const mint = mstr.slice(0, mstr.length - nexp);
             const mdec = nexp ? mstr.slice(-nexp).replace(/0+$/, '') : '';
             const vint = mint.length ? mint : '0';
             const vdec = mdec.length ? `.${mdec}` : '';
             return vint + vdec;
         }

         static #s10ToExp(s) {
             const sign = (s[0] == '+' || s[0] == '-') ? s[0] : '';
             if (sign) s = s.slice(1);
             const dot = s.replace(/0+$/, '').split('.');
             const sint = dot[0];
             const sdec = dot[1] ?? '';
             if (sint == '0') {
                 const rdec = sdec.replace(/^0+/, '');
                 const tnum = `${sign}${rdec[0]}.${rdec.slice(1)}`;
                 const rnum = tnum.replace(/\.$/, '');
                 return `${rnum}e${rdec.length - sdec.length - 1}`;
             } else {
                 const rint = sint.replace(/^0+/, '');
                 const tnum = `${rint[0]}.${rint.slice(1)}${sdec}`;
                 const rnum = tnum.replace(/\.$/, '');
                 return `${rnum}e+${rint.length - 1}`
             }
         }

         toExponential(plus) {
             if (!this.isPRN())
                 return this.#toStringNPRN(plus);
             return this.#S.#s10ToExp(this.toString10(plus));
         }

         #toStringBF(plus, base) {
             if (!this.isPRN())
                 return this.#toStringNPRN(plus);
             const bexp = this.exponent2 - this.mantissaBits;
             const pexp = bexp > 0n ? bexp : 0n;
             const nexp = bexp < 0n ? Number(-bexp) : 0;
             const dbin = this.#getMantissaEx() << pexp;
             const dval = base == 10 ? dbin * power5n(nexp) : dbin;
             return this.#toStringSign(plus) + this.#S.#toStringBN(dval, nexp, base);
         }

         toString2F(plus) { return this.#toStringBF(plus, 2); }
         toString10F(plus) { return this.#toStringBF(plus, 10); }

         toString10(plus) {
             if (!this.isPRN())
                 return this.#toStringNPRN(plus);

             const S = this.#S;
             const bits = this.dataBits;
             const rnd0 = this.#round0;
             const toS = S.#toStringBN;

             const bexp = this.exponent2 - this.mantissaBits;
             const pexp = bexp > 0n ? bexp : 0n;
             const nexp = bexp < 0n ? Number(-bexp) : 0;
             const dp5n = power5n(nexp);
             const dval = (this.#getMantissaEx() << pexp) * dp5n;

             const dcol = Math.trunc(LOG10_2 * (BitLength(dp5n << pexp) - 1));
             let dmod = power10n(dcol);
             let dcan = [dval];
             for (;;) {
                 const fcan = dcan.map(v => v - v % dmod);
                 const ccan = fcan.map(v => [v, v + dmod]).flat();
                 const ncan = ccan.filter(v => {
                     const c = new S(bits, toS(v, nexp), rnd0);
                     return (c.finite &&
                             c.exponent == this.exponent &&
                             c.mantissa == this.mantissa);
                 });
                 if (!ncan.length)
                     break;
                 dcan = ncan;
                 dmod *= 10n;
             }
             dcan.sort((a, b) => {
                 const xa = gAbs(a, dval);
                 const xb = gAbs(b, dval);
                 return xa == xb ? 0 : xa < xb ? -1 : 1;
             });
             return this.#toStringSign(plus) + this.#S.#toStringBN(dcan[0], nexp);
         }

         toString16(plus) {
             if (!this.isPRN())
                 return this.#toStringNPRN(plus);
             const mbsz = this.mantissaBits;
             const mshl = -mbsz & 3n;
             const hdec = toString16B(this.mantissa << mshl, mbsz + mshl);
             const hman = `0x${this.exponent ? 1 : 0}.${hdec}`;
             const exp2 = this.exponent2;
             const hexp = (exp2 >= 0 ? '+' : '') + `${exp2}`;
             return this.#toStringSign(plus) + `${hman}p${hexp}`;
         }

         toSepSignExpMan() {
             const sign = this.sign ? 1 : 0;
             const exp = toString16B(this.exponent, this.exponentBits);
             const man = toString16B(this.mantissa, this.mantissaBits);
             return `${sign}:${exp}:${man}`
         }
     }

     class IEEE754Binary16 extends IEEE754Binary { constructor() { super(16, ...arguments); } }
     class IEEE754Binary32 extends IEEE754Binary { constructor() { super(32, ...arguments); } }
     class IEEE754Binary64 extends IEEE754Binary { constructor() { super(64, ...arguments); } }
     class IEEE754Binary128 extends IEEE754Binary { constructor() { super(128, ...arguments); } }

     /*
      *
      */

     const viewOption = {}
     const binaryName = {
         16: '半精度',
         32: '単精度',
         64: '倍精度',
         128: '四倍精度',
     }
     const binaryList = Object.keys(binaryName).map(v => Number(v));
     const viewList = { bin: binaryList }

     const valueName = {
         'dat': '記憶域',
         'sem': '負:指:仮',
         'hex': '16進数',
         'exp': '指数',
         'dec': '非指数',
         'xct': '厳密値',
         'bin': '2進数',
     }
     const valueNameKeys = Object.keys(valueName);

     const optionName = {
         'rnd0': 'ゼロ方向丸め',
         'flip': '表の転置',
     }
     const optionNameKeys = Object.keys(optionName);

     /**/

     let lastInput;

     function toClipboard(text) {
         navigator.clipboard.writeText(text).then(() => {
             if (text.length >= 60)
                 text = text.slice(0, 57) + '⋅⋅⋅';
             tagClipboard.innerText = text;
         }, () => {
             tagClipboard.innerText = 'コピー失敗';
         });
     }
     const tagToClipboard = (tag => toClipboard(tag.innerText));

     function updateViewer() {
         const color_dis = 'lightgray';

         const getTag = (n => document.getElementById(n));
         const setfmt = ((m, n) => {
             const tagTd = getTag(`tagMode_${n}`);
             const tagInp = getTag(`chkbox_${n}`);
             tagInp.checked = viewOption[n];
             tagInp.disabled = !m;
             tagTd.style.backgroundColor = m ? null : color_dis;
         });

         viewOption['fbin'] = binaryList.filter(n => viewOption.bin && viewOption[`bin${n}`]);
         binaryList.forEach(n => setfmt(viewOption.bin, `bin${n}`));

         [['val', valueNameKeys],
          ['opt', optionNameKeys],
         ].forEach(l => {
             const [pfx, keys] = l;
             keys.forEach(k => {
                 const key = `${pfx}${k}`;
                 const tagName = getTag(`chkbox_${key}`);
                 tagName.checked = viewOption[key];
             });
         });
     }

     /**/

     const genCbTag = ((tag, cls, txt) =>
         `<${tag} class="${cls}" onclick="toClipboard('${txt}')">${txt}</${tag}>`
     );
     const genCodeCbTag = ((cls, txt) => genCbTag('code', cls, txt));

     function getValueNameList() {
         return valueNameKeys.map(
             k => viewOption[`val${k}`] ? valueName[k] : null
         ).filter(v=>v);
     }
     function getData(inp) {
         const rnum = new FractionBI(inp);
         const rnd0 = viewOption.optrnd0;
         return {
             inp: inp,
             bin: {
                 list: viewOption.fbin.map(v => {
                     const bin = new IEEE754Binary(v, rnum, rnd0);
                     return {
                         data: bin,
                         tag: [
                             viewOption.valdat ? ['ctext htext', bin.toHexData()] : null,
                             viewOption.valsem ? ['ctext', bin.toSepSignExpMan()] : null,
                             viewOption.valhex ? ['ctext', bin.toString16()] : null,
                             viewOption.valexp ? ['ctext', bin.toExponential()] : null,
                             viewOption.valdec ? ['ctext', bin.toString10()] : null,
                             viewOption.valxct ? ['ctext ftext', bin.toString10F()] : null,
                             viewOption.valbin ? ['ctext ftext', bin.toString2F()] : null,
                         ].filter(v=>v).map(l => genCodeCbTag(l[0], l[1])),
                     }
                 }),
             },
         }
     }

     function genOutputBinBlock1(nlist) {
         const binf = nlist[0].bin; if (!binf.list.length) return '';
         const getBinTag = ((i, b, n) => nlist[i].bin.list[b].tag[n]);
         const cline = ['eline', 'oline'];
         const tagHeader = getValueNameList();
         return [
             '<tr>',
             '<th>形式</th>',
             viewOption.fbin.map(n => `<th>binary${n}</th>`),
             '</tr>',
             nlist.map((s, i) => [
                 '<tr class="inpdata">',
                 '<th style="min-width: 3em;">入力</th>',
                 `<td class="ntext" colspan="${viewOption.fbin.length}">`,
                 genCodeCbTag('ctext large', s.inp),
                 '</td>',
                 '</tr>',
                 tagHeader.map((s, n) => [
                     `<tr class="${cline[n & 1]}">`,
                     `<th class="small">${s}</th>`,
                     viewOption.fbin.map((_, b) => [
                         '<td class="vtop ntext">', getBinTag(i, b, n), '</td>',
                     ]),
                     '</tr>',
             ])]),
         ];
     }

     function genOutputBinBlock2(nlist) {
         const binf = nlist[0].bin; if (!binf.list.length) return '';
         const getBinTag = ((i, b, n) => nlist[i].bin.list[b].tag[n]);
         const cline = ['eline', 'oline'];
         const tagHeader = getValueNameList();
         return [
             '<tr>',
             '<th>形式</th>',
             tagHeader.map(n => `<th>${n}</th>`),
             '</tr>',
             nlist.map((s, i) => [
                 '<tr class="inpdata">',
                 '<th style="min-width: 3em;">入力</th>',
                 `<td class="ntext" colspan="${tagHeader.length}">`,
                 genCodeCbTag('ctext large', s.inp),
                 '</td>',
                 '</tr>',
                 viewOption.fbin.map((w, b) => [
                     `<tr class="${cline[b & 1]}">`,
                     `<th class="small">binary${w}</th>`,
                     tagHeader.map((_, n) => [
                         '<td class="vtop ntext">', getBinTag(i, b, n), '</td>',
                     ]),
                     '</tr>',
             ])]),
         ];
     }

     const input_separator = [
         [...Array(33)].map((_, i) => String.fromCodePoint(i)),
         '!"#$%&\'()*,/:;<=>?@[\\]^`{|}~',
     ].join('');

     function onUpdate(inp) {
         inp = inp ?? tagNumber.innerText;
         const nums = [...input_separator].reduce(
             (p, c) => p.map(s => s.split(c)).flat(), [inp]
         ).filter(v => v != null && v.length);
         if (!nums.length)
             return;
         lastInput = inp;

         const nlist = nums.map(s => getData(s));
         const bintags = (viewOption.optflip ? genOutputBinBlock2 : genOutputBinBlock1)(nlist);

         tagOutput.innerHTML = [
         '<table>', bintags, '</table>', '<p></p>',
         ].flat(8).join('');
     }

     function onChangeViewer(tag) {
         viewOption[tag.id.split('_')[1]] = tag.checked;
         updateViewer();
         onUpdate(lastInput);
     }

     /*
      *
      */

     window.onload = (() => {
         const chkbox = ((n, l) => [
             `<input id="chkbox_${n}" name="chkbox_${n}" type="checkbox"`,
             ` onchange="onChangeViewer(this)">`,
             `<label id="label_${n}" for="chkbox_${n}">${l}</label>`,
         ]);

         const exact = ((n) => new IEEE754Binary64(n).toString16());

         document.body.innerHTML = [
         '<h3>IEEE 754 浮動小数点数 詳細表示</h3>',
         '<div><textarea',
         ' id="tagNumber"', ' cols="72"', ' rows="5"',
         ' placeholder="数値を入力してください"',
         ' oninput="onUpdate(value)">',
         '</textarea></div>',
             /**/
         '<details id="tagSettings"><summary>表示設定</summary>',
         '<table>',
         '<tr>', '<th>データ型</th>',
             Object.entries(binaryName).map(prec => {
                 const [b, l] = prec;
                 return [`<td id="tagMode_bin${b}">`, chkbox(`bin${b}`, l), `(${b})</td>`];
             }),
             '</tr>',
             '</table>',
             '<table style="margin-top: 2px;">',
             '<tr>', '<th>表示項目</th>',
             Object.entries(valueName).map(v => [
                 `<td id="tagView_val${v[0]}">`, chkbox(`val${v[0]}`, v[1]), '</td>'
             ]),
             '</tr>',
             '</table>',
             '<table style="margin-top: 2px;">',
             '<tr>', '<th>その他</th>',
             Object.entries(optionName).map(v => [
                 `<td id="tagOption_opt${v[0]}">`, chkbox(`opt${v[0]}`, v[1]), '</td>'
             ]),
             '</table>',
             '</details>',
             /**/
             '<div>&nbsp;</div>',
             '<div class="xsmall">クリップボード：<code id="tagClipboard">(数値をクリック)</code></div>',
             '<div>&nbsp;</div>',
             '<div id="tagOutput"></div>',
             '<div>&nbsp;</div>',
             '<table>',
             '<tr><th colspan="4">定数テスト（binary64）</th></tr>',
             [['PI', 'LN2', 'LOG2E', 'SQRT1_2'],
              ['E', 'LN10', 'LOG10E', 'SQRT2'],
             ].map(l => [
                 '<tr>',
                 l.map(n => [
                     '<td style="padding: 2px;">',
                     `<button onclick="onUpdate('${exact(Math[n])}')">Math.${n}</button>`,
                     '</td>',
                 ]),
                 '</tr>',
             ]),
             '</table>',
             '<div>&nbsp;</div>',
             '<table>',
             '<tr class="small"><th colspan="2">説明</th></tr>',
             '<tr class="small eline"><th>入力</th><td>改行などの区切りで複数値に対応</td></tr>',
             '<tr class="small"><th>表示項目</th><th>浮動小数点数に対する内容</th></tr>',
             '<tr class="small eline"><th>記憶域</th><td>メモリ上のデータ</td></tr>',
             '<tr class="small oline"><th>負:指:仮</th><td>符号ビット、指数部(16進)、仮数部(16進)の値</td></tr>',
             '<tr class="small eline"><th>16進数</th><td>指数形式16進数(厳密値)</td></tr>',
             '<tr class="small oline"><th>指数</th><td>指数形式10進数(近似値)</td></tr>',
             '<tr class="small eline"><th>非指数</th><td>10進数(近似値)</td></tr>',
             '<tr class="small oline"><th>厳密値</th><td>10進数(厳密値)</td></tr>',
             '<tr class="small eline"><th>2進数</th><td>2進数(厳密値) : 前置 \'0b\' は省略</td></tr>',
             '</table>',
         ].flat(9).join('');

         /*
          * URLの引数
          *
          * on=<type> または off=<type> で表示を制御
          *
          * <type>:
          *   setting: 表示設定
          *
          *   bin16: 2進数半精度
          *   bin32: 2進数単精度
          *   bin64: 2進数倍精度
          *   bin128: 2進数四倍精度
          *
          *   valdat: 記憶域
          *   valsem: 負:指:仮
          *   valhex: 16進
          *   valexp: 指数
          *   valdec: 非指数
          *   valxct: 厳密値
          *   valbin: 2進数
          *
          *   optrnd0: ゼロ方向丸め
          *   optflip: 表の転置
          */

         const set_flag = ((f, v) => {
             const p = v.slice(0, 3);
             if (viewList[p]) {
                 if (f)
                     viewOption[p] = f;
                 viewOption[v] = f;
                 return;
             }

             const s = v.slice(3);
             if (p == 'val') {
                 if (valueName[s])
                     viewOption[v] = f;
                 return;
             }
             if (p == 'opt') {
                 if (optionName[s])
                     viewOption[v] = f;
                 return;
             }
             if (v == 'setting') {
                 tagSettings.open = f;
                 return;
             }

             // ...
         });
         const set_flags = ((f, l) => l.forEach(v => set_flag(f, v)));

         /**/

         const url = new URL(window.location);
         const search = url.searchParams;

         const get_arglist = (l => l.map(n => search.getAll(n).map(v => v.split(','))).flat(5));
         const args_on = get_arglist(['on', 's']);
         const args_off = get_arglist(['off', 'u']);
         const args_inp = search.getAll('n').join('\n');

         set_flags(true, ['bin32', 'bin64']);
         set_flags(true, valueNameKeys.map(k => `val${k}`));

         set_flags(true, args_on);
         set_flags(false, args_off);

         updateViewer();
         onUpdate(args_inp.length ? args_inp : `${exact(Math.PI)}`);
     });

    </script>
  </body>
</html>
```

</div></details>

# Python コマンドライン版

<details><summary>Python ソースコード(長いので折りたたみ)</summary><div>

```Python:sample.py
#!/usr/bin/env python3

import math


class IEEE754Binary:
    """IEEE 754 - Binary 形式"""

    class _Parameter:
        """符号部、指数部、仮数部の情報"""

        def __init__(self, exponent_bits: int, mantissa_bits: int):
            self.mantissa_position = 0
            self.mantissa_bits = mantissa_bits
            self.mantissa_int = 1 << mantissa_bits
            self.mantissa_mask = self.mantissa_int - 1

            self.exponent_position = mantissa_bits
            self.exponent_bits = exponent_bits
            self.exponent_mask = (1 << exponent_bits) - 1
            self.exponent_bias = self.exponent_mask >> 1

            self.sign_position = self.exponent_position + exponent_bits
            self.sign_bit = 1 << self.sign_position

    # ----------

    _BINARY_TABLE = {
        16: _Parameter(5, 10),
        32: _Parameter(8, 23),
        64: _Parameter(11, 52),
        128: _Parameter(15, 112),
    }

    # ----------

    _BASE2_TABLE = {f'{n}': n for n in range(2)}
    _BASE8_TABLE = {f'{n}': n for n in range(8)}
    _BASE10_TABLE = {f'{n}': n for n in range(10)}
    _BASE16_TABLE = {f'{n:x}': n for n in range(16)}

    _BASE_TABLE = {
        'b': (2, _BASE2_TABLE),
        'o': (8, _BASE8_TABLE),
        'x': (16, _BASE16_TABLE),
    }

    # ----------

    def __init__(self, data_bits: int, value: any = None, round_toward_zero: bool = None):
        self._round_toward_zero = round_toward_zero

        self._data_bits = data_bits
        self._parameter = IEEE754Binary._BINARY_TABLE[self._data_bits]

        self._binary = None

        self._nan = None
        self._finite = None

        self._sign = None
        self._exponent = None
        self._mantissa = None

        self._numerator = None
        self._denominator = None

        if value is None:
            self._set_zero(False)
        elif isinstance(value, int):
            self._from_int(value)
        elif isinstance(value, float):
            self._from_float(value)
        elif isinstance(value, str):
            self._from_string(value)
        elif isinstance(value, IEEE754Binary):
            self._from_binary(value)
        else:
            raise TypeError(value)

    def __repr__(self) -> str:
        """10進数文字列を返す"""
        return self._str_decimal()

    # ----------

    @property
    def round_toward_zero(self) -> bool:
        """ゼロ方向丸めの場合は True"""
        return self._round_toward_zero

    @property
    def data_bits(self) -> int:
        """浮動小数点データのビット数"""
        return self._data_bits

    @property
    def binary(self) -> int:
        """記憶域用のデータ"""
        return self._binary

    @property
    def nan(self) -> bool:
        """非数の場合は True"""
        return self._nan

    @property
    def finite(self) -> bool:
        """有限値の場合は True"""
        return self._finite

    @property
    def sign(self) -> (bool, None):
        """負の場合は True"""
        return self._sign

    @property
    def sign_position(self) -> int:
        """符号のビット位置"""
        return self._parameter.sign_position

    @property
    def exponent(self) -> int:
        """指数部のデータ"""
        return self._exponent

    @property
    def exponent_position(self) -> int:
        """指数部のビット位置"""
        return self._parameter.exponent_position

    @property
    def exponent_bias(self) -> int:
        """指数部のバイアス値"""
        return self._parameter.exponent_bias

    @property
    def exponent_bits(self) -> int:
        """指数部のビット数"""
        return self._parameter.exponent_bits

    @property
    def mantissa(self) -> int:
        """仮数部のデータ"""
        return self._mantissa

    @property
    def mantissa_bits(self) -> int:
        """仮数部のビット数"""
        return self._parameter.mantissa_bits

    @property
    def numerator(self) -> (int, None):
        """分数表現での分子"""
        return self._numerator

    @property
    def denominator(self) -> (int, None):
        """分数表現での分母"""
        return self._denominator

    # ----------

    def _set_binary(self) -> 'IEEE754Binary':
        param = self._parameter
        sign = param.sign_bit if self.sign else 0
        exp = self._exponent << param.exponent_position
        self._binary = sign | exp | self._mantissa
        return self

    def _set_nan(self, sign: bool) -> 'IEEE754Binary':
        param = self._parameter
        self._nan = True
        self._finite = False
        self._sign = sign
        self._exponent = param.exponent_mask
        self._mantissa = param.mantissa_int >> 1
        self._numerator = None
        self._denominator = None
        return self._set_binary()

    def _set_inf(self, sign: bool) -> 'IEEE754Binary':
        self._nan = False
        self._finite = False
        self._sign = sign
        self._exponent = self._parameter.exponent_mask
        self._mantissa = 0
        self._numerator = None
        self._denominator = None
        return self._set_binary()

    def _set_zero(self, sign: bool) -> 'IEEE754Binary':
        self._nan = False
        self._finite = True
        self._sign = sign
        self._exponent = 0
        self._mantissa = 0
        self._numerator = 0
        self._denominator = 1
        return self._set_binary()

    def _set_finite(self, sign: bool, numerator: int, denominator: int) -> 'IEEE754Binary':
        if not denominator:
            return (self._set_inf if numerator else self._set_nan)(sign)
        if not numerator:
            return self._set_zero(sign)

        self._nan = False
        self._finite = True
        self._sign = sign

        param = self._parameter

        bmask = numerator | denominator
        shift = (bmask & -bmask).bit_length() - 1
        numerator >>= shift
        denominator >>= shift
        while True:
            ndiv, nmod = divmod(numerator, 5)
            ddiv, dmod = divmod(denominator, 5)
            if nmod or dmod:
                break
            numerator = ndiv
            denominator = ddiv
        self._numerator = numerator
        self._denominator = denominator

        fnum = numerator
        fden = denominator

        exp = fnum.bit_length() - fden.bit_length()
        if exp >= 0:
            fden <<= exp
        else:
            fnum <<= -exp
        if fnum < fden:
            fnum <<= 1
            exp -= 1

        exp += param.exponent_bias
        if exp <= 0:
            fden <<= 1 - exp
            exp = 0

        xnum = fnum << param.mantissa_bits
        xdiv = xnum // fden
        xrem = xnum % fden

        xcmp = (xrem << 1) - fden
        xrnd = (1 if not self._round_toward_zero and
                ((xcmp > 0) or ((xcmp == 0) and (xdiv & 1))) else 0)

        man = xdiv + xrnd
        mshift = int(exp > 0)
        if man >= (param.mantissa_int << mshift):
            man >>= mshift
            exp += 1
        if exp < param.exponent_mask:
            self._exponent = exp
            self._mantissa = man & param.mantissa_mask
        else:
            self._finite = False
            self._exponent = param.exponent_mask
            self._mantissa = 0
        return self._set_binary()

    def setfrac(self, sign: bool, numerator: int, denominator: int) -> 'IEEE754Binary':
        """分数で値を設定する"""
        return self._set_finite(sign, numerator, denominator)

    @staticmethod
    def fromfrac(data_bits: int, round_toward_zero: bool,
                 sign: bool, numerator: int, denominator: int) -> 'IEEE754Binary':
        """分数から IEEE754Binary を作る"""
        fpval = IEEE754Binary(data_bits, None, round_toward_zero)
        return fpval.setfrac(sign, numerator, denominator)

    # ----------

    def _from_int(self, rhs: int) -> 'IEEE754Binary':
        return self._set_finite(rhs < 0, abs(rhs), 1)

    def _from_float(self, rhs: float) -> 'IEEE754Binary':
        sign = math.copysign(1.0, rhs) < 0
        if not math.isfinite(rhs):
            return (self._set_nan if math.isnan(rhs) else self._set_inf)(sign)
        if not rhs:
            return self._set_zero(sign)
        man, exp = math.frexp(rhs)
        iman = int(man * (1 << 53))
        iexp = exp - 53
        bnum = iman << max(0, iexp)
        bden = 1 << max(0, -iexp)
        return self._set_finite(sign, bnum, bden)

    def _from_binary(self, rhs: 'IEEE754Binary') -> 'IEEE754Binary':
        self._round_toward_zero = rhs.round_toward_zero
        self._data_bits = rhs.data_bits
        self._parameter = IEEE754Binary._BINARY_TABLE[self._data_bits]
        self._binary = rhs.binary
        self._nan = rhs.nan
        self._finite = rhs.finite
        self._sign = rhs.sign
        self._exponent = rhs.exponent
        self._mantissa = rhs.mantissa
        self._numerator = rhs.numerator
        self._denominator = rhs.denominator
        return self

    def _from_string(self, text: str) -> 'IEEE754Binary':
        text = text.strip().lower()

        fsign = False
        fnum = 0
        fden = 1

        tpos = 0
        if tpos >= len(text):
            return self._set_nan(fsign)
        tch = text[tpos]
        if tch in ('-+'):
            fsign = tch == '-'
            tpos += 1
            if tpos >= len(text):
                return self._set_nan(fsign)

        tch = text[tpos:]
        if tch == 'nan':
            return self._set_nan(fsign)
        if tch in ('inf', 'infinity'):
            return self._set_inf(fsign)

        dtab = self._BASE10_TABLE
        btab = dtab
        base = 10

        if tpos >= len(text):
            return self._set_nan(fsign)
        tch = text[tpos]
        if tch == '0':
            tpos += 1
            if tpos >= len(text):
                return self._set_finite(fsign, fnum, fden)
            tch = text[tpos]
            bmap = self._BASE_TABLE.get(tch)
            if bmap:
                base, btab = bmap
                tpos += 1
                if tpos >= len(text):
                    return self._set_nan(fsign)
                tch = text[tpos]

        dot = False
        while True:
            cnum = btab.get(tch)
            if cnum is not None:
                fnum = fnum * base + cnum
                if dot:
                    fden *= base
            elif tch not in ('_,'):
                if tch != '.':
                    break
                if dot:
                    return self._set_nan(fsign)
                dot = True
            tpos += 1
            if tpos >= len(text):
                return self._set_finite(fsign, fnum, fden)
            tch = text[tpos]

        expm = base
        if tch not in ('ep'):
            return self._set_nan(fsign)
        if tch == 'p':
            if expm == 10:
                return self._set_nan(fsign)
            expm = 2
        tpos += 1
        if tpos >= len(text):
            return self._set_nan(fsign)
        tch = text[tpos]

        esign = False
        if tch in ('-+'):
            esign = tch == '-'
            tpos += 1
            if tpos >= len(text):
                return self._set_nan(fsign)
            tch = text[tpos]

        xnum = 0
        while True:
            cnum = dtab.get(tch)
            if cnum is None:
                return self._set_nan(fsign)
            xnum = xnum * 10 + cnum
            tpos += 1
            if tpos >= len(text):
                break
            tch = text[tpos]
        if xnum >= 10000000:
            return (self._set_zero if esign else self._set_inf)(fsign)

        expv = 1
        while xnum:
            if xnum & 1:
                expv *= expm
            expm *= expm
            xnum >>= 1
        if esign:
            fden *= expv
        else:
            fnum *= expv
        return self._set_finite(fsign, fnum, fden)

    # ----------

    def _is_prn(self) -> bool:
        return not self._finite or not (self._exponent or self._mantissa)

    def _str_sign(self, plus: bool = None) -> str:
        return '-' if self._sign else '+' if plus else ''

    def _str_nan(self) -> str:
        return 'nan'

    def _str_inf(self, plus: bool = None) -> str:
        return self._str_sign(plus) + 'inf'

    def _str_zero(self, plus: bool = None) -> str:
        return self._str_sign(plus) + '0'

    def _str_prn(self, plus: bool = None) -> str:
        return (self._str_nan() if self._nan else
                (self._str_zero if self._finite else self._str_inf)(plus))

    def _str_decimal(self, plus: bool = None, efmt: bool = None, exact: bool = None) -> str:
        if self._is_prn():
            return self._str_prn(plus)

        param = self._parameter
        dexp = self._exponent
        dman = self._mantissa

        bexp = max(1, dexp) - param.exponent_bias - param.mantissa_bits
        pexp = max(0, bexp)
        nexp = max(0, -bexp)
        bman = dman | (param.mantissa_int if dexp else 0)
        dp5n = pow(5, nexp)
        fnum = (bman << pexp) * dp5n
        fden = dp5n << nexp

        log10_2 = 0.3010299956639812
        dmod = pow(10, int(log10_2 * ((dp5n << pexp).bit_length() - 1)))

        _new = self.fromfrac
        bits = self._data_bits
        frtz = self._round_toward_zero

        def check(value):
            chk = _new(bits, frtz, False, value, fden)
            return chk.finite and chk.exponent == dexp and chk.mantissa == dman

        dcan = [fnum]
        while not exact:
            fcan = [v - v % dmod for v in dcan]
            ccan = [v + dmod for v in fcan]
            ncan = list(filter(check, fcan + ccan))
            if not ncan:
                break
            dcan = ncan
            dmod *= 10
        fnum = sorted(dcan, key=lambda v: abs(v - fnum))[0]
        snum = self._format_decimal(fnum, nexp)
        if efmt:
            snum = self._str_dec_exp(snum)
        return f'{self._str_sign(plus)}{snum}'

    def _str_hexadecimal(self, plus: bool = None) -> str:
        if self._is_prn():
            return self._str_prn(plus)

        param = self._parameter
        dexp = self._exponent
        dman = self._mantissa
        mbsz = param.mantissa_bits
        mshl = -mbsz & 3
        hdec = self._format_hexadecimal(dman << mshl, mbsz + mshl)
        hman = f'0x{int(bool(dexp))}.{hdec}'
        exp2 = max(1, dexp) - param.exponent_bias
        hexp = f'+{exp2}' if exp2 >= 0 else f'{exp2}'
        return f'{self._str_sign(plus)}{hman}p{hexp}'

    @staticmethod
    def _format_decimal(dval: int, nexp: int) -> str:
        dstr = str(dval)
        if not nexp:
            return dstr
        mstr = '0' * max(0, nexp - len(dstr)) + dstr
        mint, mdec = mstr[:-nexp], mstr[-nexp:].rstrip('0')
        return ((mint if mint else '0') + f'.{mdec}').rstrip('.')

    @staticmethod
    def _str_dec_exp(nstr: str) -> str:
        sint, sdec = (nstr.split('.') + [''])[:2]
        if sint == '0':
            edec = len(sdec)
            sdec = sdec.lstrip('0')
            snum = f'{sdec[:1]}.{sdec[1:]}'.rstrip('.')
            return f'{snum}e-{edec - len(sdec) + 1}'

        eint = len(sint)
        snum = (sint + sdec).rstrip('0')
        snum = f'{snum[:1]}.{snum[1:]}'.rstrip('.')
        return f'{snum}e+{eint - 1}'

    @staticmethod
    def _format_hexadecimal(value: int, bits: int) -> str:
        cnt = max(1, (bits + 3) >> 2)
        return ('0' * cnt + f'{value:x}')[-cnt:]

    # ----------

    def data(self):
        """記憶域用の16進データ文字列を返す"""
        return '0x' + self._format_hexadecimal(self._binary, self._data_bits)

    def sep(self):
        """負:指:仮 分離形式を返す"""
        param = self._parameter
        sign = int(self._sign)
        exp = self._format_hexadecimal(self._exponent, param.exponent_bits)
        man = self._format_hexadecimal(self._mantissa, param.mantissa_bits)
        return f'{sign}:{exp}:{man}'

    def dec(self, plus: bool = None, efmt: bool = None) -> str:
        """10進文字列を返す"""
        return self._str_decimal(plus=plus, efmt=efmt)

    def full(self, plus: bool = None, efmt: bool = None) -> str:
        """10進全桁の文字列を返す"""
        return self._str_decimal(plus=plus, efmt=efmt, exact=True)

    def hex(self, plus: bool = None) -> str:
        """指数形式16進文字列を返す"""
        return self._str_hexadecimal(plus=plus)


class IEEE754Binary16(IEEE754Binary):
    def __init__(self, value: any = None, round_toward_zero: bool = None):
        super().__init__(16, value, round_toward_zero)


class IEEE754Binary32(IEEE754Binary):
    def __init__(self, value: any = None, round_toward_zero: bool = None):
        super().__init__(32, value, round_toward_zero)


class IEEE754Binary64(IEEE754Binary):
    def __init__(self, value: any = None, round_toward_zero: bool = None):
        super().__init__(64, value, round_toward_zero)


class IEEE754Binary128(IEEE754Binary):
    def __init__(self, value: any = None, round_toward_zero: bool = None):
        super().__init__(128, value, round_toward_zero)


if __name__ == '__main__':
    import argparse
    import sys

    def main():
        parser = argparse.ArgumentParser()
        # parser.add_argument('-v', '--verbose', action='store_true')
        parser.add_argument('-H', '--binary16', action='store_true', help='半精度(binary16)を使用する')
        parser.add_argument('-S', '--binary32', action='store_true', help='単精度(binary32)を使用する')
        parser.add_argument('-D', '--binary64', action='store_true', help='倍精度(binary64)を使用する')
        parser.add_argument('-Q', '--binary128', action='store_true', help='四倍精度(binary128)を使用する')
        parser.add_argument('-s', '--storage', action='store_true', help='記憶域用データを表示する')
        parser.add_argument('-p', '--parameter', action='store_true', help='負:指:仮 分離形式を表示する')
        parser.add_argument('-x', '--hex', action='store_true', help='16進数を表示する')
        parser.add_argument('-e', '--exp', action='store_true', help='指数形式10進数を表示する')
        parser.add_argument('-d', '--dec', action='store_true', help='10進数を表示する')
        parser.add_argument('-f', '--full', action='store_true', help='厳密値を表示する')
        parser.add_argument('-0', '--roundtowardzero', action='store_true', help='ゼロ方向丸めを使用する')
        parser.add_argument('numbers', metavar='N', nargs='+')
        args = parser.parse_args()

        binary_types = tuple(filter(None, [
            ('binary16', IEEE754Binary16) if args.binary16 else None,
            ('binary32', IEEE754Binary32) if args.binary32 else None,
            ('binary64', IEEE754Binary64) if args.binary64 else None,
            ('binary128', IEEE754Binary128) if args.binary128 else None,
        ]))
        if not binary_types:
            print('オプション -H, -S, -D, -Q から1つ以上指定してください')
            parser.print_help()
            sys.exit(2)

        sep = '-' * 32
        for num in args.numbers:
            print('\n'.join([sep, f'入力文字列: "{num}"', sep]))
            for bname, btype in binary_types:
                fpval = btype(num, round_toward_zero=args.roundtowardzero)
                [print(line) for line in filter(lambda s: s is not None, [
                    f'{bname}',
                    f'  記憶域: {fpval.data()}' if args.storage else None,
                    f'  分離  : {fpval.sep()}' if args.parameter else None,
                    f'  16進  : {fpval.hex()}' if args.hex else None,
                    f'  指数  : {fpval.dec(efmt=True)}' if args.exp else None,
                    f'  非指数: {fpval.dec()}' if args.dec else None,
                    f'  厳密値: {fpval.full()}' if args.full else None,
                    '',
                ])]

    sys.exit(main())
```

</div></details>

```console:実行結果(ゼロ方向丸め)
% ./sample.py -HSD -spxedfb -0 0.001
--------------------------------
入力文字列: "0.001"
--------------------------------
binary16
  記憶域: 0x1418
  分離  : 0:05:018
  16進  : 0x1.060p-10
  指数  : 1e-3
  非指数: 0.001
  厳密値: 0.00099945068359375
  2進数 : 0.00000000010000011

binary32
  記憶域: 0x3a83126e
  分離  : 0:75:03126e
  16進  : 0x1.0624dcp-10
  指数  : 1e-3
  非指数: 0.001
  厳密値: 0.00099999993108212947845458984375
  2進数 : 0.00000000010000011000100100110111

binary64
  記憶域: 0x3f50624dd2f1a9fb
  分離  : 0:3f5:0624dd2f1a9fb
  16進  : 0x1.0624dd2f1a9fbp-10
  指数  : 1e-3
  非指数: 0.001
  厳密値: 0.00099999999999999980397624721462079833145253360271453857421875
  2進数 : 0.00000000010000011000100100110111010010111100011010100111111011
```

```console:実行結果(近傍丸め)
% ./sample.py -HSD -spxedfb 0.001
--------------------------------
入力文字列: "0.001"
--------------------------------
binary16
  記憶域: 0x1419
  分離  : 0:05:019
  16進  : 0x1.064p-10
  指数  : 1e-3
  非指数: 0.001
  厳密値: 0.00100040435791015625
  2進数 : 0.00000000010000011001

binary32
  記憶域: 0x3a83126f
  分離  : 0:75:03126f
  16進  : 0x1.0624dep-10
  指数  : 1e-3
  非指数: 0.001
  厳密値: 0.001000000047497451305389404296875
  2進数 : 0.000000000100000110001001001101111

binary64
  記憶域: 0x3f50624dd2f1a9fc
  分離  : 0:3f5:0624dd2f1a9fc
  16進  : 0x1.0624dd2f1a9fcp-10
  指数  : 1e-3
  非指数: 0.001
  厳密値: 0.001000000000000000020816681711721685132943093776702880859375
  2進数 : 0.000000000100000110001001001101110100101111000110101001111111
```