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

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

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

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

Q&A

解決済

3回答

531閲覧

浮動小数点数の計算の処理に困っています。

uragirionigiri

総合スコア8

Python

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

0グッド

0クリップ

投稿2023/05/18 09:18

実現したいこと

以下のようなコードの場合の少数の処理をどのように行うべきか知りたいです。

発生している問題・エラーメッセージ

入力例
10
1 1 10
10

出力結果
#1.0 0.1
#1.0 0.2
#1.0 0.30000000000000004
#...   
#10.0 9.99999999999998
USAGI

本来であればUSAGIのところに
DRAWを表示させたいのですが少数がずれていってしまうため出力が異なってしまいます。
この問題が浮動小数点数は、有限のビット数で実数を表現するため、厳密な値を表現することができないためであるということはなんとなく分かったのですが、実際にどのように少数の処理を行えばいいのか分からず困っています。

該当のソースコード

python

1G = int(input()) 2 3u,a,b = map(int,input().split()) 4 5k = int(input()) 6 7usagi = 0 8kame = 0 9 10usagi_kyori = 0 11usagi_rest = 0 12 13 14while True: 15 if usagi >= G and kame >= G: 16 print("DRAW") 17 break 18 elif usagi >= G > kame: 19 print("USAGI") 20 break 21 elif kame >= G > usagi: 22 print("KAME") 23 break 24 else: 25 26 kame += 1 / k 27 28 if usagi_rest == 0: 29 usagi += 1 / u 30 usagi_kyori += 1 / u 31 32 if a <= usagi_kyori: 33 usagi_rest = b 34 usagi_kyori = 0 35 else: 36 usagi_rest -= 1 37 38 print(usagi,kame) #今回起きている問題を明確にするための文です。(本来は不要)

試したこと

def my_round(val, digit=0):
p = 10 ** digit
return (val * p * 2 + 1) // 2 / p

こういった自作関数で処理しようとしたのですが、よく分からずうまくいきませんでした。

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

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

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

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

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

tatsu99

2023/05/18 23:27

入力例の 10 1 1 10 10 は、どのような数字なのでしょうか。 そして、その場合、どのような結果が出力されることを期待しているのでしょうか。
uragirionigiri

2023/05/19 00:20

説明が不足しており、申し訳ないです。 1行目はゴールまでの距離G(10キロ) 2行目はうさぎが1キロを走る時間u(分)、またaキロを走る毎にb分の休憩をとることを表します。 3行目はかめが1キロを走る時間k(分) 出力としては先にゴールしたほうを出力しますが同着の場合はDRAWとします。 今回はこのDRAWの場合の入力値想定していますが、1分毎に進む距離を計算していくとズレが発生してしまうというところが問題となっています。
tatsu99

2023/05/19 02:09 編集

これは、浮動小数点で行うには、無理があります。 あなたのアルゴリズムをそのまま、採用する場合は、正確な値を保持するために、 分数形式で変数を保持する必要があります。 例 2/11 を11回加算して、2になることを期待するような場合です。 このようなケースでは、有理数型の値で変数を保持します。 https://python.atelierkobato.com/fraction/ https://docs.python.org/ja/3/library/fractions.html 回答欄に有理数型を使用した方法を書きます。
guest

回答3

0

直接ゴールに達するまでの時間を算出する方法です。
亀の場合、1Kmにつきk分なので、G×k分 かかる。
うさぎの場合、1Kmにつきu分 かかり、aKmにつきb分休憩なので、
aKm進むにはa×u+b 分かかる、但し、ゴールがaKmで割り切れるなら最後の休憩は不要になる。
よって、
G÷aの余りが0の場合は、(G÷aの商-1)×(au+b) + au 分かかる。
G÷a余りが0でない場合は、(G÷aの商)×(a*u+b)+(G÷aの余り)×u 分かかる。
上記をコードにすると以下のようになります。

python3

