[過去ログ] Pythonのお勉強 Part68 (1002レス)
1-

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
139
(1): (ワッチョイ 4b17-NGtF) 2022/09/26(月)23:33 ID:Gide+MMY0(2/2) AAS
ほらよ
画像リンク

140
(1): (ワッチョイ d201-/Peb) 2022/09/26(月)23:49 ID:eE4Lst2k0(1) AAS
>>139
それREPLでやってるからinterningが効いてないじゃないかな

>>135
Tupleはimmutableだからaとcが同じオブジェクトを指しても問題なくて
Pythonが最適化をした場合はa is cがTrueになるケースがある
「interning」でググってみて

例えばTupleを関数で返すようにすればinterningされずにFalseになると思う
def foo(x):
 return (x, x+1, x+2)

a = foo(1)
c = foo(1)
141: (ワッチョイ 4212-+bWc) 2022/09/27(火)00:20 ID:LFY5tutJ0(1) AAS
>>140
ありがとうございます、オプティマイゼーションの余地がある、ということですね、納得しました
142: (ワッチョイ 2f97-5djn) 2022/09/27(火)19:02 ID:zjZtbJ3M0(1) AAS
a is cが真になるかはかなりケースバイケースな気がするし、
中身を比較したいんだったら使うべきじゃないね

本当に同じtupleインスタンスかどうかを確認したいときだけにすべき
143: (ワッチョイ 3733-tX/F) 2022/09/27(火)22:33 ID:3OHfLHhN0(1/2) AAS
tupleだけの話ではなくてどの型でも同じだけどね
例えば文字列とか
144
(3): 2022/09/27(火)23:35 ID:tKd9rAjb(1) AAS
n=12345.67

小数点以下が何桁あるのか調べたいのですが
len(str(n).split(".")[1]) if isinstance(n, float) else 0
こんなんでいいですかね・・?
145
(1): (ワッチョイ 3733-tX/F) 2022/09/27(火)23:51 ID:3OHfLHhN0(2/2) AAS
>>144
外部リンク:ideone.com
146
(1): (ワッチョイ 1610-DrlT) 2022/09/27(火)23:53 ID:+joc5Asc0(1) AAS
>>144
誤差で予想外の挙動しそうだからDecimal使う方がいい
147
(1): (ワッチョイ 2701-tX/F) 2022/09/28(水)02:27 ID:OOL0jr8Q0(1/2) AAS
>>144
それだと
n=1.0 -> 1
n=0.00001 -> IndexError
になる

len(format(n,".17f").split(".")[1].rstrip("0"))
後ろのif isinstance(n, float) else 0も不要
n=1.0 -> 0
n=0.00001 -> 5
148: 2022/09/28(水)09:19 ID:9I9ISsCh(1/6) AAS
>>145-147
たしかに
0.30000000000000004に対して17得られたのは正解だと思いますが
0.00001で1e-05になっててエラーでました
Decimalかformat使ってみようと思います
ありがとうございました
149: 2022/09/28(水)10:07 ID:9I9ISsCh(2/6) AAS
やりたかったことは
受けとった1234.56や0.12345などの固定小数点数に
0.1とかを掛けたり足したりして計算、変形したのを
受け取った固定小数点数の整数部と小数部の数を維持したまま
固定小数点か文字列で処理したかったのですが
改めてやってみるとなんか勝手に桁数が変わってしまいますね・・

1234.56で受け取った場合、1.05を掛けたとき→1296.288ではなく1296.29
0.12345で受け取った場合、1.05を掛けたとき→0.1296225ではなく0.12962
1234で受け取った場合、1.05を掛けたとき→1295.7でもいいし1296でもいいし1296.0でもいい
みたいにしたかったのですが難しい・・
150: 2022/09/28(水)10:17 ID:9I9ISsCh(3/6) AAS
from decimal import Decimal
str(Decimal(0.123456))
str(Decimal(0.123456)*Decimal(1.05))
#'0.1296288000000000015945911258'

あれ、そもそも0.123456の小数部の桁数はどうやって知るんだっけ??
てところで詰まってます・・
151: 2022/09/28(水)11:25 ID:9I9ISsCh(4/6) AAS
冗長な気がしますがこんな感じにしてみました
何かバグが発生しそうな気がします
from decimal import Decimal
ary=[1234.5,165,0.34,0.0001,0.000001,3.00001,0.1*3,123456]

def f(n):
 s=format(n)
 return int(s.split("-")[1]) if "-" in s else len(s.split(".")[1].rstrip("0")) if "." in s else 0

r=1.05
for n in ary:
 d=f(n)
 c=Decimal(n)*Decimal(r)
 rs=c.quantize(Decimal("0."+("0"*d)))
 print(n,c,d)
 print("-->",rs,"\n")
