【问题标题】:How to compare to numeric_limits<int64_t>::min()如何与 numeric_limits<int64_t>::min() 进行比较
【发布时间】:2015-10-26 10:47:00
【问题描述】:

考虑符号(+1-1)是已知的,并且有一个代码可以解析无符号整数。该无符号整数可以等于-numeric_limits&lt;int64_t&gt;::max()。如何在不触发未定义行为的情况下正确比较?

int8_t sign = /* +1 or -1 */;
uint64_t result = /* parse the remaining string as unsigned integer */;
if( result > uint64_t(numeric_limits<int64_t>::max()))
{
    if(sign == 1) return false; // error: out of range for int64_t
    // Is the below code correct or how to implement correctly its intent?
    if(result == uint64_t(-numeric_limits<int64_t>::min()))
    {
        return true;
    }
    return false;
}

【问题讨论】:

  • 这不应该是通常的情况吗:abs(numeric_limits&lt;int64_t&gt;::min()) == numeric_limits&lt;int64_t&gt;::max()?那么第二个 if 永远不会评估为 true。
  • -numeric_limits&lt;int64_t&gt;::min() 将在大多数实现中惨遭失败,因为它将转换为超出范围的内容(-128 => +128 对于典型的int8,这是不可能的,所以你'可能会得到0 )。
  • @m.s.在通常情况下(2 的补码)abs(min) = max + 1。使用反码或符号大小时,abs(min) = max,没有问题,但这是“深奥”的情况。
  • @m.s.,这是我的担忧,但以下程序将 numeric_limits&lt;int64_t&gt;::min() 的否定正确存储在 uint64_t: ideone.com/uHIcCD 中。但这只是特定编译器的示例,而不是一般规则。
  • 如果您假设二进制补码(对我来说看起来像?),那么您应该简单地从result 中删除一个并将其与max 进行比较。

标签: c++ stl int64 uint64 numeric-limits


【解决方案1】:

正如 Holt 所说,您实际上是在假设 2 的补码算术。因此,您可以将-min 替换为max+1

if(result == uint64_t(numeric_limits<int64_t>::max()) + 1)

这避免了在取最小值时导致的未定义行为(有符号整数溢出)。

验证您的系统是否真的使用 2 的补码可能是个好主意(取决于您希望遵守 C++ 标准的严格程度)。这可以通过比较-maxmin 来实现:

if (numeric_limits<int64_t>::max() + numeric_limits<int64_t>::min() == 0)
{
    // If not two's complement:
    // Too large absolute value == error, regardless of sign
    return false;

    // on all sane (2's complement) systems this will be optimized out
}

minmax之间没有其他关系的可能性;这是解释here

【讨论】:

  • 您提供的代码似乎应该返回false而不是true,因为在-min==max的情况下无法表示这样的负值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
相关资源
最近更新 更多