![](/img/trans.png)
[英]How Close is the Javascript Math.Round to the C# Math.Round?
[英]How to correct for inaccurate Javascript math with math.round()?
我幾天前就發布了這段代碼,但是討論似乎使人對Javascript的弱點(更不用說我自己作為“程序員”的明顯弱點)有了哲理,然后在沒有明確解決方案的情況下就消失了。 我希望有人能幫助糾正這一點。
由於明顯地被稱為“浮點數學”的現象,Javascript在下面的計算器代碼中返回了算術上不准確的答案(正確答案下方為.00000004或類似內容)。 建議我通過“在變量上調用math.round()”來對答案進行四舍五入,我認為這可以很好地滿足我的目的,只是我的JS功夫太弱了,因此在上下文中這樣做的語法也是如此遠遠沒有我。
我在哪里/如何撥打電話? 到目前為止,我所有的嘗試都失敗了,即使我確定每次嘗試都不會失敗。 考慮到我對這個主題的低級了解,我肯定會喜歡一個答案。 這一定是外面有人的灌籃。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script language="javascript">
<!-- Begin Trip Tickets Savings Calc script
function doMath4() {
var one = parseInt(document.theForm4.elements[0].value);
var two = parseInt(document.theForm4.elements[1].value);
var selection = document.getElementsByName("zonett")[0].value;
if(selection == "z4"){
var prodZ4tt = (((one * two) * 4.25) *12) - (((one * two) * 3.75) *12);
alert("Your yearly savings if you buy Trip Tickets is $" + prodZ4tt + ".");
}
else if(selection == "z3"){
var prodZ3tt = (((one * two) * 3.75) *12) - (((one * two) * 3.35) *12);
alert("Your yearly savings if you buy Trip Tickets is $" + prodZ3tt + ".");
}
else if(selection == "z2"){
var prodZ2tt = (((one * two) * 3) *12) - (((one * two) * 2.8) *12);
alert("Your yearly savings if you buy Trip Tickets is $" + prodZ2tt + ".");
}
else if(selection == "z1"){
var prodZ1tt = (((one * two) * 2.5) *12) - (((one * two) * 2.3) *12);
alert("Your yearly savings if you buy Trip Tickets is $" + prodZ1tt + ".");
}
else if(selection == "Base"){
var prodBasett = (((one * two) * 1.5) *12) - (((one * two) * 1.5) *12);
alert("Your yearly savings if you buy Trip Tickets is $" + prodBasett + ".");
}
}
// End Trip Tickets Savings Calc script -->
</script>
</head>
<body>
<form name="theForm4" class="calcform">
<h2>You Do the Math: Commuter Express Trip Tickets Vs. Cash</h2>
<div class="calcform-content">
<div class="formrow-calc">
<div class="calcform-col1">
<p>Days you commute on Commuter Express monthly:</p>
</div>
<div class="calcform-col2">
<input type="text">
</div>
<div class="calcform-col3"> </div>
</div>
<div class="clear"></div>
<div class="formrow-calc">
<div class="calcform-col1">
<p>Daily boardings on Commuter Express Bus:</p>
<table border="0" cellspacing="0" cellpadding="0" class="fareexampletable">
<tr>
<td colspan="2" class="savingsleft"><p class="ifyouride">EXAMPLE:</p></td>
</tr>
<tr>
<td class="savingsleft"><p><strong>Go to work:</strong></p></td>
<td class="savingsright"><p>1 time</p></td>
</tr>
<tr>
<td class="savingsleft"><p><strong>Come home from work:</strong></p></td>
<td class="additionline savingsright"><p>+1 time</p></td>
</tr>
<tr>
<td class="savingsleft"><p><strong>Total:</strong></p></td>
<td class="savingsright"><p>2 times</p></td>
</tr>
</table>
</div>
<div class="calcform-col2">
<input type="text">
</div>
<div class="calcform-col3"> </div>
</div>
<div class="clear"></div>
<div class="formrow-calc savings-zone">
<div class="calcform-col1">
<p>Choose Zone:</p>
</div>
<div class="calcform-col2">
<select name="zonett">
<option value="Base">Base</option>
<option value="z1">Zone 1</option>
<option value="z2">Zone 2</option>
<option value="z3">Zone 3</option>
<option value="z4">Zone 4</option>
</select>
</div>
</div>
<div class="formrow-calc">
<div class="calcform-col4-ce">
<button type="submit" onclick="doMath4()" class="btn-submit"><div class="btn-submit"><img src="img/btn_savings.png" alt="Show My Yearly Savings" /></div></button>
</div>
</div>
<div class="clear">
</div>
</div>
</form>
</body>
</html>
通常, 您需要四舍五入 ,因此可以一直保持數學准確性,直到顯示數據為止。
這是我實現您的小圖書館的方法:
var SavingsLib = {
round : function(val, digits) {
var pow = Math.pow(10, digits);
return Math.round(pow * val) / pow;
},
padCurrency : function (val) {
var str = val.toString();
var parts = str.split(".");
return parts.length > 1 && parts[1].length == 1 ? str + "0" : str;
},
processForm : function() {
var daysPerMonth = parseInt(document.theForm4.elements[0].value);
var boardingsPerDay = parseInt(document.theForm4.elements[1].value);
var zone = document.getElementsByName("zonett")[0].value;
var savings = 0;
if(zone == "z4") savings = this.calculateSavings(daysPerMonth, boardingsPerDay, 4.25, 3.75);
else if(zone == "z3") savings = this.calculateSavings(daysPerMonth, boardingsPerDay, 3.75, 3.35);
else if(zone == "z2") savings = this.calculateSavings(daysPerMonth, boardingsPerDay, 3, 2.8);
else if(zone == "z1") savings = this.calculateSavings(daysPerMonth, boardingsPerDay, 2.5, 2.3);
else if(zone == "Base") savings = this.calculateSavings(daysPerMonth, boardingsPerDay, 1.5, 1.5);
this.showMessage(savings);
return false; // Don't submit form
},
calculateSavings : function(daysPerMonth, boardingsPerDay, price1, price2) {
var amount1 = (((daysPerMonth * boardingsPerDay) * price1) * 12);
var amount2 = (((daysPerMonth * boardingsPerDay) * price2) * 12);
return this.round(amount1 - amount2, 2);
},
showMessage : function(savings) {
alert("Your yearly savings if you buy Trip Tickets is $" + this.padCurrency(savings));
}
}
我的變更:
1.4500001
變為1.45
而不是1
) 1.4
變為1.40
) 這很簡單 :
var prodZ4tt = Math.round(((one * two) * 4.25) *12) - (((one * two) * 3.75) *12);
盡管您可能會對語法感到困惑,這是可以理解的,但由於JavaScript以其直觀的做事方式而聞名。 ;)
注意:這會將數字四舍五入到最接近的整數,而不是“四舍五入”。
您可以使用Math.round編寫kludge,但這將使您不勝其煩(不確定在您的示例中是否適用,看起來好像可以)。 您可能想要的是固定的:
alert((102.000000004).toFixed(2)); // alerts "102.00"
這不是在IE中的四舍五入,但是根據我的判斷,這對您來說並不重要。
(docs: https : //developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number/toFixed,http : //www.codingforums.com/showthread.php ? t =102421 , http : //msdn.microsoft .com / zh-CN / library / sstyff0z.aspx )
編輯:打算將其放入評論中,但markdown在那里不起作用? 仍然習慣...
無論如何,如果您願意,也可以在Math.round中使用kludge:
alert(Math.round(val * 100) / 100);
仍然可能顯示愚蠢的浮動問題,您可以使用另一個.toFixed(現在您100%確信沒有剩余的小數位不能正確舍入):
alert((Math.round(val * 100) / 100).toFixed(2));
編輯:集成:
將其添加到腳本塊的頂部:
function roundNicely(val) {
return (Math.round(val * 100) / 100).toFixed(2);
}
然后在您的警報中,將值prodBasett
包裝在函數調用中: roundNicely(prodBasett)
(其他警報也類似)
那有意義嗎?
對於這種情況,當您需要精度時,您需要一個數學“任意精度庫” ...您可以在這里找到一篇不錯的文章。
http://blog.thatscaptaintoyou.com/introducing-big-js-arbitrary-precision-math-for-javascript/
Javascript本身具有round,ceil和floor來將浮點數轉換為整數。
var fl = 349.12783691847;
Math.round(fl) // 349
Math.ceil(f1) // 350
Math.floor(fl) // 349
當您進行數學運算時,優良作法是使用分布性,並正確使用括號。
Math.round(((((a + b) * (c - d)) % e) * f));
請注意“ NaN”(http://en.wikipedia.org/wiki/NaN)和非Number類型。
祝你今天愉快
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.