我有一行代码可以将数字四舍五入到两位小数。但是,我得到的数字像这样:10.8、2.4等。这不是我认为的两位小数,请问如何改进以下代码?
Math.round(price*Math.pow(10,2))/Math.pow(10,2);
我希望得到像10.80、2.40这样的数字。使用jQuery也可以。
我有一行代码可以将数字四舍五入到两位小数。但是,我得到的数字像这样:10.8、2.4等。这不是我认为的两位小数,请问如何改进以下代码?
Math.round(price*Math.pow(10,2))/Math.pow(10,2);
我希望得到像10.80、2.40这样的数字。使用jQuery也可以。
这是一个简单的例子
。function roundFloat(num,dec){
var d = 1;
for (var i=0; i<dec; i++){
d += "0";
}
return Math.round(num * d) / d;
}
使用方法如下:alert(roundFloat(1.79209243929,4));
点击此处查看示例。
function descale(num, decimals) {
var hasMinus = num < 0;
var numString = Math.abs(num).toString();
var precedingZeroes = '';
for (var i = numString.length; i <= decimals; i++) {
precedingZeroes += '0';
}
numString = precedingZeroes + numString;
return (hasMinus ? '-' : '')
+ numString.substr(0, numString.length-decimals)
+ '.'
+ numString.substr(numString.length-decimals);
}
alert(descale(127, 2));
使用字符串,您仍然需要进行四舍五入,但它仍然可操作:
function precise_round(num, decimals) {
var parts = num.split('.');
var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
var decimalPart = parts.length > 1 ? parts[1] : '';
if (decimalPart.length > decimals) {
var roundOffNumber = decimalPart.charAt(decimals);
decimalPart = decimalPart.substr(0, decimals);
if ('56789'.indexOf(roundOffNumber) > -1) {
var numbers = integralPart + decimalPart;
var i = numbers.length;
var trailingZeroes = '';
var justOneAndTrailingZeroes = true;
do {
i--;
var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
if (roundedNumber === '0') {
trailingZeroes += '0';
} else {
numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
justOneAndTrailingZeroes = false;
break;
}
} while (i > 0);
if (justOneAndTrailingZeroes) {
numbers = '1' + trailingZeroes;
}
integralPart = numbers.substr(0, numbers.length - decimals);
decimalPart = numbers.substr(numbers.length - decimals);
}
} else {
for (var i = decimalPart.length; i < decimals; i++) {
decimalPart += '0';
}
}
return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}
alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));
precise_round("999999999999999999.9999", 2)
returns
"1000000000000000000.00"
- FaizanHussainRabbani999999999999999999.99
。 - FaizanHussainRabbani@heridev和我在jQuery中创建了一个小函数。
你可以尝试下面的代码:
HTML
<input type="text" name="one" class="two-digits"><br>
<input type="text" name="two" class="two-digits">
jQuery
// apply the two-digits behaviour to elements with 'two-digits' as their class
$( function() {
$('.two-digits').keyup(function(){
if($(this).val().indexOf('.')!=-1){
if($(this).val().split(".")[1].length > 2){
if( isNaN( parseFloat( this.value ) ) ) return;
this.value = parseFloat(this.value).toFixed(2);
}
}
return this; //for chaining
});
});
使用这些示例在尝试将数字1.005四舍五入时仍会出现错误,解决方法是使用类似Math.js的库或此函数:
function round(value: number, decimals: number) {
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}
round(num * p) / p
天真的实现function naiveRound(num, decimalPlaces) {
var p = Math.pow(10, decimalPlaces);
return Math.round(num * p) / p;
}
console.log( naiveRound(1.245, 2) ); // 1.25 correct (rounded as expected)
console.log( naiveRound(1.255, 2) ); // 1.25 incorrect (should be 1.26)
round(-1.005, 2)
计算结果为-1
,即使round(1.005, 2)
的计算结果为1.01
。lodash 的 _.round 方法使用此技术。
/**
* Round half up ('round half towards positive infinity')
* Uses exponential notation to avoid floating-point issues.
* Negative numbers round differently than positive numbers.
*/
function round(num, decimalPlaces) {
num = Math.round(num + "e" + decimalPlaces);
return Number(num + "e" + -decimalPlaces);
}
// test rounding of half
console.log( round(0.5, 0) ); // 1
console.log( round(-0.5, 0) ); // 0
// testing edge cases
console.log( round(1.005, 2) ); // 1.01
console.log( round(2.175, 2) ); // 2.18
console.log( round(5.015, 2) ); // 5.02
console.log( round(-1.005, 2) ); // -1
console.log( round(-2.175, 2) ); // -2.17
console.log( round(-5.015, 2) ); // -5.01
// Round half away from zero
function round(num, decimalPlaces) {
num = Math.round(Math.abs(num) + "e" + decimalPlaces) * Math.sign(num);
return Number(num + "e" + -decimalPlaces);
}
/**
* Round half away from zero ('commercial' rounding)
* Uses correction to offset floating-point inaccuracies.
* Works symmetrically for positive and negative numbers.
*/
function round(num, decimalPlaces) {
var p = Math.pow(10, decimalPlaces);
var e = Number.EPSILON * num * p;
return Math.round((num * p) + e) / p;
}
// test rounding of half
console.log( round(0.5, 0) ); // 1
console.log( round(-0.5, 0) ); // -1
// testing edge cases
console.log( round(1.005, 2) ); // 1.01
console.log( round(2.175, 2) ); // 2.18
console.log( round(5.015, 2) ); // 5.02
console.log( round(-1.005, 2) ); // -1.01
console.log( round(-2.175, 2) ); // -2.18
console.log( round(-5.015, 2) ); // -5.02
1.005
被编码为64位二进制浮点数的1.0049999999999999
;而1234567.005
被编码为64位二进制浮点数的1234567.0049999998882413
。舍入误差
取决于(1)数值的大小和(2)相对机器epsilon(2^-52)。将您的小数值四舍五入,然后对其使用toFixed(x)
函数以得到您期望的数字。
function parseDecimalRoundAndFixed(num,dec){
var d = Math.pow(10,dec);
return (Math.round(num * d) / d).toFixed(dec);
}
调用
parseDecimalRoundAndFixed(10.800243929,4) => 10.80 parseDecimalRoundAndFixed(10.807243929,2) => 10.81
这是我的一行解决方案:Number((yourNumericValueHere).toFixed(2));
以下是具体步骤:
1)首先,将.toFixed(2)
应用于您想要舍入小数位的数字。请注意,这将把该值从数字转换为字符串。因此,如果您正在使用Typescript,则会出现如下错误:
"Type 'string' is not assignable to type 'number'"
2)要获取数字值或将字符串转换为数字值,只需对所谓的“字符串”值应用Number()
函数即可。
为了更好地理解,请看以下示例:
示例: 我有一个金额,其小数点后有5位数字,我想将其缩短到最多2位小数。我可以这样做:
var price = 0.26453;
var priceRounded = Number((price).toFixed(2));
console.log('Original Price: ' + price);
console.log('Price Rounded: ' + priceRounded);
fixPrecision: function (value) {
var me = this,
nan = isNaN(value),
precision = me.decimalPrecision;
if (nan || !value) {
return nan ? '' : value;
} else if (!me.allowDecimals || precision <= 0) {
precision = 0;
}
//[1]
//return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
precision = precision || 0;
var negMultiplier = value < 0 ? -1 : 1;
//[2]
var numWithExp = parseFloat(value + "e" + precision);
var roundedNum = parseFloat(Math.round(Math.abs(numWithExp)) + 'e-' + precision) * negMultiplier;
return parseFloat(roundedNum.toFixed(precision));
},
我也有一些代码注释(抱歉,我已经忘记了所有的细节)...我在这里发布我的答案供将来参考:
9.995 * 100 = 999.4999999999999
Whereas 9.995e2 = 999.5
This discrepancy causes Math.round(9.995 * 100) = 999 instead of 1000.
Use e notation instead of multiplying /dividing by Math.Pow(10,precision).
在某个全局作用域中放置以下内容:
Number.prototype.getDecimals = function ( decDigCount ) {
return this.toFixed(decDigCount);
}
然后尝试:
var a = 56.23232323;
a.getDecimals(2); // will return 56.23
请注意,toFixed()
只能用于小数位数在 0-20
之间的数字,例如 a.getDecimals(25)
可能会生成 JavaScript 错误,因此您可以添加一些额外的检查来适应这种情况。
Number.prototype.getDecimals = function ( decDigCount ) {
return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}
number.toFixed(x)
方法将其转换为具有所需零数量的字符串。例如,使用跨浏览器方法将1.34
舍入为1.3
,然后添加1个零并使用1.3.toFixed(2)
转换为字符串(以获取"1.30"
)。 - Edward