152
(1): 2022/09/28(水)11:30 ID:9I9ISsCh(5/6) AAS
連投すみません 結果です
外部リンク:ideone.com
153: (ワンミングク MM42-nX9g) 2022/09/28(水)13:38 ID:E42G0/DqM(1) AAS
元々の桁数でroundしたいって感じなのかな
154
(2): (ワッチョイ 2701-tX/F) 2022/09/28(水)18:25 ID:OOL0jr8Q0(2/2) AAS
>>152
format使うの提案したけど使わないほうがよさそう、誤差がでる

f(n): 負数で落ちる
s=str(n).lstrip("-")

c=Decimal(n*r) のところで
n*r で誤差がでる
c=Decimal(str(n)) * Decimal(str(r))

負数対応四捨五入 -0.015 を四捨五入して -0.02
rs=((c > 0) - (c < 0)) * abs(c).quantize(Decimal("0."+("0"*d)), rounding=ROUND_HALF_UP)

-0.015 を四捨五入して -0.01のようにしたい場合
rs=c.quantize(Decimal("0."+("0"*d)), rounding=ROUND_HALF_UP)

四捨五入したいのかよくわからんかった、roundingは好みのオプションでどうぞ
155: 2022/09/28(水)19:37 ID:9I9ISsCh(6/6) AAS
>>154
ありがとうございます
やはり至るところで誤差が発生するのですね
四捨五入は今回の用途ではどちらでも良い感じです
せっかくなのでまとめてみました
外部リンク:ideone.com
ありがとうございました
156: (ワッチョイ 96bb-nd6Q) 2022/09/28(水)19:42 ID:o0cHd3Tq0(1) AAS
先にIEEE754読んでみては?
誤差に関しての勘所がわかるようになる
157: (ワッチョイ 2f97-5djn) 2022/09/28(水)20:32 ID:x5UMfEp40(1) AAS
Pythonに限らず浮動小数点数を使う場合は常に誤差の問題がつきまとう。
0.1というのがすでに二進数ではきっちり表現できない数字なので、有効数字を何桁にするのかというのは実装の段階で決めなくちゃならない。

外部リンク[html]:docs.python.org

正確に表現できるのは、0.5,0.25,0.125...と1を2で割っていった数とその整数倍のみ

0.1は1/(2×5)となり1/5が2進数では循環小数となり浮動小数点数では正確に表せない。

ということを念頭に置いてまず何がやりたいか考えた方がいいよ。

decimalモジュールは便利そうだね。
158: (ワッチョイ 23da-QqKk) 2022/09/28(水)23:21 ID:FDPwu/KN0(1) AAS
log2で有効桁数計算出来るでしょ
159: (ワッチョイ 2701-tX/F) 2022/09/29(木)00:26 ID:3C3gpnCY0(1) AAS
>>154
どちらの書き方でも
-0.015 を四捨五入したら-0.02だった、すまん
-0.01にしたい場合は自力でなんとかして
160
(6): (ワッチョイ 9202-XjGR) 2022/09/30(金)00:55 ID:qun5+YRs0(1) AAS
昔から不思議なんだけど
何で分数で処理しないのかな?
最後に割り算を一回だけすれば
誤差がでないじゃないの
161
(1): (ガックシ 06de-TTgm) 2022/09/30(金)01:46 ID:0IYvIpx66(1) AAS
掛け算でも足し算でも誤差が出るから
162: (ワッチョイ b302-nX9g) 2022/09/30(金)01:53 ID:sForoGQI0(1) AAS
Pythonは整数側の桁数制限が無いのを利用して高精度にできそう
163: (アウアウウー Sa43-hb2l) 2022/09/30(金)02:07 ID:f+ZVHjVVa(1) AAS
>>160
似たような大きさの数字ならその発想もいいけどね
現実はコスパの悪い任意精度の演算が必要になることが多いのでは
164: (ワッチョイ 23da-QqKk) 2022/09/30(金)03:11 ID:FkDRVgM50(1) AAS
>>160
つ fractions
165: (ワッチョイ 96bb-nd6Q) 2022/09/30(金)04:56 ID:HxNT59pn0(1) AAS
だから誤差の話するならIEEE754読めよ
166: (ワッチョイ f390-UZRN) 2022/09/30(金)04:57 ID:CfDFJOy00(1) AAS
>>160
昔GCD付きの分数クラス作ったけど
結局はdoubleになったことがある
167: (ワッチョイ 1201-ut7I) 2022/09/30(金)05:21 ID:oHn8O8ll0(1/4) AAS
>>160
四則演算だけならいいけど√とかsin( )とかはどうする?

>>161
掛け算、足し算で誤差がでるケースとは?
168
(1): (ワッチョイ 1e66-yYUR) 2022/09/30(金)08:01 ID:Gm4+1fgX0(1/3) AAS
sinとかも内部は四則演算
1-
あと 834 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ

ぬこの手 ぬこTOP 0.012s