ExcelのROUNDと同じ結果を求める – 2進浮動小数点数近似による誤差

Excel ROUND function in Javascript – StackOverflow

Excelもプログラミング言語も違いはない。
あくまで表記上の問題であって、内部精度の問題ではないし、
別にExcelでも他の言語でもIEEE754に準拠していれば同じ。
あくまで、表現の問題(だと思う)。

手元にExcelがないので、Googleスプレッドシートで試すと、
「0.3/12」は「0.25」になる。本来、0.3は循環小数になるので、
2進数でそのまま表現しようとすると0.024999999999999998になる。
これは、単に

0.3/12, round(0.3/12, 15)
(0.024999999999999998, 0.025)

という違い。

なので、スプレッドシートと同じ実装を考えるのであれば、

round(round(0.3/12, 15), 2)
0.03

になる。

で、誤差云々以前に、普通は有効数字を考えるので、
四捨五入する桁数は有効けたである事が仮定される場合、

import math


def rounding(x, dt=0.01):
    n = math.log10(dt)
    y = x * 10**(-n)
    y = int(y+0.5 if y>0 else y-0.5)
    return y * 10**n


rounding(0.3/12)
0.03

とできる。

で、より高精度が求められる、厳密な等価性テストの要求があった場合に、
十進数を正確に表現するためのdecimalモジュールが(大体の言語に)ある。
pythonの場合,decimalモジュールを用いると,任意精度で浮動小数点数を扱う事ができる.
(スプレッドシートで等価的にやろうと思うとどうやるのかは分からない)

from decimal import Decimal, ROUND_HALF_UP


(Decimal('0.3') / 12).quantize(Decimal('.01'), rounding=ROUND_HALF_UP)
Decimal('0.03')

 
 
関連:
三角関数(sin)の精度 – 任意精度演算

Pythonのビット演算が遅いのは任意精度だから?

numpyで任意精度演算

広告
カテゴリー: 未分類 パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください