【问题标题】:How to ensure that operations on unsigned integers do not result in wrap如何确保对无符号整数的操作不会导致换行
【发布时间】:2021-10-30 14:37:42
【问题描述】:

我有两个无符号整数,我需要计算它们之间的差异并将其存储在有符号变量中

unsigned int var1, var2;
signed int diff;
diff = (signed)var1 - var2;

由于 var1 和 var2 都是无符号的,这会导致换行吗? 在分配给差异之前,两者的临时差异在哪里存储。如果那是有符号的变量,那么它不会换行,否则它应该换行。

在类似的线路上, 我们可以这样做吗 -

var1 - var2 > signed_int_max

假设 var1

这是正确的做法吗?同样,如果我现在了解在比较之前如何存储临时操作,我会得到答案。

【问题讨论】:

  • 无论如何你都会遇到问题,因为(假设是 32 位整数)两个无符号整数之间的差异可以在 -40 亿到 +40 亿之间,但范围签名的 int 仅为 -20 亿到 +20 亿。
  • @user3386109 是的!确实如此。但是无论如何,如果我假设我的 var1 和 var2 都在有符号的范围内,那么临时结果是如何存储的,即使在这种情况下,如果 var2>var1 将我的结果换行还是给出负值。例如 var2 = 2 var1 = 1 所以我的答案是 diff = -1 或 diff = Wrapped value
  • 从技术上讲,答案是实现定义的。使用二进制补码,答案将是 diff = -1,因为包装值的位模式将被解释为有符号整数值 -1。但是,由于您假设 var1 和 var2 都在有符号整数的范围内,因此您应该在进行减法之前将它们都转换为有符号。

标签: c error-handling unsigned gcc-warning


【解决方案1】:

假设补码。

给定两个无符号整数var1var2var1 - var2 的类型为unsigned int,存储到signed int 时可能会导致溢出。要确定是否溢出,您可以执行var1 - var2 > INT_MAX 之类的操作,其中INT_MAX 将在比较之前隐式转换为unsigned int

var1 < var2 的情况下,var1 - var2 的结果仍然是unsigned int 类型,并且可能会被包装以防下溢。例如,0 - UINT_MAX 将导致 1。在这种情况下,我建议您将var1var2 互换,然后进行相应的判断。类似的东西

  if (var1 >= var2) {
    if (var1 - var2 > INT_MAX) // overflow
    else // good
  }
  else {
    if (var2 - var1 > INT_MAX + 1u) // underflow
    else // good
  }

【讨论】:

  • 如果我们将此差异存储在有符号值中,并且我们假设两者都在有符号范围内。和 var2 > var1 这意味着 ans 应该是负数。但它会因为 unsigned diff 临时存储在 unsigned temp 中而包装吗?
  • 假设 var1
猜你喜欢
  • 2016-01-30
  • 2015-01-16
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 2019-11-28
  • 2023-03-20
  • 2020-10-30
  • 2017-07-21
相关资源
最近更新 更多