質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

5回答

3418閲覧

Python3でべき乗計算の結果に誤差がでる

masaru.gotou

総合スコア8

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2021/06/16 14:53

前提・実現したいこと

python3系で、べき乗の計算を正しく行いたいです。
実務上はほぼ問題ないと思われますが、このようなことが起こる理由を知りたいです。
python3系で処理ロジックが変わったのでしょうか。

発生している問題・エラーメッセージ

  • python3系だと、べき乗の計算で誤差が発生します。(0.7**2 = 0.489999..)
  • python2だと、問題ないようです。(0.7**2 = 0.49)

該当のソースコード

  • Python2.7

python

1# python 2Python 2.7.18 (default, Mar 8 2021, 13:02:45) 3[GCC 9.3.0] on linux2 4Type "help", "copyright", "credits" or "license" for more information. 5>>> print(0.7 ** 2) 60.49 7>>> print(pow(0.7,2)) 80.49 9>>> import math 10>>> print(math.pow(0.7,2)) 110.49 12>>> quit()
  • Python3.8

python

1# python3 2Python 3.8.5 (default, May 27 2021, 13:30:53) 3[GCC 9.3.0] on linux 4Type "help", "copyright", "credits" or "license" for more information. 5>>> print(0.7 ** 2) 60.48999999999999994 7>>> print(pow(0.7,2)) 80.48999999999999994 9>>> import math 10>>> print(math.pow(0.7,2)) 110.48999999999999994 12>>> quit()

試したこと

  • 0.7 ** 2, pow(), math.pow()でダメ
  • numpyのpower()でも同じ結果です
  • anacondaの3.7系でも同じ結果です

補足情報(FW/ツールのバージョンなど)

  • python 2.7, 3.8
  • Xubuntu 20.04

どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

Python2で、print(0.7 ** 2 - 0.49)もしくはprint(0.7 ** 2 * 100 - 49)としてみれば、誤差がないわけでは無いということが分かると思います。
単に、表示の際に何桁目を丸めるかの違いでしょう。

2進浮動小数点表現では0.7は誤差無く表現できませんので、演算するごとに誤差が累積して大きくなっていきます。

投稿2021/06/16 15:57

otn

総合スコア84566

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaru.gotou

2021/06/16 21:40

ご回答ありがとうございます。浮動小数点での演算誤差は普通のことでしたね。
otn

2021/06/17 00:22

浮動小数点の計算でも、2進浮動小数点表現で正確に表現できる数(整数や、0.5、0.75等)の和差積は有効桁数を越えない限り正確に計算できます。
guest

0

浮動小数点の計算はそもそも誤差があるものなので、たまたまPython2のときに0.7 ** 2で誤差がなかったのかもしれませんが、色々やってれば必ず誤差が出るはずです。Pythonのバージョンや環境によって微妙に結果が異なります。
Python2のときから誤差がないという仕様ではありません。

投稿2021/06/16 15:13

fukatani

総合スコア626

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaru.gotou

2021/06/16 21:41

ご回答ありがとうございます。printの仕様の問題でしたか・・
guest

0

他の人も言っていますが、

  • 2進数で10進数の小数を計算するのに誤差は避けられません

  • Python2は多分print時に適当に四捨五入されてるだけです

  • 10進数演算ライブラリdecimalを使えば正確な演算ができます

  • ↑以外の解決法としては小数の桁数が有限なら整数にしてから計算するといいです

投稿2021/06/16 21:03

kairi003

総合スコア1330

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaru.gotou

2021/06/16 21:37

まとめていただき、ありがとうございます。
guest

0

ベストアンサー

誤差が発生する理由は他の方が仰る通りです。
誤差が発生しないようにするには、標準ライブラリのdecimalモジュールを使って計算すると良いでしょう。

python3

1>>> from decimal import Decimal 2>>> 3>>> 0.7 ** 2 40.48999999999999994 5>>> 6>>> Decimal("0.7") ** Decimal("2") 7Decimal('0.49')

詳しくは公式ドキュメントを読んでみてください。

投稿2021/06/16 20:41

karintly

総合スコア68

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaru.gotou

2021/06/16 21:39

解決策のご提示ありがとうございます。試したところ、想定の結果になりました。
masaru.gotou

2021/06/16 21:45

JavaなどでもBigDecimalなどの固定小数点計算ができる特別なクラスを用いるようです。 浮動小数点と固定小数点の違いと使い分けに、より具体的に気づかせていただけましたのでベストアンサーとさせていただきます
guest

0

python2 で >>>0.7**2 と入力してみてください。python3 と同じでしょう。

python2 の print は float の桁数を四捨五入して短く表示しているから、
0.49 になっているのでしょう。

>>>print(1.0/7) も試してみてください。

投稿2021/06/16 15:27

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaru.gotou

2021/06/16 21:41

ご回答ありがとうございます。printの仕様の問題でしたか・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問