【问题标题】:Casting negative integer to larger unsigned integer将负整数转换为更大的无符号整数
【发布时间】:2014-02-14 01:15:14
【问题描述】:

我遇到过执行以下转换的代码:

static_cast<unsigned long>(-1)

据我所知,C++ 标准定义了将有符号整数值转换为无符号整数类型时会发生什么(请参阅:What happens if I assign a negative value to an unsigned variable?)。

我在上面的代码中担心的是源类型和目标类型的大小可能不同,以及这是否会对结果产生影响。编译器会在转换之前扩大源值类型吗?它会改为转换为相同大小的无符号整数然后放大吗?还是别的什么?

用代码澄清一下,

int nInt = -1;
long nLong = -1; // assume sizeof(long) > sizeof(int)

unsigned long res1 = static_cast<unsigned long>(nInt)
unsigned long res2 = static_cast<unsigned long>(nLong);

assert(res1 == res2); // ???

基本上,我应该担心编写类似的代码

static_cast<unsigned long>(-1L)

结束

static_cast<unsigned long>(-1)

【问题讨论】:

  • 名词是“整数”。 (积分也是名词......在微积分中,不是 C++)
  • 确认!你是对的。太多的 Haskell 编程......
  • 我曾经有一个非常相似的问题:stackoverflow.com/q/18303682/2445184

标签: c++ casting size


【解决方案1】:

来自 C++11 标准,4.7“积分转换”,第 2 段:

如果目标类型是无符号的,则结果值是最小的 与源整数一致的无符号整数(模 2n 其中 n 是用来表示无符号类型的位数)。

换句话说,当转换为无符号整数时,只有输入的值很重要,而不是它的类型。将 -1 转换为 n 位无符号整数将始终为您提供 2n-1,无论 -1 以哪种整数类型开始。

【讨论】:

  • 这就是我不擅长使用规范的原因。这句话对我来说毫无意义,主要是因为它取决于“一致”的定义。这是规范中其他地方定义的吗?因为英文定义并没有真正的帮助。我可以很容易地说 (uint32_t)-1 应该是 0x00000001,因为 -1 与 1 的相似性比与 4294967295 的相似。如果您使用“形式相同;叠加时恰好重合”的几何定义,那么就没有t 一个永远匹配 -1 的无符号数。
  • 它使用全等的数学定义:如果两个数在除以 N 时都留下相同的余数,则它们在模 N 下是全等的。
【解决方案2】:

这是一个很好的问题,draft C++ standard 这个部分的4.7 积分转换 说:

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2n 其中 n 是用于表示无符号类型的位数)。 [ ...]

不是最直接的解释,在这种情况下,我会回到draft C99 standard,它说:

否则,如果新类型是无符号的,则通过重复添加或转换值 比新类型可以表示的最大值多减一 直到值在新类型的范围内。49

脚注49 有用的是:

这些规则描述的是数学值的算术运算,而不是给定类型表达式的值。

这更直接,并且无论操作数是什么类型,都清楚地给出了-1 + MAX + 1MAX 的结果。

【讨论】:

  • C++ 版本对我来说似乎更明确!
  • @MattMcNabb 我没有说得更清楚,我说的是直截了当或更广泛的人可以访问。最好在 C++ 中指定。
猜你喜欢
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-09
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
相关资源
最近更新 更多