「なでしこv1」開発掲示板

なでしこv1のバグや要望を書き込む掲示板
[一覧へ] > (@596) [低] [感謝]
@596■ (#1906) INT()関数の計算誤差 - 奈良の鹿 (2011-03-01 16:51) /高 未処理
【症状】INT()関数の計算誤差


【再現方法】
//-------------------------------------------
//整数化を行った場合。※誤差発生※

INT(100*1.05)を表示   //結果 104

//-------------------------------------------

(100*1.05)の整数部分を表示   //結果 104

(100*1.05)の小数部分を表示   //結果   1

//-------------------------------------------
ひまわりでは正しく計算されました。
     
INT(100*1.05)を、表示。      //結果 105

//-------------------------------------------

#質問する板に投稿した内容とほぼ同じです。
#詳細は、2011-02-02 消費税(税込)の計算誤差について


【要望】どのような解決が望ましいか?


【バージョン】確認したバージョン
---------------------------------------
日本語プログラミング言語「なでしこ」
---------------------------------------
バージョン:1.5332
最終更新日:2011/02/28
OS   :Windows XP [5.1(2600:2)]
---------------------------------------


【その他】
INT()は、基本的な関数なので、誤差の発生を疑うことはありません。
特定のバージョン以降の現象となれば、集計結果の間違いに気づき、
原因を突き止めるのも大変でしょう。

実務上、消費税の計算に使用している場合を考えると、速やかな対応が必要だと思います。




(#1908) (Delphi の)浮動小数点数の問題なのでどうしようもない - U D (2011-03-08 01:36) /低 未処理
元スレはこちらですね:
 http://nade.jp-pro.net/bbs/bbs1/mbbs.php?m=thread&threadid=16


この問題は浮動小数点数全般に起こることなので、どうしようもありませんね。
(元スレでも VB の場合について言及されていますが、他の言語でも同様の例を作ろうと思えば作れると思います)

内部的には Delphi の Extended をずっと使っているので、
特定バージョン以降に限るバグということでもありません。
もっと言うと Delphi でも Extended 型を Trunc すると同様のことが起こります。

確かに *1.05 という計算においては誤差が下側に出る割合が他の言語と比べて多い気がしますが、
だからと言ってこの現象がバグだという訳ではありません。
この計算では Double で誤差が上に出て Extended で誤差が下に出やすいだけのような気がします。
数値型の浮動小数点の精度には倍精度(Double)を採用する言語が多く、
一方なでしこ(Delphi)では Extended を採用しているためこの差が出る、と。
Extended の方が精度が良いので、当然、計算誤差そのものは Extended の方が小さいハズです。


元スレで既に解決していますが、一応こういう場合のより一般的な対処方法も紹介しておきます。
(a) 浮動小数点計算を可能な限り避ける: 1900*105/100
(b) (小数点以下で)四捨五入する: 1900*1.05を60で小数点四捨五入
(c) 固定小数点型 / 有理数で計算する。
  (なでしこにはどちらもないので自前で実装しない限りこの方法は使えません)



(#1909) ありがとうございました。 - 奈良の鹿 (2011-03-09 11:48) /低 感謝
詳細にわたり丁寧な回答ありがとうございます。


開発の場からすると、計算誤差はDelphiの言語仕様に負う部分が多く、容易に解決をみない問題なので、
不本意ではあるが放置してあるという、内容ですね。

的はずれな考えかもしれませんが、なでしこの前身である「ひまわり」では正しく計算されるのに、
どうして、「なでしこ」では発生するのかも気になっていました。


なでしこが対象にしているユーザー層を思うと、このような計算誤差が容易に発生することが残念でなりません。

なでしこ2では、(a)のように自然と浮動小数点計算を避けるような関数仕様になっていると素晴らしいですね。


感謝・感謝




(#1906)へ返信する:

👆お手数ですが、いたずら防止のために、「真夏」の読み方を記入してください。

編集時に使うキーを入力(省略可能)

画像ファイル(最大300KB)を添付可能