3

我正在开发一个混合 64 位(用于某些计算)和 32 位(用于节省空间的存储)无符号整数的程序,因此在算术过程中将它们分类以避免溢出非常重要

这是一个示例问题

我想将 1 向左移动一个 unsigned long n,但我希望结果是一个 unsigned long long。这将用于 if 语句中的比较操作,因此不会进行赋值。我给你一些代码。

void example(unsigned long shift, unsigned long long compare)
{
    if((1<<shift)>compare)
    {
        do_stuff;
    }
}

我怀疑这不会做我想要的,那么下面会做我想要的吗?

void example(unsigned long shift, unsigned long long compare)
{
    if(((unsigned long long)1<<shift)>compare)
    {
        do_stuff;
    }
}

我如何微观管理这些东西的位宽?哪个操作数决定了执行操作的位宽,还是两者中较大的一个?

另外,如果可能的话,我也想了解一下它对其他操作的工作原理,例如 + * / % 等。

也许引用具有此信息的资源会很好,我似乎无法在任何地方找到有关此信息的明确声明。或者也许规则很简单,只需发布​​即可。我不确定。

4

3 回答 3

4

它会做你想要的。但是,这可以通过使用 type 的文字常量来实现(在这种特殊情况下)long long1LL

于 2012-10-01T00:37:33.050 回答
4

哪个操作数决定了执行操作的位宽,还是两者中较大的一个?

对于位移,左操作数(要移位的)决定了执行操作的类型。如果整数提升将其转换为intor unsigned int,则以该类型执行操作,否则以左操作数的类型执行操作。

为了比较,移位的结果可以被转换为另一个操作数的类型。在您的示例代码中,整数常量1具有 type int,因此将在 type 处执行移位int,并将结果转换为unsigned long long用于比较。强制转换有效,因为结果的类型不会被整数提升更改,就像使用后缀文字一样1ull

对于其他列出的操作,算术操作(如比较),执行操作的类型由两个操作数确定,如下所示:

否则,对两个操作数都执行整数提升。然后将以下规则应用于提升的操作数:

  • 如果两个操作数具有相同的类型,则不需要进一步转换。
  • 否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型,则具有较小整数转换等级的类型的操作数将转换为具有较高等级的操作数的类型。
  • 否则,如果无符号整数类型的操作数的等级大于或等于另一个操作数类型的等级,则将有符号整数类型的操作数转换为无符号整数类型的操作数的类型。
  • 否则,如果有符号整数类型的操作数的类型可以表示无符号整数类型的操作数类型的所有值,则将无符号整数类型的操作数转换为有符号整数类型的操作数的类型。
  • 否则,两个操作数都转换为与带符号整数类型的操作数类型对应的无符号整数类型。
于 2012-10-01T00:48:58.747 回答
3

你想要的是一个long long 文字。为此,请使用1LL而不是1.

于 2012-10-01T00:35:49.907 回答