【问题标题】:Can integer division yield a different result when applied on unsigned operands vs signed operands?当应用于无符号操作数和有符号操作数时,整数除法会产生不同的结果吗?
【发布时间】:2023-03-20 19:28:02
【问题描述】:

当然,我问的是返回的实际“位数据”。

换句话说,以下函数能否返回false

bool func(uint x, uint y)
{
    return x / y == (uint)((int)x / (int)y);
}

?

【问题讨论】:

  • uint 到底是什么?为什么要发明自己的 typedef 语言而不是使用标准化类型?
  • 此外,在过时的 C90 ("ANSI-C") 中存在一个语言错误,其中未指定除法的舍入方向与负数。这在 1999 年得到修复,C90 被撤回。如果您使用的是非常旧的编译器,它仍然可能是个问题。
  • 这个问题更多的是关于整数算术而不是关于 C。它也可能是 C++ 或任何其他强类型语言。我使用 C 只是为了给出一个更具体的例子来说明我的意思。
  • 我刚刚给了你一个完美的例子,说明为什么确切的语言和版本很重要。 C 和 C++ 都没有称为uint 的类型。在任何一种语言中,这种类型实际对应的内容也很重要。隐式提升和有符号到无符号的转换基于类型的大小发生。所以用一些伪代码例子来讨论这个是没有意义的。

标签: c twos-complement integer-division


【解决方案1】:

绝对可以。 4294967295 / 2 == 0x7fffffff,但 -1 / 2 == 0。

大值是uint32_t 类型,所有位都已设置,-1 也是一个32 位值int32_t,所有位都已设置。当设置参数的最高位时,您应该会得到不同的结果。例外是 a / a == 1,对于有符号和无符号除法,当 a != 0 时。

当算术在有符号和无符号操作数之间时,编译器知道要为 CPU 发出不同的指令。

【讨论】:

  • 这是一个很好的答案,但我不会通过-1,我会通过(uint)(-1)
  • 但你是对的,它确实回答了我的问题的标题,所以我需要在这里稍微解释一下我的逻辑混乱......
  • 当您将x=0xffffffff 作为uint32_t 传递时,在转换为(int)x 之后它将是-1。
  • 好吧,当你用这些值调用func 时,你明白了吗?我收到了 true... 但也许我做错了什么。
  • 是的,我用错了(cout'ing uint8,将其转换为 char)。
猜你喜欢
  • 1970-01-01
  • 2020-10-30
  • 2014-12-09
  • 2016-12-08
  • 2018-10-28
  • 2012-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多