pythonにて計算を行う際に本来の答えと違うであろう答えが出てくるのですが原因を教えていただきたいです。
1.print(.3*3)を実行した際
0.8999999999999999
この様に出力されます。
2.print(.4*3)を実行した際
1.2000000000000002
この様に出力されます
3print("3"+3)を実行した際
Traceback (most recent call last):
File "ex2-1.py", line 1, in <module>
print("3"+3)
TypeError: can only concatenate str (not "int") to str
この様なエラーが出ます。
1.2は同様なものだと思います。又。3に関してはエラーの意味を教えていただけると幸いです。
以下のような質問にはグッドを送りましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
下記のような質問は推奨されていません。
- 間違っている
- 質問になっていない投稿
- スパムや攻撃的な表現を用いた投稿
適切な質問に修正を依頼しましょう。
回答2件
4
ベストアンサー
Pythonの実数は有限桁の2進数の浮動小数点数で表されます。
2進小数というのは2のn乗の和で数を保持する発想で
例えば1.625は1+0.5+0.125=2^0 + 2^(-1) + 2^(-3)です。
0.3や0.4は2進小数で無限桁になってしまうので、有限桁に打ち切ります。
それにより質問文のような誤差が発生します。
15. 浮動小数点演算、その問題と制限 — Python 3.10.6 ドキュメント
TypeError: can only concatenate str (not "int") to str
「str
はstr
(int
ではなく)としか結合できません」
つまり文字列型は文字列型としか結合できないと言っています。
文字列の結合とは次のような処理です。
python
1print("123"+"456") # 123456
投稿2022/10/11 07:23
総合スコア13084
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
2
本質的な解答はozwkさんのものを参照してください.余談までに誤差を抑える方法を示しておきます.
1. 分数を定義して計算する
分母も分子も整数で表現できる場合,自分で分数Fraction
を定義して整数のまま四則演算を行うことで誤差を抑えることができます.手打ちで小数を入力できるということは,10進数で有限桁の小数のはずなので,分母分子共に整数にすることができるはずです.上の例では0.3
を3/10
のようにできます.
Python
1class Fraction: 2 def __init__(self, x: int, y: int): 3 """ 4 Parameters 5 ---------- 6 x : int 7 numerator(top) 8 y : int 9 denominator(bottom) 10 """ 11 gcd = self.__gcd(x, y) 12 self.n = x // gcd 13 self.d = y // gcd 14 15 def __gcd(self, x, y): 16 while y > 0: 17 x, y = y, x % y 18 return x 19 20 def __add__(self, other): 21 return Fraction( 22 self.n * other.d + self.d * other.n, 23 self.d * other.d 24 ) 25 26 def __sub__(self, other): 27 return Fraction( 28 self.n * other.d - self.d * other.n, 29 self.d * other.d 30 ) 31 32 def __mul__(self, other): 33 return Fraction( 34 self.n * other.n, 35 self.d * other.d 36 ) 37 38 def __floordiv__(self, other): 39 return Fraction( 40 self.n * other.d, 41 self.d * other.n 42 ) 43 44 def __truediv__(self, other): 45 return float(self // other) 46 47 def __str__(self): 48 return f"{self.n}/{self.d}" 49 50 def __repr__(self): 51 return f"Fraction({self.n}, {self.d})" 52 53 def __float__(self): 54 return self.n / self.d 55 56def show_product(r1: Fraction, r2: Fraction): 57 print(f"{r1} * {r2} = {r1 * r2} \t decimals: {float(r1 * r2)}") 58 59if __name__ == "__main__": 60 show_product( 61 Fraction(3, 10), # 3/10 -> 0.3 62 Fraction(3, 1) # 3/1 -> 3 63 ) 64 65 show_product( 66 Fraction(4, 10), # 4/10 -> 0.4 67 Fraction(3, 1) # 3/1 -> 3 68 )
shell:標準出力
13/10 * 3/1 = 9/10 decimals: 0.9 22/5 * 3/1 = 6/5 decimals: 1.2
2. Decimalを使う
標準ライブラリdecimalを使う.詳細はリンクを読んでください.
Python
1from decimal import Decimal 2 3def show_product(r1: Decimal, r2: Decimal): 4 print(f"{r1} * {r2} = {r1 * r2}") 5 6if __name__ == "__main__": 7 show_product(Decimal("0.3"), Decimal("3")) 8 show_product(Decimal("0.4"), Decimal("3"))
shell:標準出力
10.3 * 3 = 0.9 20.4 * 3 = 1.2
TypeErrorの回避方法
TypeError: can only concatenate str (not "int") to str
を回避するために,次のようにしても良いでしょう.
Python
1print(int("3")+3)
int()
関数に与えられた文字列が,整数と解釈できる場合には整数に変換してくれます.よって少数であるような文字列".3"
などをint(".3")
として使うとエラーになります.この場合は浮動小数点数として解釈できるのでfloat()
関数を使ってfloat(".3")
を実行することができます.
投稿2022/10/11 08:03
編集2022/10/11 08:54総合スコア1066
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
関連した質問
意見交換
受付中
Pythonの将来や動向について
回答6
クリップ0
更新
2023/02/07
Q&A
解決済
5回、自然数を入力し、その中で最小値と最大値を除いた合計値を出力するプログラム
回答4
クリップ0
更新
2023/02/07
Q&A
解決済
大量のテキストファイルを読み込んで、その数だけ変数を作ってそれに入れる方法
回答4
クリップ0
更新
2023/02/07
Q&A
解決済
while構文を使う際のbreakの位置と使い方
回答1
クリップ0
更新
2023/02/04
意見交換
受付中
Python:データフレームを列ごとにプロット
回答4
クリップ0
更新
2023/02/02
Q&A
解決済
unrecognized tokenの解決方法
回答2
クリップ0
更新
2023/02/06
Q&A
解決済
PythonのSessionRequestへ渡すquery(json)のvalueの一部を変数で渡したいが実現できない
回答3
クリップ0
更新
2023/02/04
Q&A
受付中
PythonのValueErrorに関しまして
回答1
クリップ0
更新
2023/02/06
同じタグがついた質問を見る
Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。