我想最多四舍五入两位小数,但只有在必要时。

输入:

10
1.7777777
9.1

输出:

10
1.78
9.1

如何在JavaScript中执行此操作?


当前回答

如果您需要将货币金额格式化为整数货币或包含小数货币部分的金额,则会有一点不同。

例如:

1应输出$1

1.1应产出1.10美元

1.01应产出1.01美元

假设金额是一个数字:

常量格式amount=(amount)=>amount%1==0?amount:amount.toFixed(2);

如果amount不是数字,则使用parseFloat(amount)将其转换为数字。

其他回答

有一种解决方案适用于所有数字。试试看。表达式如下所示。

Math.round((num + 0.00001) * 100) / 100. 

Try Below Ex:

Math.round((1.005 + 0.00001) * 100) / 100 
Math.round((1.0049 + 0.00001) * 100) / 100

我最近测试了所有可能的解决方案,并在尝试了近10次后最终得出了结果。

这是计算过程中出现的问题的屏幕截图,

.

转到金额字段。它几乎无限地回归。我尝试了toFixed()方法,但它在某些情况下不起作用(例如,尝试使用pi),最后导出了上面给出的解决方案。

我的解决方案将输入视为字符串,并使用n位数字的“数学舍入”算法:取n位数字,如果数字n+1等于或大于5,则加1。它还允许指定负数,例如,将123.45舍入为-1的数字为120。它也适用于科学符号(例如1.2e-3)。我没有测量它的速度,我认为这不是最好的表现。

function safeRound( numInput, numPrecision ) {
    const strNumber = numInput.toString().replace( 'E', 'e' );
    const bSign = '+-'.indexOf( strNumber[ 0 ] ) !== -1;
    const strSign = bSign  ?  strNumber[ 0 ]  :  '';
    const numSign = strSign !== '-'  ?  +1  :  -1;
    const ixExponent = ( ixFound => ixFound !== -1  ?  ixFound  :  strNumber.length )( strNumber.indexOf( 'e' ) );
    const strExponent = strNumber.substr( ixExponent + 1 );
    const numExponent = ixExponent !== strNumber.length  ?  Number.parseInt( strExponent )  :  0;
    const ixDecimal = ( ixFound => ixFound !== -1  ?  ixFound  :  ixExponent )( strNumber.indexOf( '.' ) );
    const strInteger = strNumber.substring( !bSign  ?  0  :  1, ixDecimal );
    const strFraction = strNumber.substring( ixDecimal + 1, ixExponent );
    
    const numPrecisionAdjusted = numPrecision + numExponent;
    const strIntegerKeep = strInteger.substring( 0, strInteger.length + Math.min( 0, numPrecisionAdjusted ) ) + '0'.repeat( -Math.min( 0, numPrecisionAdjusted ) );
    const strFractionKeep = strFraction.substring( 0, Math.max( 0, numPrecisionAdjusted ) );
    const strRoundedDown = strSign + ( strIntegerKeep === ''  ?  '0'  :  strIntegerKeep ) + ( strFractionKeep === ''  ?  ''  :  '.' + strFractionKeep ) + ( strExponent === ''  ?  ''  :  'e' + strExponent );
    
    const chRoundUp = 0 <= numPrecisionAdjusted  ?  strFraction.substr( numPrecisionAdjusted, 1 )  :  ( '0' + strInteger ).substr( numPrecisionAdjusted, 1 );
    const bRoundUp = '5' <= chRoundUp && chRoundUp <= '9';
    const numRoundUp = bRoundUp  ?  numSign * Math.pow( 10, -numPrecision )  :  0;
    
    return Number.parseFloat( strRoundedDown ) + numRoundUp;
}

function safeRoundTest( numInput, numPrecision, strExpected ) {
    const strActual = safeRound( numInput, numPrecision ).toString();
    const bPassed = strActual === strExpected;
    console.log( 'numInput', numInput, 'numPrecision', numPrecision, 'strExpected', strExpected, 'strActual', strActual, 'bPassed', bPassed );
    return bPassed  ?  0  :  1;
}

