2011-01-19 73 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/