![](/img/trans.png)
[英]Does this correctly combine two unsigned 32-bit integers into one unsigned 64-bit integer in C++?
[英]C++: Difference of two unsigned 64-bit integer in a signed 64-bit integer
我試圖用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;
}
三個挑剔:
sizeof(abs_diff)*8 - 1
可以用文字63
代替而不會丟失可移植性(實際上,由於char
不是8位寬的平台,它會更容易移植) & 1
,因為移位的結果總是一位 abs_diff
派生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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.