2012-11-29 67 views
4

關於1.01+1.02著名的問題,它是2.0300000000000002數字和toFixed,toPrecision在Javascript中?

的解決方法之一是使用toFixed:例如

(1.01+1.02).toFixed(2) --->"2.03" 

但我看到toPrecision解決

parseFloat((1.01+1.02).toPrecision(10))-->"2.03" 

但是讓我們看看n

  • toFixed(n)

  • toPrecision(n)

我怎麼知道什麼是n?

0.xxxxxxxxxxx 
+ 
    0.yyyyyyyyyyyyy 
--------------------- 
    0.zzzzzzzzzzzzzzzzzzzzzzzzz 
       ^
       | 
-----??????------ 

添加的每個號碼都可以有不同的小數位數...

例如:

1.0002+1.01+1.03333 - > 3.0435300000000005

我將如何計算這裏的n?這個(特定)問題的最佳做法是什麼?

+0

我從來不知道這個問題的存在...也許像'的ToString()。length'可以用來獲得最長數字的長度,用在'.toPrecision(n)'中? – Cerbrus

+0

爲什麼你想「弄清楚」'n'?當我向用戶輸出值時,我只會應用'toFixed'和好友,在這種情況下,我會根據需要多少小數位的情況做出決定。 – phant0m

+2

@ phant0m我認爲這是因爲他想知道計算的真正價值,而不是讓額外數字浮點固有地增加。他可能只是想以最小的精度顯示它,能夠顯示計算的確切值。 –

回答

0

這將返回預期輸出:

function add(){ 
    // Initialize output and "length" properties 
    var length = 0; 
    var output = 0; 
    // Loop through all arguments supplied to this function (So: 1,4,6 in case of add(1,4,6);) 
    for(var i = 0; i < arguments.length; i++){ 
     // If the current argument's length as string is longer than the previous one (or greater than 0 in case of the first argument)) 
     if(arguments[0].toString().length > length){ 
      // Set the current length to the argument's length (+1 is to account for the decimal point taking 1 character.) 
      length = arguments[0].toString().length +1; 
     } 
     // Add the current character to the output with a precision specified by the longest argument. 
     output = parseFloat((output+arguments[i]).toPrecision(length)); 
    } 
    // Do whatever you with with the result, here. Usually, you'd 'return output;' 
    console.log(output); 
} 
add();      // Returns 0 
add(1,2,3);    // Returns 6 
add(1.01,2.01,3.03);  // Returns 6.05 
add(1.01,2.0213,3.3333); // Returns 6.3646 
add(11.01,2.0213,31.3333); // Returns 44.3646 

parseFloat甚至擺脫尾隨零對你的。

該函數接受任意數量的數字作爲參數,然後在添加數字時將這些數字加在一起考慮數字的字符串長度。加法中使用的精度被動態修改以適應「當前添加的」參數的長度。

Fiddle

+1

不要只是發佈代碼。其實解釋你的回答和推理。是的,我們大多數人可以閱讀你的代碼並理解它,但是給出代碼並且沒有任何解釋往往不會幫助人們學習。 –

+1

@JonTaylor:好的,正在努力。 – Cerbrus

+0

在for循環中,我認爲你的意思是[i] –

1

此外,因爲在這種情況下,我會檢查每個操作數的小數位數。

在最簡單的情況下,操作數中小數位數最多的小數位數是n的值。

一旦你有了這個,使用你喜歡的任何方法來截斷你的價值。然後擺脫尾隨零。

您可能會遇到諸如1.06 + 1.04,第一步將帶你到1.10的情況下尾隨零然後截斷爲零將得到1.1

在您的最後一個例子1.0002 + 1.01 + 1.03333最大的十進制數地方是5,所以你留下3.04353和沒有尾隨零截斷。

0

如果你正在做計算,你有兩個選擇:

  • 例如通過100,乘以數字轉換爲整數,然後進行計算,然後再轉換回
  • 做計算,不約的舍入誤差的擔心,那麼一輪顯示時間

的結果。如果你處理星期一埃及/貨幣,第一種選擇可能不是一個壞的選擇。如果你只是在做科學數學,我個人不會擔心它,只是在顯示時間將結果捨去,例如6個有效數字,這是我的C++編譯器的默認值(gcc;不知道它是否在C++中標準或沒有,但如果你的gcc C++打印1.234567890,輸出1.23457,避免問題)

0
var a = 216.57421; 

a.toPrecision(1); // => '200' because 216 with 1 < 5; 
a.toPrecision(2); // => '220' because 216 with 6 >= 5; 

a.toFixed(1); // => 216.6 because 7 >= 5; 
a.toFixed(2); // => 216.57 because 4 < 5; 
相關問題