function safeRoundTests() {
    let numFailed = 0;
    numFailed += safeRoundTest( 0, 0, '0' );
    numFailed += safeRoundTest( '0', 0, '0' );
    numFailed += safeRoundTest( '0.1', 0, '0' );
    numFailed += safeRoundTest( '+0.1', 0, '0' );
    numFailed += safeRoundTest( '-0.1', 0, '0' );
    numFailed += safeRoundTest( '0.1', 1, '0.1' );
    numFailed += safeRoundTest( '+0.1', 1, '0.1' );
    numFailed += safeRoundTest( '-0.1', 1, '-0.1' );
    numFailed += safeRoundTest( '0.9', 0, '1' );
    numFailed += safeRoundTest( '+0.9', 0, '1' );
    numFailed += safeRoundTest( '-0.9', 0, '-1' );
    numFailed += safeRoundTest( '0.9', 1, '0.9' );
    numFailed += safeRoundTest( '+0.9', 1, '0.9' );
    numFailed += safeRoundTest( '-0.9', 1, '-0.9' );
    numFailed += safeRoundTest( '0.5', 0, '1' );
    numFailed += safeRoundTest( '+0.5', 0, '1' );
    numFailed += safeRoundTest( '-0.5', 0, '-1' );
    numFailed += safeRoundTest( '0.4999', 0, '0' );
    numFailed += safeRoundTest( '+0.4999', 0, '0' );
    numFailed += safeRoundTest( '-0.4999', 0, '0' );
    numFailed += safeRoundTest( '1.005', 2, '1.01' );
    numFailed += safeRoundTest( '1.00499999999', 2, '1' );
    numFailed += safeRoundTest( '012.3456', -4, '0' );
    numFailed += safeRoundTest( '012.3456', -3, '0' );
    numFailed += safeRoundTest( '012.3456', -2, '0' );
    numFailed += safeRoundTest( '012.3456', -1, '10' );
    numFailed += safeRoundTest( '012.3456', 0, '12' );
    numFailed += safeRoundTest( '012.3456', 1, '12.3' );
    numFailed += safeRoundTest( '012.3456', 2, '12.35' );
    numFailed += safeRoundTest( '012.3456', 3, '12.346' );
    numFailed += safeRoundTest( '012.3456', 4, '12.3456' );
    numFailed += safeRoundTest( '012.3456', 5, '12.3456' );
    numFailed += safeRoundTest( '12.', 0, '12' );
    numFailed += safeRoundTest( '.12', 2, '0.12' );
    numFailed += safeRoundTest( '0e0', 0, '0' );
    numFailed += safeRoundTest( '1.2e3', 0, '1200' );
    numFailed += safeRoundTest( '1.2e+3', 0, '1200' );
    numFailed += safeRoundTest( '1.2e-3', 0, '0' );
    numFailed += safeRoundTest( '1.2e-3', 3, '0.001' );
    numFailed += safeRoundTest( '1.2e-3', 4, '0.0012' );
    numFailed += safeRoundTest( '1.2e-3', 5, '0.0012' );
    numFailed += safeRoundTest( '+12.', 0, '12' );
    numFailed += safeRoundTest( '+.12', 2, '0.12' );
    numFailed += safeRoundTest( '+0e0', 0, '0' );
    numFailed += safeRoundTest( '+1.2e3', 0, '1200' );
    numFailed += safeRoundTest( '+1.2e+3', 0, '1200' );
    numFailed += safeRoundTest( '+1.2e-3', 0, '0' );
    numFailed += safeRoundTest( '+1.2e-3', 3, '0.001' );
    numFailed += safeRoundTest( '+1.2e-3', 4, '0.0012' );
    numFailed += safeRoundTest( '+1.2e-3', 5, '0.0012' );
    numFailed += safeRoundTest( '-12.', 0, '-12' );
    numFailed += safeRoundTest( '-.12', 2, '-0.12' );
    numFailed += safeRoundTest( '-0e0', 0, '0' );
    numFailed += safeRoundTest( '-1.2e3', 0, '-1200' );
    numFailed += safeRoundTest( '-1.2e+3', 0, '-1200' );
    numFailed += safeRoundTest( '-1.2e-3', 0, '0' );
    numFailed += safeRoundTest( '-1.2e-3', 3, '-0.001' );
    numFailed += safeRoundTest( '-1.2e-3', 4, '-0.0012' );
    numFailed += safeRoundTest( '-1.2e-3', 5, '-0.0012' );
    numFailed += safeRoundTest( '9876.543e210', 0, '9.876543e+213' );
    numFailed += safeRoundTest( '9876.543e210', -210, '9.877e+213' );
    numFailed += safeRoundTest( '9876.543e210', -209, '9.8765e+213' );
    numFailed += safeRoundTest( '9876.543e+210', 0, '9.876543e+213' );
    numFailed += safeRoundTest( '9876.543e+210', -210, '9.877e+213' );
    numFailed += safeRoundTest( '9876.543e+210', -209, '9.8765e+213' );
    numFailed += safeRoundTest( '9876.543e-210', 213, '9.876543e-207' );
    numFailed += safeRoundTest( '9876.543e-210', 210, '9.877e-207' );
    numFailed += safeRoundTest( '9876.543e-210', 211, '9.8765e-207' );
    console.log( 'numFailed', numFailed );
}

