这一行代码把数字四舍五入到小数点后两位。但我得到的数字是这样的:10.8、2.4等等。这些都不是我的小数点后两位的想法,所以我怎么能改善以下?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);

我想要10.80、2.40等数字。jQuery的使用对我来说很好。


当前回答

浮点值的问题在于,它们试图用固定数量的比特表示无限数量的(连续的)值。所以自然地,在游戏中一定会有一些损失,你会被一些价值观咬伤。

当计算机将1.275存储为浮点值时,它实际上不会记住它是1.275还是1.27499999999999993,甚至是1.27500000000000002。这些值在四舍五入到两个小数后应该会给出不同的结果,但它们不会,因为对于计算机来说,它们存储为浮点值后看起来完全相同,并且没有办法恢复丢失的数据。任何进一步的计算只会积累这样的不精确性。

因此,如果精度很重要,就必须从一开始就避免使用浮点值。最简单的选择是

使用专门的图书馆 使用字符串存储和传递值(附带字符串操作) 使用整数(例如,你可以传递实际值的百分之一,例如,用美分代替美元)

例如,当使用整数存储百分位数时,查找实际值的函数非常简单:

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));

注意,这个函数舍入到最近邻,与零绑定,而IEEE 754建议舍入到最近邻,与偶数绑定,作为浮点运算的默认行为。这样的修改留给读者练习:)

其他回答

toFixed(n)提供小数点后的n个长度;toPrecision (x) 总长度为x。

使用下面的方法

// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
    // It will round to the tenths place
    num = 500.2349;
    result = num.toPrecision(4); // result will equal 500.2

如果你想要固定的号码,可以使用

result = num.toFixed(2);

下面是https://stackoverflow.com/a/21323330/916734的TypeScript实现。它还使用了函数,并允许可选的数字偏移量。

export function round(rawValue: number | string, precision = 0, fractionDigitOffset = 0): number | string {
  const value = Number(rawValue);
  if (isNaN(value)) return rawValue;

  precision = Number(precision);
  if (precision % 1 !== 0) return NaN;

  let [ stringValue, exponent ] = scientificNotationToParts(value);

  let shiftExponent = exponentForPrecision(exponent, precision, Shift.Right);
  const enlargedValue = toScientificNotation(stringValue, shiftExponent);
  const roundedValue = Math.round(enlargedValue);

  [ stringValue, exponent ] = scientificNotationToParts(roundedValue);
  const precisionWithOffset = precision + fractionDigitOffset;
  shiftExponent = exponentForPrecision(exponent, precisionWithOffset, Shift.Left);

  return toScientificNotation(stringValue, shiftExponent);
}

enum Shift {
  Left = -1,
  Right = 1,
}

function scientificNotationToParts(value: number): Array<string> {
  const [ stringValue, exponent ] = value.toString().split('e');
  return [ stringValue, exponent ];
}

function exponentForPrecision(exponent: string, precision: number, shift: Shift): number {
  precision = shift * precision;
  return exponent ? (Number(exponent) + precision) : precision;
}

function toScientificNotation(value: string, exponent: number): number {
  return Number(`${value}e${exponent}`);
}

一轮下来

function round_down(value, decPlaces) {
    return Math.floor(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

围捕

function round_up(value, decPlaces) {
    return Math.ceil(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

圆的

function round_nearest(value, decPlaces) {
    return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

合并https://stackoverflow.com/a/7641824/1889449和 https://www.kirupa.com/html5/rounding_numbers_in_javascript.htm谢谢 他们。

@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
    });
});

​ 在线演示:

http://jsfiddle.net/c4Wqn/

100%的工作! !试一试

<html> <head> <script> function replacePonto(){ var input = document.getElementById('qtd'); var ponto = input.value.split('.').length; var slash = input.value.split('-').length; if (ponto > 2) input.value=input.value.substr(0,(input.value.length)-1); if(slash > 2) input.value=input.value.substr(0,(input.value.length)-1); input.value=input.value.replace(/[^0-9.-]/,''); if (ponto ==2) input.value=input.value.substr(0,(input.value.indexOf('.')+3)); if(input.value == '.') input.value = ""; } </script> </head> <body> <input type="text" id="qtd" maxlength="10" style="width:140px" onkeyup="return replacePonto()"> </body> </html>