2009-12-01 84 views
5

我正在將C++程序轉換爲Java,並完全停留在下面的方法中,這讓我大惑不解。你是否會善意解釋這種方法在做什麼?將C++位模式轉換爲Java

long TSBCA::GetSignedValue(const NDataString &value) 
    { 
     static NDataString s;  
     s = value; 

     long multiplier(1); 
     size_t len(s.Len()); 
     if (len != 0) 
     { 
      if (s[0] >= (char)0xB0 && s[0] <= (char)0xB9) 
      { 
      s[0] &= 0x7F; //Bit Pattern: 0111 1111 
      multiplier = -1; 
      } 
      else if (s[len - 1] >= (char)0xB0 && s[len - 1] <= (char)0xB9) 
      { 
      s[len - 1] &= 0x7F; //Bit Pattern: 0111 1111 
      multiplier = -1; 
      } 
      else 
      multiplier = 1; 
     } 
     else 
      multiplier = 1; 
     return s.ToLong() * multiplier; 
    } 

編輯:

我最初的Java版本:

private long getSignedValue(final String value){ 

     byte[] bytes = value.getBytes(); 
     int length = bytes.length; 
     long multiplier = 1L; 

     if (bytes.length > 0){ 
      if (bytes[0] >= (char)0xB0 && bytes[0] <= (char)0xB9){ 


      bytes[0] &= 0x7F; //Bit Pattern: 0111 1111 
      multiplier = -1; 
      } 
      else if (bytes[length - 1] >= (char)0xB0 && bytes[length - 1] <= (char)0xB9) 
      { 
       bytes[length - 1] &= 0x7F; //Bit Pattern: 0111 1111 
      multiplier = -1; 
      } 
      else 
      multiplier = 1; 
     } 
     else 
      multiplier = 1; 
     return Long.parseLong(Arrays.toString(bytes))* multiplier; 
} 

我做得對嗎?

+0

NDataString?那不是目標C嗎? – 2009-12-01 21:17:40

+0

難道你不想將問題隔離一點,而不是在線發佈公司的代碼? – 2009-12-01 21:19:18

+0

順便說一下,如果這讓你的頭腦發熱,因爲它顯得複雜而複雜,好!我不會把它稱爲好的,明確的代碼的例子。 – 2009-12-01 22:25:45

回答

1

它需要一個字節字符串(即不是文本)並將其轉換爲一個長字符串。它依賴於許多實現特定的東西,並且看起來被破壞:它從兩個不同的地方提取符號位。另一個問題是不必要的非重入(由靜態變量引起)。

+0

如果這是正在轉換的代碼,那麼假設它可以正常工作並且不一定是「破壞」是公平的。標誌的實施可能是一個你並不期待的奇怪協議,但這並不意味着它被破壞,只是尷尬。 – Tenner 2009-12-01 21:32:11

+0

這就是爲什麼我說它看起來壞了,顯然我沒有它寫的確切規範。 – 2009-12-01 21:55:30

+0

如果我做對了,你可以看看編輯嗎?謝謝。 – 2009-12-01 22:13:44

1
s[0] &= 0x7F; 

意味着比特和s[0]用十六進制7F或者換言之,條帶符號位關閉字節值。 相同與s[len-1],所以它:

  • 需要一個數字串,其中所述第一或最後一位數字有添加了一個符號位(0x30 - 0x39 == '0' - '9'0xB0 - 0xB9是相同的範圍內與0x80比特集。)
  • 條即符號位,記住它作爲乘數
  • 使用乘法器來設置符號
  • 返回解釋數值字符串參數值

編輯

查看你的代碼使我下面的話:

  • 按預期它不工作,一定要寫一些JUnit測試新的代碼檢查他們做你期望的東西
  • 將魔術數字放在單獨的常量中
  • 使用byte比較時的常數到字節(符號問題)
  • 懸掛其他的應該得到大括號,並在這種情況下不需要
  • 使用new String(byte[])來重建字符串,而不是數組實用程序類。

這使我這個版本:

// Bit Pattern: 0111 1111 
private static final int BYTE_7F = 0x7F; 

// '0' with sign bit set 
private static final byte BYTE_NEGATIVE_0 = (byte) 0xB0; 

// '9' with sign bit set 
private static final byte BYTE_NEGATIVE_9 = (byte) 0xB9; 


private long getSignedValue(String value) { 

    byte[] bytes = value.getBytes(); 
    final int length = bytes.length; 
    long multiplier = 1; 

    if (0 < length) { 
     if (bytes[0] >= BYTE_NEGATIVE_0 && bytes[0] <= BYTE_NEGATIVE_9) { 

      bytes[0] &= BYTE_7F; 
      multiplier = -1; 

     } else if (bytes[length - 1] >= BYTE_NEGATIVE_0 && bytes[length - 1] <= BYTE_NEGATIVE_9) { 
      bytes[length - 1] &= BYTE_7F; 
      multiplier = -1; 
     } 
    } 

    return Long.parseLong(new String(bytes)) * multiplier; 
} 

您還是要注意添加正確的意見和更新常量名,使之符合您的文檔術語。

+0

如果我做對了,你可以看一下編輯嗎?謝謝。 – 2009-12-01 22:13:00

0

看起來它是測試一些奇怪的標誌版本(正面或負面)。如果第一或最後一個(但優選第一)字符是0xB00xB9之間,然後砍掉取其字符它(和0x39通過'9'使它之間0x30,數字'0')的最高階位。然後返回帶有負號的數字,正如人類所知道的那樣。

+0

如果我做對了,你能否看看編輯?謝謝。 – 2009-12-01 22:15:36