簡體   English   中英

C ++:帶符號64位整數中兩個無符號64位整數的差值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM