2009-10-01 44 views
1

我有一個函數可以將賦給函數的數字舍入到最近的整個便士。以10爲底的舍入

<script type='text/javascript'> 
Math.roundNumber = function(a,b){ 
    if(!isNaN(parseInt(a))){ 
     c = Math.pow(10,b); 
     return (Math.round(a*c)/c); 
    } 
    return false; 
} 
</script> 

但它已經到了我的注意,輸入到該函數的表示號碼只能四捨五入到最接近的一個便士但是它必須四捨五入至小數點後兩位。

E.G.

 
15.236562213541684 would = 15.24 
9846.65456169846 would = 9846.66 

我認爲這將只是改變 回報(Math.round(一)/ C)的情況; 返回 return(Math.ceil(a c)/ c);

顯然我錯了。

在這個問題上的任何幫助?

**編輯**

這裏是我試圖實現也許公式,它會幫助

a = intrest price 
b = terms 
c = a/b 
d = c*(b-1) 
e = a-d 

因此,例如權

a = 295.30 
b = 156 
c = 295.30/156 = 1.90 (rounded up to nearest decimal as above) 
d = 1.90 * (b-1) = 294.50 
e = 295.30 - 294.50 = 0.80 
可以

人函數做到以上?

Here是一個鏈接到當前的代碼,我已經包括公式...它是一個非常古老的公式,當我第一次啓動JavaScript時(這是前一段時間現在),但我仍然沒有更好的現在作爲那時我回來了。

任何人都可以清理它,看看他們是否可以看到爲什麼它不工作以匹配上面的功能?

+1

「顯然我錯了。」 例子? – 2009-10-01 17:00:41

+1

我認爲你的代碼實際上工作。也許你有一箇舊腳本緩存? – 2009-10-01 17:23:49

+0

上面使用的parseInt()會給出意想不到的結果,如果該數字以固定爲零的ZERO – 2009-10-01 19:27:11

回答

0
function currency_fix(number) 
{ 
    var unfixed_number = Math.ceil(number.toFixed(5) * 100)/100; 
    return unfixed_number.toFixed(2) 
} 

var a = currency_fix(295.30) 
var b = currency_fix(156) 
var c = currency_fix(a/b) 
var d = currency_fix(c * (b - 1)) 
var e = currency_fix(a - d) 

document.write(
    'a = ' + a + '<br />' + 
    'b = ' + b + '<br />' + 
    'c = ' + c + '<br />' + 
    'd = ' + d + '<br />' + 
    'e = ' + e + '<br />' 
) 

// OUTPUT 
//a = 295.30 
//b = 156.00 
//c = 1.90 
//d = 294.50 
//e = 0.80 

我在這種情況下得到了你想要的結果。不知道它是否會每次都起作用,但看起來似乎。我肯定會檢查它的工作,因爲你想要它第一。

+0

......這將我提出的所有東西都放在了概念之中......你只是以一種合理的方式呈現它。感謝您花時間寫這篇文章。 – 2009-10-01 19:30:36

5

這裏有一個內置函數,Number.toFixed(numDigits),爲什麼不用這個?

參數:數字
小數點後出現的位數;這可能是0到20之間的一個值,包括0和20,並且實現可以可選地支持更大範圍的值。如果省略該參數,它被視爲0。

返回:
數的字符串表示,不採用指數計數法,並且具有小數點後的數字準確的數字。如有必要,數字被舍入,小數部分填充零(如有必要),使其具有指定的長度。如果number大於1e + 21,則此方法僅調用Number.toString()並以指數表示形式返回字符串。

例子:

>>> new Number(15.236562213541684).toFixed(2); 
"15.24" 
>>> new Number(9846.65456169846).toFixed(2); 
"9846.65" 

最後一項不符合您的例子 - 9846.65456169846四捨五入至小數點後兩位應9846.65,不9846.66

+1

也向下舍入。這比他的Math.round解決方案更好,但它仍然不能按要求工作。 「 – scragar 2009-10-01 16:48:18

+1

」這最後一個與您的示例不符 - 9846.65456169846舍入到小數點後兩位應該是9846.65,而不是9846.66。「 - 這是不正確的,因爲我提到它需要總是舍入到最近的一個便士。 – 2009-10-01 16:50:51

+0

啊,我不明白他的意思。 – 2009-10-01 16:57:52

1

您的代碼比您需要完成此任務更復雜。如果您知道小數點總是表示一個穩定值,無論該小數點兩邊的數字長度如何,您都很幸運。

1)然後,你必須僅僅多個原始的數目由100

2)如果(號碼(x.charAt(INDEXOF( 「」)+ 1))> 4){X + = 1},其中x是你的號碼

3)parseInt函數

4)除以100,和你做。

+0

「如果您知道小數點將始終代表穩定值,而不管小數點兩邊的數字長度是多少。「 - 謹慎地闡述你的意思? – 2009-10-01 16:52:28

0

不,你說得對。

我測試了你的代碼與ceil modifictaion,它的工作原理。

+0

ceil不起作用...使用ceil似乎會產生不準確的結果,例如:利息價格:£295.30 155英鎊支付1.90英鎊,之後支付0.81英鎊。總計達295.31,其中一筆支付必須是0.80英鎊...... – 2009-10-01 17:40:37

+1

@尼爾:因爲你總是四捨五入,你總會得到一個總數大於精確值的總數。即使四捨五入你有時也會有所不同。如果您希望總額相同,您必須計算最終付款爲總額與以前實際付款總額之間的差額。 – Guffa 2009-10-01 18:21:25

+0

@Guffa我理解這一點,如果你看看我在編輯中添加了什麼,你會看到我正在嘗試的實際公式......也許你可以看到需要應用這個公式才能工作的數字。 – 2009-10-01 18:24:27

1

替換Math.round()Math.ceil()應該工作:該錯誤必須在其他地方。

此外,我建議完全放棄isNaN(parseInt()),因爲數學函數無論如何都會投射數字,如果不可能,則返回NaN。這將導致返回NaN的函數,這比布爾值false更適合。

btw:使用帶有貨幣值的浮點數學是一個壞主意:改用固定點算術!


現在我們知道你想做什麼,這裏的後者計算所需的值,你的例子代碼:

var value = 295.30; 
var count = 156; 
var payment = Math.ceil(value * 100/count)/100; 
var last_payment = Math.round((value - (count - 1) * payment) * 100)/100; 

更改round()ceil()所有計算爲沒有工作最後一筆支付必須進行正常取整以彌補由於使用浮點值而導致的不準確性。

這是一般最好只使用整數運算,所以用100乘以所有值和僅輸出值時,轉換:

var value = 29530; 
var count = 156; 
var payment = Math.ceil(value/count); 
// rounding no longer necessary as integer math is precise: 
var last_payment = value - (count - 1) * payment; 
+0

我已經添加了我試圖找出的公式......任何想法? – 2009-10-01 17:58:55

1

建議使用定點運算是很好的建議。不幸的是,Javascript中沒有定點算術 - 所有數字都是雙精度浮點數。 (好吧,沒有定點算法,沒有拉入某些明確的支持庫。)

對於文本字段中的輸入輸入,我已經開始處理數字作爲字符串(儘可能)。將輸入切換到小數點左側和右側的部分,然後使用整數值(必要時通過Math.floor())。如果你必須處理超過小數點後第二位的雜散數字,或者將它們當作錯誤(它們意味着什麼?),否則,再次將它們分開並將它們作爲整數處理。

如果你是而不是處理用戶提供的值(即,來自文本輸入字段的東西),那麼你真的不應該在Javascript中這樣做,因爲再次,你沒有數字你真正需要的工具。

+0

在JS中可能沒有專門的定點算術,但你總是可以用適當的因子乘以所有的值來得到整數;數學將是準確的,只要你不耗盡雙精度的雙精度 – Christoph 2009-10-01 18:43:18