safeRoundTests();

这对我(TypeScript)起到了作用:

round(decimal: number, decimalPoints: number): number{
    let roundedValue = Math.round(decimal * Math.pow(10, decimalPoints)) / Math.pow(10, decimalPoints);

    console.log(`Rounded ${decimal} to ${roundedValue}`);
    return roundedValue;
}

样本输出

Rounded 18.339840000000436 to 18.34
Rounded 52.48283999999984 to 52.48
Rounded 57.24612000000036 to 57.25
Rounded 23.068320000000142 to 23.07
Rounded 7.792980000000398 to 7.79
Rounded 31.54157999999981 to 31.54
Rounded 36.79686000000004 to 36.8
Rounded 34.723080000000124 to 34.72
Rounded 8.4375 to 8.44
Rounded 15.666960000000074 to 15.67
Rounded 29.531279999999924 to 29.53
Rounded 8.277420000000006 to 8.28

问题是四舍五入到两位小数。

让我们不要把这个复杂化,修改原型链等。

以下是单线解决方案

让round2dec=num=>数学舍入(num*100)/100;控制台日志(round2dec(1.77));控制台日志(round2dec(1.774));控制台日志(round2dec(1.777));console.log(round2dec(10));

这是astorije的答案的修改版本,更好地支持负值舍入。

// https://stackoverflow.com/a/21323513/384884
// Modified answer from astorije
function round(value, precision) {
    // Ensure precision exists
    if (typeof precision === "undefined" || +precision === 0) {
        // Just do a regular Math.round
        return Math.round(value);
    }

    // Convert the value and precision variables both to numbers
    value = +value;
    precision = +precision;

    // Ensure the value is a number and that precision is usable
    if (isNaN(value) || !(typeof precision === "number" && precision % 1 === 0)) {
        // Return NaN
        return NaN;
    }

    // Get the sign of value
    var signValue = Math.sign(value);

    // Get the absolute value of value
    value = Math.abs(value);

    // Shift
    value = value.toString().split("e");
    value = Math.round(+(value[0] + "e" + (value[1] ? (+value[1] + precision) : precision)));

    // Shift back
    value = value.toString().split("e");
    value = +(value[0] + "e" + (value[1] ? (+value[1] - precision) : -precision));

    // Apply the sign
    value = value * signValue;

    // Return rounded value
    return value;
}