よりも大きなa + b
がLong.MAX_VALUE
/Long.MIN_VALUE
より小さく/大きくなっていないことを確認する簡単な方法はありますか? Guavaを使用してロング+ロングはLong.MAX_VALUE
答えて
は、それは同様に簡単です
long c = LongMath.checkedAdd(a, b); // throws an ArithmeticException on overflow
として、私は確かに、非常に読みやすいと思いますしたいと思います。 (LongMath Javadoc
here)
公平のために、私はApache CommonsがArithmeticUtils.addAndCheck(long, long)
を提供していると言います。
どのように動作するのかを知りたい場合、答えはグアバのビットハッピーの1行です。(a^b) < 0 | (a^(a + b)) >= 0
の場合、結果はオーバーフローしません。これは、同じ符号を持つ場合、2つの数値のビットごとのXORが負ではないというトリックに基づいています。
a
とb
の符号が異なる場合は、(a^b) < 0
は真ですが、その場合はオーバーフローしません。または、(a^(a + b)) >= 0
の場合、a + b
はa
と同じ符号を持つため、オーバーフローせずにマイナスになります。
(このようなより多くのトリックのために、素敵なブックHacker's Delightを調査する。)
Apacheはa
とb
の符号に基づいて、より複雑なケースワークを使用しています。
グアバの+1。 (私が最初に示唆したように)比較しても(私はそれが適切だと思うには眠すぎるが)、すぐに使える機能を好む。 – Bozho
全開示:私は 'LongMath'の著者で、残りはGuavaのcommon.mathパッケージの...しかし、@Bozhoは、独自の実装をロールバックするのではなく、一般的にライブラリコードに頼っている方が一般的には良いということは間違いありません。(特に、このコードはすでに非常に徹底的にテストされているので、必要ありません!) –
非常にクールです。このような単純なケースでは、別のライブラリ全体を追加するのは難しいかもしれません(この場合、オーバーフローを検出するのは簡単です)。しかし、既にGuavaを使用している場合は... –
1つのオプションは、正確な計算を行うためにBigInteger
クラスを使用し、その結果が問題の値よりも大きいか小さいかをチェックすることです。例:
if (BigInteger.valueOf(a).add(BigInteger.valueOf(b)).compareTo(BigInteger.valueOf(Long.MAX_VALUE) > 1) {
/* Overflow occurred. */
} else {
/* No overflow occurred.
}
これが役に立ちます。
フルパワーを使うなら'BigInteger'の' myBigInt.bitLength()
@LouisWassermanは、より小さいために正しい、そうでなければ、1だけ離れているでしょう。私は2つのオプションのいずれかが読めるとは思わないし、答えの1つはLong.MIN_VALUEではなくLong.MAX_VALUEでしかないと思う。 –
これはこれよりも読みにくいということに同意した。参考のため、BigIntegerアプローチは、ライブラリを使用したくない場合は、*乗算*のオーバーフローをチェックする最も読みやすい方法です。 –
簡単なルート:
if(a/2+b/2+(a&b&1)>long.MAX_VALUE/2||a/2+b/2<long.MIN_VALUE/2)...
あなたはちょうど彼らが同じ符号を持つ(両方!0
ある)場合にのみ問題だ、それは(a+b)/2
私はこれが正しく動作するとは思わない。 a = Long.MAX_VALUEとb = 1を取ると、2つの値を加算するとオーバーフローがはっきりしますが、a/2 = Long.MAX_VALUE/2とb/2 = 0になるので、a/2 + b/2 <= Long.MAX_VALUE。 – templatetypedef
@templatetypedef私はそれを解決しました(オーバーフローを追加しました) –
に最適化されないことを願ってする必要があり、それ以外の場合は、オーバーフローから安全です。オーバーフローが発生した場合、結果の符号が反転します。だから、:[?]
long r = a + b;
if ((a < 0 && b < 0 && r >= 0) ||
(a > 0 && b > 0 && r <= 0)) {
// Overflow occurred
}
投票した、最も簡単で、最も読みやすく、最良の方法。うまくいけば、このコースはもっと最適化された数学的方法には向かないでしょう。 –
@ owlsteadコンパイラが十分にスマートな場合は、CPUの "キャリー"フラグを使うことができるので、解決策は十分です。唯一の算術演算がキャリーを介して行われた日に戻ってください。 – bestsss
ほとんどの宿題に適した解決策がアップされました。 –
- 1. のRedisのLUA - はLong.MAX_VALUE
- 2. 型キャスト符号なしロングロングC
- 3. レルム内に「符号なしロングロング」番号を格納するベストプラクティス
- 4. Javaでコンパイル時にLong.MAX_VALUEの文字列値を取得する方法は?
- 5. KafkaConsumer.poll()をLong.MAX_VALUEで呼び出さない理由は何ですか?
- 6. Java番号がlong.max_valueを超えています - どのように検出するのですか?
- 7. 小さな整数を効率的に追加するBignumの実装
- 8. 算術演算を実行するPig
- 9. Javaでの算術演算
- 10. HDRヒストグラム:私はHDRヒストグラムのJava実装を使用しています1つのサンプル数
- 11. 等価演算子は等しくない値に対して真を返します
- 12. Abstract未知のサイズを持つスプリッタの実装はOutOfMemoryErrorをスローします:Javaヒープ領域
- 13. Disruptor EventReleaser.release()メソッド
- 14. "+ ="演算子とint longの使用
- 15. Vavrプロパティのチェック用にLongを含むタプルを生成する
- 16. Math.round MAX返される値
- 17. "22!"で間違った結果を返す再帰的階乗関数
- 18. 桟橋http/2プッシュストリームを開いたままにする
- 19. forループの文字列リテラル対forループのstringbuilder
- 20. カフカコンシューマーによるポーリングと再接続
- 21. java aio SO_KEEPALIVEはubuntu 16.04ではサポートされていませんか?
- 22. カフカ消費者ポーリングタイムアウト
- 23. Javaで「解決できません」というエラーが表示されるのはなぜですか?
- 24. Javaでは、java.nioライブラリとFileChannelを使用して、どのようにファイルからPropertiesオブジェクトをロードできますか?
- 25. 固定数のスレッドを持つリストアイテムを処理する
- 26. Java:URLからの.txtファイル
- 27. Javaスレッドをハングする方法
- 28. Java Durationの最大値は何ですか?
- 29. Firebaseでグライドする - 読み込みに失敗しました
- 30. JavaのループでのSystem.currentTimeMillis()の使用
はどのようにするために、質問テキストボックスの右に、そしてそれ以上** **リンク(およびその下のプレビュー)に**ボックスをフォーマットするために**方法を参考にしてください質問を適切に書式設定する –
アセンブラでは、*キャリー*フラグをチェックできますか? –
私は[宿題]タグを削除しました。コメントスレッドで言及されているOPは偶然にしか存在しなかったためです。 –