位移位宽和C算术

时间:2012-10-01 00:33:33

标签: c math bit-manipulation

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

这是一个示例问题

我希望将无符号长整数位向左移位1,但我希望结果为无符号长整数。这将用于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;
    }
}

如何对这些东西的位宽进行微观管理?哪个操作数确定执行操作的位宽,或者它是两个中的较大者?

此外,如果可能的话,我想了解其他操作的效果,例如+ * /%等。

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

3 个答案:

答案 0 :(得分:4)

它将完全符合您的要求。但是,这可以通过使用long long类型的文字常量来实现(在此特定情况下):1LL

答案 1 :(得分:4)

  

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

对于位移,它是左操作数(要移位的操作数),用于确定执行操作的类型。如果整数提升将其转换为intunsigned int,则以该类型执行操作,否则执行左操作数的类型。

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

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

  

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

     
      
  • 如果两个操作数具有相同的类型,则不需要进一步转换。
  •   
  • 否则,如果两个操作数都有有符号整数类型或两者都有无符号整数类型,则具有较小整数转换等级类型的操作数将转换为具有更高等级的操作数类型。
  •   
  • 否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的秩,则带有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型。 / LI>   
  • 否则,如果带有符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值,则具有无符号整数类型的操作数将转换为带有符号整数的操作数的类型类型。
  •   
  • 否则,两个操作数都将转换为无符号整数类型,对应于带有符号整数类型的操作数类型。
  •   

答案 2 :(得分:3)

您想要的是long long 文字。为此,请使用1LL代替1