2012-02-14 30 views
0

這可能是不可能的,但我認爲它不能傷害要求。 我有一個程序需要將非整數小數轉換爲八進制符號。據我所知,Java只能自動處理整數八進制。我拼湊了一些雜物,其中包括將這個數字分解爲八個冪次,就像這樣。如何解析Java中的非整數八進制數?

.abcd = X *(1/8)+ Y *(1/64)+ Z *(1/512)+ ......

這將顯示爲「0.xyz 「, 如果那有意義的話。問題是,這導致了很多舍入/截斷錯誤的長數字。有一個更好的方法嗎?

(編輯) 這是我一直在使用來處理數字小數點右邊的算法:

double floatPartNum = Double.parseDouble("0." + temps[1]); 
    if (floatPartNum > 0) { 
     int p = 1; 
     result = result + "."; 
     while (floatPartNum > 0 && p < 16) { 
      double scale = 1/(Math.pow(8, p)); 
      int modT = (int)(floatPartNum/scale); 
      result = result + modT; 
      double modScale = (double)modT * scale; 
      floatPartNum -= modScale; 
      p++; 
     } 
    } 

回答

2

我不知道浮點或在基地八進制數固定點支撐Java的。如果顯示從小數點中提取八進制數字的算法,也許我們可以幫助減少錯誤。

+0

這裏是我正在使用的算法。該點左側的部分被處理,就像它是一個整數一樣,所以我只包括處理該點右邊數字的部分: – Leonide 2012-02-14 04:46:54

+0

糟糕,我忘了按回車貼東西... ' double floatPartNum = Double.parseDouble(「0。「+ temps [1]); if(floatPartNum> 0){p> 1; result = result +」。「; while(floatPartNum> 0 && p <16)double scale = 1 /( Math.pow(8,p)的); INT MODT =(int)的(floatPartNum /刻度); 結果=結果+ MODT; 雙modScale =(雙)MODT *規模; floatPartNum - = modScale; 的p ++; } } ' – Leonide 2012-02-14 04:47:47

1

在Float和Double類中有一些方法允許您獲取數字的按位表示;例如Double.doubleToLongBits(double)

然後,您可以從double-as-bits中提取尾數和指數部分,並將它們轉換爲八進制格式,而不會損失精度。


但是,修復當前算法可能會更簡單。我本以爲你應該能夠在不損失精度的情況下實現你的方法應該。 (你有沒有考慮到精度已經丟失的可能性;在首先產生你的號碼的過程/計算,即)

0

怎麼樣更多的東西像這樣?:

String result = ""; 
    double floatPartNum = temps[1]; 
    if(floatPartNum > 0) 
    { 
    int p = 1; 
    result = result + "."; 
    while(floatPartNum > 0 && p < 16) 
    { 
     floatPartNum *= 8.0D; 
     int modT = (int)floatPartNum; 
     floatPartNum -= modT; 
     result = result + modT; 

     p++; 
    } 
    } 

很多減少引入錯誤的操作。 (對不起,我不能在發佈之前測試此代碼,我不在我的編程工具附近。)

1

您的p < 16是人爲截斷您的輸出。當我在1.0/3.0上嘗試您的代碼時,我得到0.252525252525252,但如果將其更改爲p < 20,則雙精度值中實際上還有足夠的精度來添加三個八進制數字,產生0.252525252525252525。但是如果您擔心「長號碼」,那麼您可能會發現double只是不夠大,無法滿足您的需求。

順便說一句,你的循環可以顯著簡化到:

for(int p = 1; floatPartNum > 0 && p < 20; ++p) 
{ 
    floatPartNum *= 8.0; 
    result = result + (int)floatPartNum; 
    floatPartNum -= (int)floatPartNum; 
} 

(測試),從而消除所有Math.pow等的需要。 (Math.pow通過執行對數和指數運算;這是過度的,並且可能是四捨五入的,當你乘以8時。)