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

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

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

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

Q&A

解決済

3回答

543閲覧

Pythonで計算する時に出てくる端数について

Shousuke

総合スコア1

Python

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

0グッド

0クリップ

投稿2020/05/03 14:47

Python超初心者です。

円の面積を計算するコードを書いていたら、
mathからpiを使って半径10の円の面積をhalf_diameter * half_diameter * math.piで計算すると、314.1592653589793と表示されるのに、直接、10103.1415と入れるような場合だと314.15ではなく、314.15000000000003と不思議な端数がついた結果が返ってきます。これはどうしてでしょうか?くだらない質問で恐縮ですが、教えていただければ幸いです。

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

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

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

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

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

guest

回答3

0

Python

1from struct import pack, unpack 2 3def show(x): 4 b = unpack('>Q', pack('>d', x))[0] 5 print(f" {#b:x} {x}") 6 print('-' * 10) 7 b -= 4 8 for i in range(8): 9 d = unpack('>d', pack('>Q', b))[0] 10 print(f" {b:#x} {d:.20f}") 11 b += 1 12 print('=' * 10) 13 14p = 3.1415 15show(p) 16show(10 * 10 * p);

実行結果

0x400921cac083126f 3.1415 ---------- 0x400921cac083126b 3.14149999999999840483 0x400921cac083126c 3.14149999999999884892 0x400921cac083126d 3.14149999999999929301 0x400921cac083126e 3.14149999999999973710 0x400921cac083126f 3.14150000000000018119 0x400921cac0831270 3.14150000000000062528 0x400921cac0831271 3.14150000000000106937 0x400921cac0831272 3.14150000000000151346 ========== 0x4073a26666666667 314.15000000000003 ---------- 0x4073a26666666663 314.14999999999980673238 0x4073a26666666664 314.14999999999986357579 0x4073a26666666665 314.14999999999992041921 0x4073a26666666666 314.14999999999997726263 0x4073a26666666667 314.15000000000003410605 0x4073a26666666668 314.15000000000009094947 0x4073a26666666669 314.15000000000014779289 0x4073a2666666666a 314.15000000000020463631 ==========

これから分かることは、3.1415 は 2進で正確に表現できず
0x400921cac083126e 3.14149999999999973710
0x400921cac083126f 3.14150000000000018119
の 2つのうち、値の近い 0x400921cac083126f というビットパターンになります。
これは 3.1415 より少し大きめの値です。

これを 100倍すると、0x4073a26666666667 になり
314.15000000000003 と表示されているようです。

投稿2020/05/04 08:07

kazuma-s

総合スコア8224

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

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

Shousuke

2020/05/04 09:07

私の能力ではコードを理解することはできませんが、おっしゃることは、なるほどという感じがします。ありがとうございました!気になるのは、もし数桁の小数でも2進で正確に表現できないことがよくあるなら、プログラムあるいはコンピューターでの計算というもの自体に誤差を伴うことがよくあるということでしょうか。それって色んな状況で大丈夫なことなのか気になります。
guest

0

PI の本当の値をしっていますか?
3.1415, math.pi もどちらの正確な値ではないです。
(そもそも 10 進数で正確な値を表記することもできません)

print(math,pi) を試してみてください。

投稿2020/05/03 21:29

katoy

総合スコア22324

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

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

Shousuke

2020/05/04 09:13

ありがとうございます。試したら、3.141592653589793とでました。これのちょうど100倍が出ているので、こちらはある意味3.1415の100倍より正確(?)でたまたま誤差(本来のπとはもちろん誤差があるのでしょうが)がないようなものでしょうか。
guest

0

ベストアンサー

コンピュータの中では、小数点付きの数値は2進数で表現されます。
ところが、ニンゲンが使おうとする数値は10進数で表現しようとします
この2進数と10進数の変換のときに誤差が入ります。

簡単に言うと、0.1という数値は2進数では表現できません(誤差が出る)

投稿2020/05/03 14:59

y_waiwai

総合スコア88042

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

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

Shousuke

2020/05/03 15:06

ありがとうございます。では、piの方の結果にも同様の誤差がはいっているのでしょうか。
y_waiwai

2020/05/03 15:08

そういうことですね 「浮動小数点数 誤差」でぐぐると詳しい解説が出てきます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問