61909


`python3系`で除算をしたあとの整数への変換にいつも`int()`を使っていましたが、AtCoderの他の人の回答を見ると`//`を使用していました。

[code]

    a = 3 / 2
    print(int(a)) # 今までのやり方
    
    a = 3 // 2
    print(a)      # 正しいやり方（？）
    
[/code]

確かにAtCoderでも`int()`を使うと間違いと判定され、`//`に変えてみたところ正解になった問題がありました。

自分では違いが全くわかっていませんが、全然違うものなのでしょうか？

追記：質問の仕方が悪かったので補足します。  
`int()`を使う場合と`//`を使う場合出力される結果は同じになると思いますが、AtCoderでコードを提出したところ`int()`で整数に変換したものは間違いと判定されてしまいました。  
`//`で最初から整数値のみを算出したものは正解と判定されたので不思議と思って質問しました。

それぞれの意味はおおまかには理解していますが、結果が変わる場合があることは認識していませんでした。  
違う結果が出力される場合はどのようなときなのでしょうか？

参考までにそれぞれのコードを貼っておきます。

[code]

    # 間違いと判定されたコード
    n, a, b = map(int, input().split())
    if (b - a) % 2 == 0:
        ans = (b-a)/2
    else:
        ans = min(a-1, n-b) + 1 + (b-a-1)/2
    print(int(ans))
    
[/code]

[code]

    # 正解と判定されたコード
    n, a, b = map(int, input().split())
    if (b - a) % 2 == 0:
        ans = (b-a)//2
    else:
        ans = min(a-1, n-b) + 1 + (b-a-1)//2
    print(ans)
    
[/code]

上記のお題はAtCoderの「AtCoder Grand Contest 041」のA「Table Tennis Training」です。


CC BY-SA 4.0
2019-12-30T18:08:20.850
61899
2019-12-31T03:08:08.373
2019-12-31T02:21:13.460
35942
35942
question
python python3
この２つのコードのどこが異なるのか教えて下さい。


`/`と`//`はともに除算の演算子ですが、計算方法が異なります。

`3 / 2`の結果はfloat(浮動小数点数)です。

[code]

    >>> type(3 / 2)
    <class 'float'>
    
[/code]

`3 // 2`の結果はint(整数)です。

[code]

    >>> type(3 // 2)
    <class 'int'>
    
[/code]

> a = 3 / 2  
>  print(int(a)) # 今までのやり方

この方法はfloatで演算した結果をintに変換しています。

> a = 3 // 2  
>  print(a) # 正しいやり方（？）

この方法ではintのまま演算しています。

どちらの方法も間違ってはいるわけではありませんが、除算結果を切り捨てるときは`//`を使うのがよいです。


CC BY-SA 4.0
2019-12-30T23:01:04.370
61901
2019-12-30T23:01:04.370
35558
61899
answer


正しいか間違っているかは、その問題に書かれた答えるための条件によるでしょう。  
問題の内容が提示されておらず、単なる2行のコーディングを示されただけでは、推測は付きますが判断は出来ません。

まあ引っ掛け問題かもしれませんけど、「答えを整数で求めて表示せよ」みたいな感じで出されていて、結果を格納する変数の値や属性まで整数でなければならないとか、そういう解釈になっている可能性が考えられます。

つまり表示される結果は`1`で同じですが、変数`a`の値としては上は`浮動小数点数`の`1.5`で、下は`整数`の`1`です。

この辺の、細かく見て対応しなければならないような「条件」が問題に記述されていたのではありませんか？

ちなみに`Python 演算子 //`で検索すると、以下のような記事が見つかるので、単純な違いならそうしたことで調べられます。  
[6.7. 二項算術演算 (binary arithmetic
operation)](https://docs.python.org/ja/3/reference/expressions.html#binary-
arithmetic-operations)

> `/`(除算: division) および`//`(切り捨て除算: floor division)
> は、引数同士の商を与えます。数値引数はまず共通の型に変換されます。整数の除算結果は浮動小数点になりますが、整数の切り捨て除算結果は整数になります;
> この場合、結果は数学的な除算に 'floor' 関数
> を適用したものになります。ゼロによる除算を行うと[ZeroDivisionError](https://docs.python.org/ja/3/library/exceptions.html#ZeroDivisionError)例外を送出します。

[算術演算子 - Python入門 Pythonの演算子まとめ
(1/2)](https://www.atmarkit.co.jp/ait/articles/1907/23/news010.html#arithmeticop)

> / 除算 1 / 5→0.2（整数同士の除算。結果は浮動小数点数となる）  
>  1.0 / 5.0→0.2（浮動小数点数同士の除算。結果は浮動小数点数となる）
>
> // 整数除算 5 // 2→2（「5÷2」の商が求まる。結果は整数となる）  
>  （切り捨て除算） 1.7 // 0.6→2.0（「1.7÷0.6」の商が求まる。「1.7＝0.6×2.0＋0.5」なので、  
>  その商である「2.0」が得られる。結果は浮動小数点数となる）  
>  3.14 // 3→1.0（浮動小数点数と整数の切り捨て除算。  
>  結果は浮動小数点数となる）

[Pythonの演算子の一覧表とわかりやすい解説](https://www.headboost.jp/python-operators/)

> 1.1. 数値演算子一覧  
>  / a/b 割り算  
>  // a//b aをbで割った商の整数値


CC BY-SA 4.0
2019-12-30T23:03:00.257
61902
2019-12-30T23:10:07.220
2019-12-30T23:10:07.220
26370
26370
61899
answer


編集後のご質問の主文 **_違う結果が出力される場合はどのようなときなのでしょうか？_** だけに限っての回答ですが。

ちなみに、 ** _上記のお題はAtCoderの「AtCoder Grand Contest 041」のA「Table Tennis
Training」です。_** といった情報は最初からご質問に含めておいた方が良いでしょう。

出題中にこんな制約があります。

  * 2≤N≤10¹⁸
  * 1≤A<B≤N
  * 入力中のすべての値は整数である。

この値の範囲を見ると、分かる人なら「ははぁん」と納得して、「どのようなとき」に「違う結果が出力されるか、すぐに例が作れてしまうでしょう。

[code]

    a = 2
    b = 1000000000000000000
    ans = (b-a)/2
    print(int(ans)) #->500000000000000000
    
    ans = (b-a)//2
    print(ans)      #->499999999999999999
    
[/code]

Pythonの`float`型は64ビットの浮動小数点数で、10進換算で15〜16桁の精度しかなく、`499999999999999999`のような18桁ある整数値を正確に表すことができません。従って、計算結果を`float`型に変換する`/`除算では結果を正確に表すことができない訳です。

出題に「10¹⁸」なんて値が設定してあるのには、単にループや再帰などを使った繰り返し型の回答を排除するだけでなく、
**途中計算に`float`型を使うと正しい結果が得られない** ように設定したかったのだろうと思われます。


CC BY-SA 4.0
2019-12-31T03:08:08.373
61909
2019-12-31T03:08:08.373
13972
61899
answer