文字列を Number(JavaScript) 型に変換して詳細を出力します。
C/C++ double 型, Python float 型も同じ形式です。
See the Pen Untitled by Ikiuo (@ikiuo) on CodePen.
HTML単体版
HTML ファイル(長いので折りたたみ)
sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>IEEE 754 倍精度浮動小数点数 詳細表示</title>
<style>
body {
width: 40em;
margin: auto;
}
table {
border: solid 1px #e2e2e2;
border-collaspe: collaspe;
border-spacing: 0;
}
th, td { border: solid 1px #e2e2e2; }
td { padding: 2px; }
.left { text-align: left; }
.center { text-align: center; }
.right { text-align: right; }
.small { font-size: small; }
.xsmall { font-size: x-small; }
.ntext {
max-width: 30em;
word-break: break-all;
}
</style>
</head>
<body>
<h3>IEEE 754 倍精度浮動小数点数 詳細表示</h3>
<div>
<textarea id="tagNumber" cols="72" rows="5"
placeholder="数値を入力してください(改行または','区切りで複数可)"
oninput="onUpdate(value)"></textarea>
</div>
<div class="xsmall"><span id="tagClipboard"> </span></div>
<div> </div>
<code id="tagOutput"></code>
<script>
function toString(number, width, base) {
return ('0'.repeat(width) + number.toString(base)).slice(-width);
}
const insNbsp4 = (s => [...s].join(' '.repeat(4)));
function digrp(s, w) {
const n = s.length;
if (n == 0) return s;
const c = Math.trunc((n - 1) / w);
const p = (i => Math.max(0, n - w * i));
const t = [...Array(c + 1)].map((_, i) => s.slice(p(i + 1), p(i)));
t.reverse();
return t;
}
function digrps(s, w, t) {
if (t == null)
t = ' ';
return digrp(s, w).join(t);
}
function pow5n(n) {
var a = 1n;
var b = 5n;
while (n) {
if (n & 1)
a *= b;
b *= b;
n >>= 1;
}
return a;
}
const DBL_DEC_MAX = 1023 + 52 - 1;
const POW5FX = pow5n(DBL_DEC_MAX);
function parsef64(num) {
const view = new DataView(new ArrayBuffer(8));
view.setFloat64(0, num, true);
const bin = view.getBigInt64(0, true) & ((1n << 64n) - 1n);
const sign = bin >> 63n;
const exp = (bin >> 52n) & 0x7ffn;
const man = bin & 0xfffffffffffffn;
const xman = (exp ? (1n << 52n) : 0n) | man;
return {num, bin, sign, exp, man, xman}
}
function ieee754info(f64i) {
const hex = toString(f64i.bin, 16, 16);
const sign = f64i.sign;
const exp = f64i.exp;
const man = f64i.man;
return [
'<tr class="xsmall">', '<th> </th>',
'<th>符号</th>',
'<th>指数部</th>',
'<th>仮数部</th>',
'</tr>',
'<tr class="xsmall">', '<th>16進</th>',
`<td colspan="2" class="right" onclick="toClipboard('0x${hex}')">${hex.slice(0,3)}</td>`,
`<td class="left" onclick="toClipboard('0x${hex}')">${hex.slice(3)}</td>`,
'</tr>',
'<tr class="xsmall">', '<th>16進</th>',
`<td class="center">${sign}</td>`,
`<td class="right"> ${insNbsp4(toString(exp, 3, 16))}</td>`,
`<td> ${insNbsp4(toString(man, 13, 16))}</td>`,
'</tr>',
'<tr class="xsmall">', '<th>2進</th>',
`<td class="center">${sign}</td>`,
`<td class="right">${digrps(toString(exp, 11, 2), 4)}</td>`,
`<td>${digrps(toString(man, 52, 2), 4)}</td>`,
'</tr>',
'<tr class="xsmall">', '<th>10進</th>',
`<td class="center">${sign}</td>`,
`<td class="right">(${exp - 1023n}) ${exp}</td>`,
`<td class="left">${man}</td>`,
'</tr>',
].join('');
}
function fullprec(f64i) {
if (f64i.exp == 2047)
return f64i.num.toString();
const ep = f64i.exp > 0n ? f64i.exp - 1n : 0n;
const fx = (f64i.xman << ep) * POW5FX;
const tmp = '' + fx;
const tlen = 1 + DBL_DEC_MAX - tmp.length;
const tval = '0'.repeat(tlen < 0 ? 0 : tlen) + tmp;
const sint = tval.slice(0, -DBL_DEC_MAX);
const sdec = tval.slice(-DBL_DEC_MAX).replace(/0+$/, '');
return (f64i.sign ? '-' : '') + (sdec.length ? `${sint}.${sdec}` : sint);
}
function hexstr(f64i) {
if (f64i.num == 0 || f64i.exp == 2047)
return f64i.num.toString();
const sign = f64i.sign ? '-' : '';
const one = (f64i.man != f64i.xman) ? 1n : 0n;
const hex = ('0'.repeat(13) + f64i.man.toString(16)).slice(-13);
const exp = f64i.exp - (1022n + one);
return `${sign}0x${one}.${hex}p${exp >= 0 ? '+' : ''}${exp}`;
}
function parseNumber(inp) {
const n = Number(inp);
if (!isNaN(n))
return n;
var sign = 1.0;
var linp = inp.trim().toLowerCase();
switch (linp[0]) {
case '-': sign = -1.0;
case '+': linp = linp.slice(1);
default: break;
}
if (linp.slice(0, 2) != '0x')
return n;
const hinp = linp.slice(2).split('p', 2);
const hnum = hinp[0];
var hexp = 0;
if (hinp.length == 2) {
const t = hinp[1];
if (t.length == 0)
return n;
hexp = Number(t);
if (!isFinite(hexp) || hexp != Math.trunc(hexp))
return n;
}
const hdot = hnum.split('.', 2);
const hint = hdot[0];
if (hint.length == 0)
return n;
const hdec = hdot.length == 1 ? '' : hdot[1];
const hval = Number(`0x${hint}${hdec}`, 16);
if (!isFinite(hval))
return n;
return sign * hval * Math.pow(2, hexp - hdec.length * 4);
}
function numberInfo(inp) {
inp = inp.trim();
if (!inp.length)
return '';
const num = parseNumber(inp);
const exp = num.toExponential();
const f64i = parsef64(num);
const fpn = fullprec(f64i);
const hex = hexstr(f64i);
return [
'<table>',
'<tr style="background-color: #efe;">',
'<th colspan="2" style="min-width: 5em;">入力文字列</th>',
`<td colspan="2" class="ntext">${inp}</td>`,
// `<td colspan="2"><textarea disabled cols="62" rows="2">${inp}</textarea></td>`,
'</tr>',
'<tr>',
'<th colspan="2">既定表示</th>',
`<td colspan="2" onclick="toClipboard('${num}')">${num}</td>`,
'</tr>',
'<tr>',
'<th colspan="2">指数表示</th>',
`<td colspan="2" onclick="toClipboard('${exp}')">${exp}</td>`,
'</tr>',
'<tr>',
'<th colspan="2">16進形式</th>',
`<td colspan="2" onclick="toClipboard('${hex}')">${hex}</td>`,
'</tr>',
'<tr>',
'<th colspan="2">厳密値</th>',
`<td colspan="2" class="ntext" onclick="toClipboard('${fpn}')">${fpn}</td>`,
// `<td colspan="2"><textarea readonly cols="62" rows="5" onclick="toClipboard('${fpn}')">${fpn}</textarea></td>`,
'</tr>',
'<tr><th colspan="4" class="xsmall">IEEE 754 倍精度浮動小数点数 詳細</th></tr>',
ieee754info(f64i),
'</table>',
'<div> </div>',
].join('');
}
function toClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
if (text.length >= 80)
text = text.slice(0, 77) + '⋅⋅⋅';
tagClipboard.innerText = 'クリップボードへコピー:' + text;
}, () => {
tagClipboard.innerText = 'クリップボードへのコピー失敗';
});
}
function onUpdate(inp) {
tagOutput.innerHTML =
inp.split('\n').map(s => s.split(',')).flat()
.map(v => numberInfo(v)).join('');
}
window.onload = (() => onUpdate('0'));
</script>
</body>
</html>
半精度/単精度/倍精度/四倍精度 版はこちら