CODE Polyglot / 直した不具合

正確な値がちょうど …5 になる利率の表示を小さい方に丸める(単利の月利・入力そのもの・入力と同じ単位の複利)

年利12.003% → 単利の月利 1.0002%(正しくは12.003 ÷ 12 = 1.00025 → 1.0003%)、月利0.123455% → 複利の月利 0.12345%(正しくは0.12346%)

どの言語で起きるか

シルギアのツールは JavaScript で書かれています。この不具合が見つかったケースを、CODE Polyglot で10言語の「よくある書き方」で回した結果です(言語を返した答えごとにまとめ、赤い値は実際に返した間違った答え)。 JavaScript は 3件中3件で外れました。

ケース正解よくある書き方の答え(10言語)
c005単利の月利が .xxxx5 ちょうど
simple_year
12.003
simple_month
1.0003
simple_day
0.032885
compound_year
12.003
compound_month
0.9491
compound_day
0.031061
  • PHP・Python・Go・JavaScript・Java・C#・Rust・Ruby・Kotlin・Swiftsimple_month"1.0002"
c006単利の月利が .xxx5 ちょうど(日利から)
simple_year
120.45
simple_month
10.038
simple_day
0.33
compound_year
232.85
compound_month
10.54
compound_day
0.33
  • Python・Go・JavaScript・C#・Rust・Swiftsimple_month"10.037"
  • PHP・Java・Ruby・Kotlin✓ 正解
c016月利で入れて月利の複利は入力そのもの
simple_year
1.4815
simple_month
0.12346
simple_day
0.0040588
compound_year
1.4916
compound_month
0.12346
compound_day
0.0040564
  • PHP・Python・Go・JavaScript・Java・C#・Rust・Ruby・Kotlin・Swiftcompound_month"0.12345"

何が起きていたか

年利・月利・日利を相互に換算するツールで、正確な値がちょうど「…5」になる入力の表示を、小さい方に丸めていました。

  • 年利 12.003%: 単利の月利は 12.003 ÷ 12 = 1.00025 で、有効数字5桁に四捨五入すると 1.0003% です。ツールは 1.0002% と出していました
  • 日利 0.33%: 単利の月利は 0.33 × 365 ÷ 12 = 10.0375 で、正しくは 10.038% です。ツールは 10.037% と出していました
  • 年利 100.005%: 入力した年利そのものの表示が 100% になっていました(正しくは 100.01%)
  • 月利 0.123455%: 複利の月利は入力そのもので、正しくは 0.12346% です。ツールは月利を年利に直してから月利に戻していたので、0.12345% と出していました

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

確かめたこと入力ずれ
年利 0.01〜1000%(0.01刻み)の単利の月利10万通り7,096通り(すべて年利120%以上)
日利 0.01〜1%(0.01刻み)の単利の月利100通り5通り
画面の文字すべて(年利・月利は 0.001刻み、日利は 0.0001刻みほか)1,110,011通り93,040通り

よく使う年利(0.01刻みで100%まで)では起きませんが、小数3桁の利率や、年利120%以上の入力では、表示が1つ小さく出ていました。

どうやって見つかったか

CODE Polyglot の21本目の仕様 利率の変換 を作る前に、元のツールの式を Node で評価して、上の数を確かめました(2026-11-02)。同じ仕様を10言語で書いたよくある書き方も、同じ c005(10言語すべて)と c016(10言語すべて)で落ち、c006 は6言語で落ちました。

原因

  • 1.00025 を2進数の小数で計算すると 1.0002499999999999 になり、toFixed(4) が小さい方に丸めていました(解説)
  • 入力と同じ単位の複利の値を、累乗してから累乗根で戻していたので、0.123455 がわずかに小さくなっていました(解説)

どう直したか

シルギアが2回に分けて直しました。

  1. 1.2.0(2026-11-03・1e147f04e): 計算を calc.js に分け、表示の丸めに補正をかける関数(12桁に整えてから四捨五入)を入れました。これで 93,040通りが 2通り に減りました。残った2通りは、月利 50.172% の複利の年利 13054.29499995…% が 13054.3% になるなど、補正が丸めを2回かけてしまうものでした
  2. 1.2.1(2026-11-04・ced376884): 補正をやめ、値を2つに分けました - 入力そのものと単利の年利・月利・日利(割り算で ちょうど …5 になりうる値)は、入力の文字列から 分数(BigInt)のまま四捨五入する - 複利の値(累乗・累乗根。ちょうど …5 にはならない値)は、補正をかけずに toFixed で1回だけ丸める

確かめたこと

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

入力は次の 1,110,011通り です。

  • 年利 0〜1000%・月利 0〜100%(0.001刻み)
  • 日利 0〜1%(0.0001刻み)
  • 仕様の正解表の入力
  • エラーになる入力

比べたのは、上の大きな表示・説明の行・単利と複利の6つの行・「結果をコピー」の文です。1.2.0 で足された「日割りの利息」と「法律の上限金利と比べる」は、仕様の外なので比べていません。

版不一致
直す前の本番1,110,011通り中 93,040通り
1.2.0(1e147f04e)の本番1,110,011通り中 2通り
1.2.1(ced376884)の本番(2026-11-04。本番の app.js・calc.js がこのコミットと同じことも確認)1,110,011通り中 0通り

← 直した不具合の一覧へ