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に関してはエラーの意味を教えていただけると幸いです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答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
総合スコア13553
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
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総合スコア1581
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。