25

浮動小数点を使用せずに最も近い整数に丸める簡単なPythonの方法はありますか?次のことをしたいのですが、整数演算を使用します。

skip = int(round(1.0 * total / surplus))

==============

@John:浮動小数点はプラットフォーム間で再現できません。コードが異なるプラットフォーム間でテストに合格するようにしたい場合は、浮動小数点を回避する必要があります(または、テストにハッキーなespilonを追加して、機能することを期待します)。上記は、ほとんど/すべてのプラットフォームで同じになるほど単純かもしれませんが、浮動小数点を完全に回避する方が簡単なので、その決定はしたくありません。それは「Pythonの精神ではない」のでしょうか。

4

6 に答える 6

42

これは非常に簡単に行うことができます。

(n + d // 2) // d、ここnで、は被除数、dは除数です。

のような代替案(((n << 1) // d) + 1) >> 1または同等のものは、古いのように実装され(((n * 2) // d) + 1) // 2ている最近のCPythonでは遅くなる可能性があります。intlong

単純な方法では、3つの変数アクセス、1つの定数ロード、および3つの整数演算を実行します。複雑なメソッドは、2つの変数アクセス、3つの定数ロード、および4つの整数演算を実行します。整数演算は、関係する数値のサイズに応じて時間がかかる可能性があります。関数ローカルの可変アクセスには、「ルックアップ」は含まれません。

あなたが本当にスピードを切望しているなら、ベンチマークをしてください。それ以外の場合は、KISS。

于 2010-10-16T21:53:55.390 に答える
7
skip = (((total << 1) // surplus) + 1) >> 1

物事を1ビット左にシフトすると、実質的に2倍になり、右に1ビットシフトすると、2で除算されます。中央に1つ追加すると、結果が小数部.5を超える場合、「切り捨て」が実際に切り上げられるようになります。

基本的にはあなたが書いたのと同じです...

skip = int((1.0*total/surplus) + 0.5)

ただし、すべてを2で乗算し、後で2で除算します。これは、整数演算で実行できることです(ビットシフトは浮動小数点を必要としないため)。

于 2010-10-16T19:18:18.880 に答える
6

zhmyhの答えの答えに触発されました。

q, r = divmod(total, surplus)
skip = q + int(bool(r)) # rounds to next greater integer (always ceiling)

、私は次の解決策を思いついた:

q, r = divmod(total, surplus) 
skip = q + int(2 * r >= surplus) # rounds to nearest integer (floor or ceiling)

OPが最も近い整数への丸めを要求したため、zhmhsのソリューションは実際にはわずかに正しくありません。これは、私のソリューションが要求どおりに機能している間、常に次に大きい整数に丸められるためです。

(私の答えはzhmhの答えに対する編集またはコメントである必要があると思われる場合は、コメントである必要があるため、提案された編集は拒否されたことを指摘しておきますが、まだ十分な評判がありませんコメント!)

どのように定義されているのか疑問に思われる場合:そのドキュメントdivmodによると

整数の場合、結果はと同じになり(a // b, a % b)ます。

したがって、OPの要求に応じて、整数演算を使用します。

于 2014-04-08T15:35:35.647 に答える
2

さらに別の面白い方法:

q, r = divmod(total, surplus)
skip = q + int(bool(r))
于 2012-10-25T11:37:54.270 に答える
0

分割する前に、丸めルールに注意してください。最も単純な切り上げの場合:

if total % surplus < surplus / 2:
    return total / surplus
else:
    return (total / surplus) + 1

適切な丸めを行う必要がある場合は、少し微調整します。

于 2010-10-16T20:38:06.443 に答える
-2

これも機能するはずです:

def rint(n):
    return (int(n+.5) if n > 0 else int(n-.5))
于 2010-10-16T20:30:28.223 に答える