2015-02-05 46 views
0

我想生成一個(非本地化)字符串,表示一個雙精度到'n'的小數位,最好舍入。例如。到小數點後四位,1.234567 - >"1.2346"用手工格式化一個Java double

我知道我可以BigDecimalDecimalFormatString.format()做到這一點,但在我的項目,我約束,並且不能夠使用他們或任何第三方庫。是否可以編寫一個簡單的函數來完成它?怎麼樣?

更新(更多詳細信息):這個問題的原因是我想要一個在GWT和Java中使用相同代碼並需要最少量代碼和庫的解決方案。格式化的數字不會根據瀏覽器的區域設置而改變(例如,當法國用戶運行它時,我不想要"1,2346")。

在GWT,我寫了這個JavaScript包裝功能:

/** 
* Convert a double to a string with a specified number of decimal places. 
* The reason we need this function is that by default GWT localizes 
* number formatting. 
* 
* @param d double value 
* @param decimalPlaces number of decimal places to include 
* @return non-localized string representation of {@code d} 
*/ 
public static native String toFixed(double d, int decimalPlaces) /*-{ 
    return d.toFixed(decimalPlaces); 
}-*/; 

我想一些簡單的Java來取代它,這樣我就可以使用相同的代碼客戶端和服務器上。

public static String toFixed(double d, int decimalPlaces) { 
    // TODO 
} 
+0

醜類,但其轉換爲字符串,舍入和削減小數點或在可能的情況下附加零點 – meskobalazs 2015-02-05 13:23:48

+2

當然,這是可能的,它已經完成了。看到你有4k代表,你現在應該知道你應該展示你的嘗試,或者至少展示一下這個主題的研究。顯示效果,是我的觀點 – 2015-02-05 13:24:04

+0

爲什麼不能使用'Double.toString(double d)'?核心類別當然不被視爲第三方api。 – vikingsteve 2015-02-05 13:25:26

回答

0

我寫了下面的函數。它採用long內部所以不會爲一些非常大的或非常小的double值工作,不過沒關係我用例:

public static String toFixed(double d, int decimalPlaces) { 
    if (decimalPlaces < 0 || decimalPlaces > 8) { 
     throw new IllegalArgumentException("Unsupported number of " 
       + "decimal places: " + decimalPlaces); 
    } 
    String s = "" + Math.round(d * Math.pow(10, decimalPlaces)); 
    int len = s.length(); 
    int decimalPosition = len - decimalPlaces; 
    StringBuilder result = new StringBuilder(); 
    if (decimalPlaces == 0) { 
     return s; 
    } else if (decimalPosition > 0) { 
     // Insert a dot in the right place 
     result.append(s.substring(0, decimalPosition)); 
     result.append("."); 
     result.append(s.substring(decimalPosition)); 
    } else { 
     result.append("0."); 
     // Insert leading zeroes into the decimal part 
     while (decimalPosition++ < 0) { 
      result.append("0"); 
     } 
     result.append(s); 
    } 
    return result.toString(); 
} 

測試:

@Test 
public void formatsDoubleToSpecifiedNumberOfDecimalPlaces() { 
    assertEquals("100.0000", toFixed(100d, 4)); 
    assertEquals("10.0000", toFixed(10d, 4)); 
    assertEquals("1.0000", toFixed(1d, 4)); 
    assertEquals("0.1000", toFixed(0.1d, 4)); 
    assertEquals("0.0100", toFixed(0.01d, 4)); 
    assertEquals("0.0010", toFixed(0.001d, 4)); 
    assertEquals("0.0001", toFixed(0.0001d, 4)); 
    assertEquals("0.0000", toFixed(0.00001d, 4)); 
    assertEquals("0.0000", toFixed(0.000001d, 4)); 

    assertEquals("12", toFixed(12.3456789d, 0)); 
    assertEquals("12.3", toFixed(12.3456789d, 1)); 
    assertEquals("12.35", toFixed(12.3456789d, 2)); 
    assertEquals("12.346", toFixed(12.3456789d, 3)); 
} 

@Test 
public void usesDotAsDecimalSeparatorRegardlessOfLocale() { 
    Locale saved = Locale.getDefault(); 
    Locale.setDefault(Locale.FRANCE); 
    try { 
     assertEquals("123.4568", toFixed(123.456789d, 4)); 
    } finally { 
     Locale.setDefault(saved); 
    } 
} 

如果你能在這個提高,請發表評論或發佈更好的答案。謝謝。

+0

您是否剛剛使用'String.format()'在我的答案中看到了我的單行代碼? – Gerrit 2015-02-05 14:52:39

+0

是的但我禁止在問題中使用String.format(),因爲它沒有得到GWT的支持。 – 2015-02-05 15:00:04

+0

對不起,沒有看到。 – Gerrit 2015-02-05 19:38:42