CODE Polyglot / 直した不具合

カウプ指数がちょうど .x5 のとき、小数第1位が下に丸まる

身長100cm・体重17.55kg → 17.5(正しくは 17.6)

何が起きていたか

乳幼児の身長と体重からカウプ指数を出し、年齢区分ごとの基準で「やせすぎ〜太りすぎ」に分けるツールで、指数が小数第2位でちょうど5になる入力を、下に丸めていました。

  • 身長 100cm・体重 17.55kg: 17.55 × 1000 ÷ 100² × 10 は 17.55 ちょうどで、小数第1位に四捨五入すると 17.6 です。ツールは 17.5 と出していました
  • 40.0cm・8.04kg は 50.25 ちょうどで、正しくは 50.3 です。ツールは 50.2 と出していました

どのくらいの入力で起きていたか

身長 30.0〜140.0cm(0.1刻み)× 体重 1.00〜40.00kg(0.01刻み)の 4,295,111通り で、正確な値と比べると、43通りで表示が 0.1 小さく出ていました。区分は丸めたあとの指数で決める仕様ですが、この範囲では区分まで変わる入力はありませんでした。

どうやって見つかったか

CODE Polyglot の ローレル指数 で同じ種類の不具合(直した不具合)が見つかりました。そこで、シルギア側が、同じように体重を身長の累乗で割るツールを探して直しました。CODE Polyglot は、直したコードを本番に出す前と出したあとに、全通りで確かめました。

原因

  • 17.55 × 1000 ÷ 100² × 10 を2進数の小数で計算すると、17.55 よりわずかに小さい値になります。Math.round(指数 × 10) / 10 で丸めていたので、17.5 になりました

どう直したか

計算を新しいファイル calc.js に分け、入力の文字列を分数(BigInt)のまま計算して、小数第1位に1回だけ四捨五入するようにしました(0.5 ちょうどは大きい方へ)。

確かめたこと

CODE Polyglot の検証(tools/shirugear-verify/。本番の app.js と calc.js をそのまま動かし、画面の文字を正確な分数の正解と比べる)で確かめました。

入力は次の 6,016,972通り です。

  • 上の 4,295,111通り(年齢区分は入力ごとに4つを順に)
  • 身長 0.1刻み × 体重 0.1刻み × 年齢区分4つ
  • 1e2 のような書き方
  • エラーになる入力

比べたのは、指数・区分・説明の行・ふつうの範囲・コピーの文字です。

版不一致
直す前の本番6,016,972通り中44通り(指数の表示とコピーの文字)
修正(0db43e57c)・本番に反映する前6,016,972通り中0通り
本番に反映したあと(2026-10-30。本番の app.js・calc.js が e82a5a944 と同じことも確認)6,016,972通り中0通り

← 直した不具合の一覧へ