C++:差分の符号なし64ビット整数に符号付きの64ビット整数
-
29-10-2019 - |
質問
うことにより関数を書くのC++言語による二つの64ビット符号無し整数型を返しますその差を符号付きの64ビット整数です。できるようにビットの複雑なので、オーバーフローの状況からの入力の二つの正の整数符号なしの場合に絶対で今までより大きい最大限の署名値(INT64_MAXし、その後の差を送信することのできないよ符号付き整数です。って書いて、以下の実施、また、英語上級者の方にお尋ねする場合、最初に、ここは正しく機能的、あるので、簡単に実装されます。あらゆる提案うぞよろしくお願い申し上げます。よろしく!(買い替えを主張すると例外ではあり!)
int64_t GetDifference(uint64_t first, uint64_t second) {
uint64_t abs_diff = (first > second) ? (first - second): (second - first);
uint64_t msb_abs_diff = (abs_diff >> (sizeof(abs_diff)*8 - 1)) & 1;
assert(msb_abs_diff == 0);
int64_t diff = first - second;
return diff;
}
解決
私はこのように見えるがより簡単に、読みやすくするために実装されます。
int64_t GetDifference(uint64_t first, uint64_t second) {
uint64_t abs_diff = (first > second) ? (first - second): (second - first);
assert(abs_diff<=INT64_MAX);
return (first > second) ? (int64_t)abs_diff : -(int64_t)abs_diff;
}
他のヒント
三nitpicks:
sizeof(abs_diff)*8 - 1
に置き換えることができるリテラル63
を損なうことなくポータビリティ高いです 以上 携帯でのプラットフォームがchar
な8ビット幅)& 1
を必要とせず、その結果、シフトとして度々取り上げられているビット- お導き出すことができる
diff
からabs_diff
なく繰り返すことで減算.
そうでない場合は、このように完全に正解でした。
これにより、短くなります。
int64_t GetDifference(uint64_t first, uint64_t second)
{
int64_t diff = first - second;
bool overflowed = (diff < 0) ^ (first < second);
assert(!overflowed);
return diff;
}
良い最適化コンパイラは知ること diff < 0
がマイナスの旗 first < second
の施フラグからの事前の表現です。の比較から二つのフラグは、クラシックの試験のためのオーバーフロー.
もっていることを確認してくださいことが少ない操作が必要です。
が最大の理由うこと ありませんマジック番号.
この:
int64_t GetDifference(uint64_t first, uint64_t second) {
int64_t diff = (int64_t)(first - second);
assert first >= second && diff >= 0 || first < second && diff < 0;
return diff;
}
所属していません StackOverflow