2011-01-19 49 views
10

我有两个整数,我需要通过一个整数,然后得到两个整数的值回来。传递两个整数作为一个整数

我想使用逻辑运算符(AND,OR,XOR等)。

+1

你什么意思通过找到?你能举一个更好的例子吗? – 2011-01-19 17:26:02

+3

两个原始整数长度有多少位? – 2011-01-19 17:26:40

+0

你使用什么编程语言?以及您想要传递的2个整数中每一个的最大值是多少? – 2011-01-19 17:27:33

回答

1

两个整数不能适合一个整数,或者至少你不能找回两个原始的整数。
但无论如何,如果原来的两个整数是有界的肯定位数你可以(在preudocode): 第一个整数 或与 (二整数SHIFTLEFT(nOfBits))

为找回这两个整数 使用由nOfBitsOne表示的二进制数表示的合并整数并获得第一个整数,然后 ShiftRight by nOfBits合并的整数,然后返回第二个整数。

3

嗯.. @Felice是正确的,但如果他们都适合在16位有一种方法:

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

收拾他们,

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

提取它们。

0

您可以在32位整数内存储2个16位整数。第一个是前16位的第一位,第二位是16位。检索并组合使用shift-operators的值。

10

使用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个字节,但这确实会施加限制。

移位运算符< <和>>用于上下滑动整数的位。移动16位,将位移动两个字节(因为每个字节有8位)。

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

4

这个问题有两个部分。首先,你如何掩饰两个32位整数为64位长整数?

正如其他人所说的,假设我有一个函数,它需要一个X和Y坐标,并返回一个表示该点的线性值的longint。我倾向于把这种线性化的二维数据:

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); 
} 

原谅我,如果我是偏执的操作顺序,有时其他操作贪婪比< <,造成东西比他们应该进一步转移。

为什么这样吗?它什么时候会失败? 整数倾向于正好是longint的一半大小。我们正在做的是把x投向一个很长的位置,将它左移,直到它完全位于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 ...在很长时间里。
  • 它可以引入难以追踪的错误。例如,如果您使用无符号类型并忽略符号扩展名,那么稍后迁移到可使这些类型变为二进制补码的平台。如果您保存longint并尝试稍后在代码的另一部分中读取它,则可能会在bitshift上发生错误并花费一个小时来调试函数,以便发现它是错误的参数。

如果太糟糕了,还有什么替代方案?

这就是人们问你语言的原因。理想的情况是,如果你在像C或C++,它会是最好说

struct Point { int x; int y; }; 

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

否则,像Java高级语言,你可能会风与一个内部类实现相同的功能:

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/

相关问题