El precio total debe redondearse a 5 centavos de acuerdo con las siguientes reglas.
Se me ocurrió el siguiente enfoque, pero parece pesado y me pregunto si alguien tiene una idea mejor.
var divisionValue = 0.05; if (number > 0 && number < divisionValue) { return divisionValue; } var roundedNumber = number; var division = roundedNumber / divisionValue; var divisionFormatted = +(division).toFixed(2); var moduloRemainder = divisionFormatted % 1; var divisionRemainderFormatted = +(moduloRemainder).toFixed(2); // When there is no remainder, the value ends with 0.05 or 0.1 if (divisionRemainderFormatted === 0) { return roundedNumber; } else if (divisionRemainderFormatted !== 0) { var diff = divisionFormatted - divisionRemainderFormatted; if (diff % 2) { // For values ending with 0.06 to 0.09 round up roundedNumber = Math.ceil(number * 10) / 10; } else { // For values ending with 0.01 to 0.04 round up roundedNumber = Math.floor(number * 10) / 10; } } return +(roundedNumber).toFixed(2Prueba
it('Slovak rounding to 5 eurocents', function () { // not round expect(MathService.roundToFiveEurocent(23)).toBe(23); expect(MathService.roundToFiveEurocent(23.1)).toBe(23.10); expect(MathService.roundToFiveEurocent(23.15)).toBe(23.15); // round down expect(MathService.roundToFiveEurocent(23.11)).toBe(23.10); expect(MathService.roundToFiveEurocent(23.12)).toBe(23.10); expect(MathService.roundToFiveEurocent(23.13)).toBe(23.10); expect(MathService.roundToFiveEurocent(23.14)).toBe(23.10); // round up expect(MathService.roundToFiveEurocent(23.17)).toBe(23.20); expect(MathService.roundToFiveEurocent(23.18)).toBe(23.20); expect(MathService.roundToFiveEurocent(23.19)).toBe(23.20); // round to 0.05 expect(MathService.roundToFiveEurocent(0.01)).toBe(0.05); expect(MathService.roundToFiveEurocent(0.02)).toBe(0.05); expect(MathService.roundToFiveEurocent(0.03)).toBe(0.05); expect(MathService.roundToFiveEurocent(0.04)).toBe(0.05); });Entonces, básicamente, necesitas jugar agregando 0.05 y definiendo tus excepciones
// not round values = [ [23, 23], [23.1, 23.10], [23.15, 23.15], // round down [23.11, 23.10], [23.12, 23.10], [23.13, 23.10], [23.14, 23.10], // round up [23.17, 23.20], [23.18, 23.20], [23.19, 23.20], // round to 0.05 [0.01, 0.05], [0.02, 0.05], [0.03, 0.05], [0.04, 0.05] ] function test_round(val) { to_round = parseFloat(val).toFixed(2) if (to_round < 0.05) return 0.05 ref = to_round * 10 if (ref - parseInt(ref) == 0.5) return to_round temp = parseFloat(to_round) + 0.05; clean = parseFloat(parseInt(temp * 10) / 10) return clean } function test(_vals) { for (v of _vals) { if (v[1] != test_round(v[0])) { console.log(['Failed rounding', '-', v, '-', test_round(v[0])].join(' ')) } } } test(values)Aquí hay una sola línea...
function rt5( x ) {return x < 0 ? null : 0 < x && x < 0.05 ? 0.05 : x * 20 % 1 === 0 ? x : Math.floor( ( x + 0.05 ) / 0.1 ) * 2 / 20 } console.log( `rt5( 0.02 ) = ${rt5(0.02)}` ); console.log( `rt5( 0.14 ) = ${rt5(0.14)}` ); console.log( `rt5( 0.15 ) = ${rt5(0.15)}` ); console.log( `rt5( 0.16 ) = ${rt5(0.16)}` ); console.log( `rt5( 999999999999.94 ) = ${rt5(999999999999.94)}` ); console.log( `rt5( 999999999999.95 ) = ${rt5(999999999999.95)}` ); console.log( `rt5( 999999999999.96 ) = ${rt5(999999999999.96)}` ); console.log( `rt5( -1.05 ) = ${rt5(-1.05)}` );