2013-12-17 57 views
3

我正在寫一個程序,打印一個數組,其中包含作爲參數傳遞的兩個數組值的總和。除了最後一個double值之外,它一切正常。我想要打印最後一個值爲3.1。相反,它的打印下列:奇怪的雙重打印陣列

[5.9,11.7,2.4,3.0999999999999996]

不知道如何格式化以其他方式打印,因爲我不允許使用字符串來解決它。我沒有與其他值的問題。這是我的代碼,並感謝您的幫助!

import java.util.*; 

class Sum 
{ 
    public static void main (String [] args) 
    { 
     double [] a1 = {4.5, 2.8, 3.4, 0.8}; 
     double [] a2 = {1.4, 8.9, -1.0, 2.3}; 

     arraySum (a1, a2); 

     System.out.println (Arrays.toString (arraySum (a1, a2))); 
    } 

    public static double [] arraySum (double [] x, double [] y) 
    { 
     int length = 0; 
     double [] sum = new double [x.length]; 
     length = x.length; 

      for (int i = 0; i <= length - 1; i++) 
      { 
       sum[i] = x[i] + y[i]; 
      } 

     return sum; 

    } 
} 
+0

這是因爲二進制浮點,這是程序員必須知道的最基本的東西之一 –

回答

3

你想用deciaml格式

DecimalFormat df=new DecimalFormat("#.#"); 
String outputString=df.format(sum); 
+0

雖然我不允許使用字符串來格式化問題,但... – srsarkar7

3

這是由於IEEE浮點模型。它不能完全代表3.1。要打印它就像你想要的,你必須手動,而不是使用Arrays.toString。環比雙打和格式化:

public static String toString(double[] x, DecimalFormat format) 
{ 
    StringBuilder sb = new StringBuilder(); 
    sb.append("["); 
    for (int i = 0; i < x.length; ++i) 
    { 
     sb.append(format.format(x[i])); 
     sb.append(", "); 
    } 
    sb.delete(sb.length() - 2, sb.length()); 
    sb.append("]"); 
    return sb.toString(); 
} 

然後調用,如:

toString(sum, new DecimalFormat("#.#")); 

要使用只有雙打,你可能會嘗試將此做的伎倆,但這種又髒又不能保證工作:

double x = ...; 
x = 0.001 * Math.round(x * 1000.0); 
System.out.println(x); 
+0

問題是我無法使用一個字符串來解決它... – srsarkar7

+1

好的答案,唯一的批評是,String.format將不得不解析數組中每個元素的格式字符串。也許DecimalFormat會更有效率。 – LINEMAN78

+0

@ LINEMAN78:謝謝,我修正了:) –

0

如果四捨五入到sigfigs合理數量的數量仍然是正確的這是什麼DecimalF ormat和String.format會爲你做的下。正如@neminem所說,這是由與Strange floating-point behaviour in a Java program相同的問題引起的。如果真的對你來說是個大問題,那麼表示的實際數字對於sigfigs>〜8是準確的,而不是考慮使用BigDecimal,因爲你永遠不會失去任何精度。

0

如果您不允許使用System.out.printf()來解決問題,那麼您的唯一選擇是使用BigDecimal對象來保存這些值。有沒有辦法你會得到一個3.1結果出double沒有這兩種方法之一(或DecimalFormat)。

你說你「不能用String來解決它」,但我不認爲這樣做......

for (double d : arraySum (a1, a2)) { 
    System.out.printf("%.1f\n", d); 
} 

資格作爲「使用字符串來解決這個問題」。似乎對我完全合法。