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

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

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

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

Python

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

Q&A

解決済

1回答

1137閲覧

Pythonの小数計算について

Charowan

総合スコア17

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2020/08/09 15:02

#AtcoderのGrand Contest(8月9日開催)のA問題について
問題)
N個の実数A1,A2,...ANが与えられます。添字のペア(i,j)(i<j)であって、積Ai,Ajが整数であるようなものの個数を求めてください。
#入力

Python

1N 2A1 3A2 4. 5. 6. 7AN

#例

Python

1#入力 211 30.9 41 51 61.25 72.30000 85 970 100.000000001 119999.999999999 120.999999999 131.000000001 14#出力 158

これに対しての私のコードはこれです。

Python

1from decimal import Decimal 2n=int(input()) 3A=[float(input()) for _ in range(n)] 4multiple=[] 5for i in range(1,n): 6 for j in range(n-i): 7 ans=Decimal(A[i-1])*Decimal(A[i+j]) 8 if float(ans).is_integer(): 9 multiple.append(ans) 10print(len(multiple))

このコードを例をテストケースにして実行すると9になってしまいます。どのようにすればいいでしょうか?小数の積の問題なのでしょうか?
また実行時間超過については十分承知です。」実行時間をこのコードを改造して短くすにはどうすればよいでしょうか?

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

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

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

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

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

tiitoi

2020/08/09 15:23

問題の URL を追記できますか?
guest

回答1

0

ベストアンサー

動かしたところ、0.999999999 * 1.000000001を整数と判断していました。
この手の挙動はfloatが怪しいです。floatを使わないようにすれば治りそう。

  1. inputは文字列として受け取ってDecimalにキャストする
  2. 整数判定はDecimalの機能(Inexact)で判定する

Charowanさんのコードに↓のようにちょっと手を入れたら私の環境では8になりました。

python

1from decimal import Decimal, Inexact 2from decimal import localcontext 3 4# いちいちinputを打つのが面倒臭いのでハードコーディング 5n=11 6target=[ 7 "0.9", 8 "1", 9 "1", 10 "1.25", 11 "2.30000", 12 "5", 13 "70", 14 "0.000000001", 15 "9999.999999999", 16 "0.999999999", 17 "1.000000001", 18] 19A=[Decimal(x) for x in target] 20count=0 21for i in range(1,n): 22 for j in range(n-i): 23 with localcontext() as ctx: 24 ans=A[i-1]*A[i+j] 25 ans.to_integral_exact() 26 count += 1 if not ctx.flags[Inexact] else 0 27print(count)

投稿2020/08/09 16:42

Thrush

総合スコア58

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

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

Charowan

2020/08/10 03:21

回答ありがとうございます。 localcontext() とctx.flags[Inexact]はどのような役割なのでしょうか?
Thrush

2020/08/10 08:52

localcontext()はDecimalを使った直前の計算についての情報(桁溢れがあった、0割だった、など)を取得する関数です https://docs.python.org/ja/3/library/decimal.html#decimal.localcontext ctx.flags[Inexact]はlocalcontext()で取得した情報のうち、Inexact(=値の丸め込みがあったかどうか)のフラグを参照しています https://docs.python.org/ja/3/library/decimal.html#decimal.Inexact したがって、以下のようなロジックになります * A[i-1]*A[i+j]を掛け算し、結果をansとする * ansを整数に変換する(=to_integral_exact()) * 整数の変換で値の丸め込みがなければcountに+1する
Charowan

2020/08/13 06:45

分かりやすい解説有難うございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問