将两个整数作为一个整数传递

时间:2011-01-19 17:22:24

标签: logic xor

我有两个整数,我需要通过一个整数,然后得到两个整数的值。

我正在考虑使用逻辑运算符(AND,OR,XOR等)。

5 个答案:

答案 0 :(得分:12)

使用C编程语言,假设两个整数小于65535,可以按如下方式完成。

void take2IntegersAsOne(int x)
{
   // int1 is stored in the bottom half of x, so take just that part.
   int int1 = x & 0xFFFF;  

   // int2 is stored in the top half of x, so slide that part of the number
   // into the bottom half, and take just that part.
   int int2 = (x >> 16) & 0xFFFF

   // use int1 and int2 here. They must both be less than 0xFFFF or 65535 in decimal

}


void pass2()
{
  int int1 = 345;
  int int2 = 2342;
  take2Integers( int1 | (int2 << 16) );
}

这取决于在C中整数存储在4个字节中的事实。因此,该示例使用前两个字节来存储其中一个整数,并使用接下来的两个字节来存储第二个字节。这确实强加了限制,尽管每个整数必须具有足够小的值,以便它们每个都只适合2个字节。

移位运算符&lt;&lt;和&gt;&gt;用于向上和向下滑动整数位。移位16,将位移动两个字节(因为每个字节有8位)。

使用0xFFFF表示位数模式,其中数字的低两个字节中的所有位都是1,因此,ANDing(带有&amp;运算符)会导致不在这两个字节中的所有位被关闭(回零)。这可用于从您当前正在提取的那个中删除“其他整数”的任何部分。

答案 1 :(得分:4)

这个问题分为两部分。首先,如何将两个32位整数写入64位长整数?

正如其他人所说的那样,假设我有一个带X和Y坐标的函数,并返回一个表示Point的线性值的longint。我倾向于将这种2d数据线性化:

public long asLong(int x, int y) {
    return ( ((long)x) << 32 ) | y;
}

public int getX(long location) {
    return (int)((location >> 32) & 0xFFFFFFFF);
}

public int getY(long location) {
    return (int)(location & 0xFFFFFFFF);
}

请原谅我,如果我对操作的顺序感到偏执,有时其他操作比<&lt;&lt;更贪婪,导致事情进一步转移。

为什么这样做?什么时候失败? 方便的是整数往往只是longins的一半大小。我们正在做的是将x转换为long,将其向左移动直到它完全位于y的左侧,然后执行并集操作(OR)以合并两者的位。

让我们假装他们将4位数字合并为8位数字:

x = 14     :      1110
y =  5     :      0101

x = x << 4 : 1110 0000

p = x | y  : 1110 0000
           OR     0101
             ---------
             1110 0101

与此同时,反过来说:

p = 229    : 1110 0101  
x = p >> 4 : 1111 1110  //depending on your language and data type, sign extension
                        //can cause the bits to smear on the left side as they're
                        //shifted, as shown here. Doesn't happen in unsigned types
x = x & 0xF:
             1111 1110
         AND 0000 1111
         -------------
             0000 1110  //AND selects only the bits we have in common

y = p & 0xF:
             1110 0101
         AND 0000 1111
         -------------
             0000 0101  //AND strikes again

这种方法很久以前就出现了,需要从存储或传输空间中挤出一点点。如果您不在嵌入式系统上或立即打包这些数据以便通过网络传输,整个过程的实用性开始真正迅速地崩溃:

  • 对于装回一个几乎总是需要取消装箱并由调用者读取的返回值,这太过分了。这有点像挖洞然后填补它。
  • 它大大降低了代码的可读性。 “返回什么类型?”呃...一个int ..和另一个int ... in a long。
  • 它可以引入难以追踪的错误。例如,如果您使用无符号类型并忽略符号扩展,那么稍后将迁移到导致这些类型为二进制补码的平台。如果你保存了longint,并尝试稍后在代码的另一部分读取它,你可能会在bitshift上遇到一个一个一个错误,并花一个小时调试你的函数只是为了找出它是错误的参数。

如果它太糟糕了,有哪些替代方案?

这就是为什么人们会问你关于你的语言的原因。理想情况下,如果您使用的是C或C ++,最好说

struct Point { int x; int y; };

public Point getPosition() {
    struct Point result = { 14,5 };
    return result;
}

否则,在像Java这样的HLL中,您最终可能会使用内部类来实现相同的功能:

public class Example {
    public class Point {
        public int x;
        public int y;
        public Point(int x, int y) { this.x=x; this.y=y; }
    }

    public Point getPosition() {
        return new Point(14,5);
    }
}

在这种情况下,getPosition返回一个Example.Point - 如果您经常使用Point,则将其提升为自己的完整类。事实上,java.awt已经有几个Point类,包括Point和Point.Float

最后,许多现代语言现在都有语法糖,用于将多个值装入元组或直接从函数返回多个值。这是最后的手段。根据我的经验,只要你假装数据不是 ,你就会遇到问题。但是,如果您的方法绝对必须返回两个实际上不属于同一数据的数字,则可以使用元组或数组。

可以在以下位置找到c ++ stdlib元组的引用 http://www.cplusplus.com/reference/std/tuple/

答案 2 :(得分:2)

嗯.. @Felice是对的,但如果它们都适合16位,那就有办法:

output_int = (first_int << 16) | second_int
                               ^
                           means 'or'

收拾它们,

first_int = output_int & 0xffff
second_int = (output int >> 16) & 0xffff
                                ^
                           means 'and'

提取它们。

答案 3 :(得分:1)

两个整数不能容纳一个整数,或者至少你不能找回原来的两个整数 但无论如何,如果两个原始整数被限制在一定数量的位,你可以(伪代码): 第一个整数 或者与 (第二个整数SHIFTLEFT(nOfBits))

获取两个整数 使用由nOfBitsOne表示的二进制数字掩码合并的整数,然后获得第一个整数 ShiftRight by nOfBits合并的整数,然后你回到第二个。

答案 4 :(得分:-1)

您可以在32位整数内存储2个16位整数。第一个是16个第一位,第二个是最后16位。要检索和组合值,请使用shift-operators。