1G = int(input()) 2 3u,a,b = map(int,input().split()) 4 5k = int(input()) 6 7usagi = 0 8kame = 0 9 10usagi_kyori = 0 11usagi_rest = 0 12 13kame = G * k 14remain = G % a 15if remain == 0: 16 usagi = ((G//a) -1 ) * (a*u + b) + a*u 17else: 18 usagi = (G//a) * (a*u + b) + remain*u 19 20print("usagi=",usagi,"kame=",kame,"remain=",remain) #参考用 21 22if kame == usagi: 23 print("DRAW") 24elif usagi > kame: 25 print("USAGI") 26else: 27 print("KAME") 28 29

実行結果
10
1 1 10
10
usagi= 100 kame= 100 remain= 0
DRAW

投稿2023/05/19 02:38

編集2023/05/19 03:00
tatsu99

総合スコア5438

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

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

0

ベストアンサー

有理数型を使用した方法です。
アルゴリズムはあなたの提示された方法をそのまま使っています。

pyhton3

1# Fraction クラスをインポート 2from fractions import Fraction 3 4G = int(input()) 5 6u,a,b = map(int,input().split()) 7 8k = int(input()) 9 10usagi = Fraction(0) 11kame = Fraction(0) 12 13usagi_kyori = Fraction(0) 14usagi_rest = Fraction(0) 15 16 17while True: 18 if usagi >= G and kame >= G: 19 print("DRAW") 20 break 21 elif usagi >= G > kame: 22 print("USAGI") 23 break 24 elif kame >= G > usagi: 25 print("KAME") 26 break 27 else: 28 29 kame += Fraction(1,k) 30 31 if usagi_rest == 0: 32 usagi += Fraction(1,u) 33 usagi_kyori += Fraction(1,u) 34 35 if a <= usagi_kyori: 36 usagi_rest = Fraction(b) 37 usagi_kyori = Fraction(0) 38 else: 39 usagi_rest -= Fraction(1) 40 41 print(usagi,kame) #今回起きている問題を明確にするための文です。(本来は不要) 42 43 44

実行結果
10
1 1 10
10

1 1/10
1 1/5
1 3/10
1 2/5
1 1/2
1 3/5
1 7/10
1 4/5
1 9/10
1 1
1 11/10
2 6/5
2 13/10
2 7/5
2 3/2
2 8/5
2 17/10
2 9/5
2 19/10
2 2
2 21/10
2 11/5
3 23/10
3 12/5
3 5/2
3 13/5
3 27/10
3 14/5
3 29/10
3 3
3 31/10
3 16/5
3 33/10
4 17/5
4 7/2
4 18/5
4 37/10
4 19/5
4 39/10
4 4
4 41/10
4 21/5
4 43/10
4 22/5
5 9/2
5 23/5
5 47/10
5 24/5
5 49/10
5 5
5 51/10
5 26/5
5 53/10
5 27/5
5 11/2
6 28/5
6 57/10
6 29/5
6 59/10
6 6
6 61/10
6 31/5
6 63/10
6 32/5
6 13/2
6 33/5
7 67/10
7 34/5
7 69/10
7 7
7 71/10
7 36/5
7 73/10
7 37/5
7 15/2
7 38/5
7 77/10
8 39/5
8 79/10
8 8
8 81/10
8 41/5
8 83/10
8 42/5
8 17/2
8 43/5
8 87/10
8 44/5
9 89/10
9 9
9 91/10
9 46/5
9 93/10
9 47/5
9 19/2
9 48/5
9 97/10
9 49/5
9 99/10
10 10
DRAW

投稿2023/05/19 01:51

tatsu99

総合スコア5438

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

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

tatsu99

2023/05/19 01:56

有理数型を使わない場合は、1分ごとに進んだ距離を算出するのではなく、 直接、ゴールに達するまでの所要時間を計算し、その時間を比較して、どちらが勝ったかの判定をする方法があります。 その方法がに興味があれば、その旨、補足してください。
uragirionigiri

2023/05/19 02:12

いろいろとご丁寧にありがとうございます。 もしよろしかったらその方法も教えていただけると勉強になります。
tatsu99

2023/05/19 02:39

回答欄にかきました。
guest

0

小数点一位までの出力でいいなら、数値を10倍して整数演算させ、出力の際に1/10すれば、あなたのお望みのように出力することができます

投稿2023/05/18 10:38

y_waiwai

総合スコア87749

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問