質問

浮動小数点を使用せずに、最も近い整数に丸めて、シンプルでピトニックな方法がありますか?以下をやりたいのですが、整数算術を使用してください。

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

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

@John:フローティングポイントは、プラットフォーム間で再現できません。コードをさまざまなプラットフォームに渡すことを望む場合は、浮遊点を避ける必要があります(または、テストにハッキーなEspilonのものを追加して、それが機能することを願っています)。上記は、ほとんど/すべてのプラットフォームで同じになるほど単純かもしれませんが、浮動点を完全に回避するのが簡単であるため、その決定をしたくありません。それは「Pythonの精神ではない」のはどうですか?

役に立ちましたか?

解決

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

(n + d // 2) // d, 、 どこ n 配当です d 除数です。

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

単純な方法は、3つの変数アクセス、1つの一定の負荷、および3つの整数操作を行います。複雑な方法は、2つの可変アクセス、3つの一定の負荷、および4つの整数操作を実行します。整数操作には、関連する数値のサイズに依存する時間がかかる可能性があります。関数の可変アクセスローカルには「ルックアップ」が含まれません。

あなたが本当にスピードを求めて乾燥しているなら、ベンチマークをしてください。そうでなければ、キス。

他のヒント

skip = (((total << 1) // surplus) + 1) >> 1

残ったものを1つのビットでシフトすることは、効果的に2を増やし、2つの丸みを帯びた丸みを帯びたものを1つビット分割します。中央に1つを追加すると、結果が.5小数の部分を超えていれば、「丸め」が実際に丸められるようになります。

それは基本的にあなたが書いた場合と同じです...

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

すべてが2で増加し、その後2で分割されることを除いて、これは整数算術でできることです(ビットシフトは浮動点を必要としないため)。

に触発された 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が要求するように、整数算術に固執します。

さらに別の面白い方法:

q, r = divmod(total, surplus)
skip = q + int(bool(r))

分割する前に、丸めルールの世話をするだけです。最も単純なラウンドハーフアップのために:

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

適切なラウンドとネズミを行う必要がある場合は、少し調整します。

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

def rint(n):
    return (int(n+.5) if n > 0 else int(n-.5))
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top