diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index 541be08f..1c8a0341 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -4,8 +4,7 @@ import KeyCode from 'rc-util/lib/KeyCode'; import { composeRef } from 'rc-util/lib/ref'; import getMiniDecimal, { DecimalClass, - roundDownUnsignedDecimal, - roundUpUnsignedDecimal, + roundUnsignedDecimal, toFixed, ValueType } from './utils/MiniDecimal'; @@ -46,11 +45,11 @@ const getDecimalIfValidate = (value: ValueType, precision: number | undefined, i const {negative, integerStr, decimalStr, negativeStr} = trimNumber(decimal.toString()); const unSignedNumberStr = integerStr +'.' + decimalStr; - + if ((isMax && !negative) || (!isMax && negative)) { - return getMiniDecimal(negativeStr + roundDownUnsignedDecimal(unSignedNumberStr, precision)); + return getMiniDecimal(negativeStr + roundUnsignedDecimal(unSignedNumberStr, precision, false)); } else { - return getMiniDecimal(negativeStr + roundUpUnsignedDecimal(unSignedNumberStr, precision)); + return getMiniDecimal(negativeStr + roundUnsignedDecimal(unSignedNumberStr, precision, true)); } }; diff --git a/src/utils/MiniDecimal.ts b/src/utils/MiniDecimal.ts index 6088b861..9fd57579 100644 --- a/src/utils/MiniDecimal.ts +++ b/src/utils/MiniDecimal.ts @@ -266,27 +266,20 @@ export default function getMiniDecimal(value: ValueType): DecimalClass { /** * round up an unsigned number str, like: 1.4 -> 2, 1.5 -> 2 + * Or round down an unsigned number str, like: 1.4 -> 1, 1.5 -> 1 */ -export function roundUpUnsignedDecimal(numStr: string, precision: number) { +export function roundUnsignedDecimal(numStr: string, precision: number, roundUp: boolean) { const {integerStr, decimalStr} = trimNumber(numStr); - const advancedDecimal = getMiniDecimal(integerStr + '.' + decimalStr).add( - `0.${'0'.repeat(precision)}${5}`, - ); - return toFixed(advancedDecimal.toString(), '.', precision); -} -/** - * round up an unsigned number str, like: 1.4 -> 1, 1.5 -> 1 - */ -export function roundDownUnsignedDecimal(numStr: string, precision: number) { - const {negativeStr, integerStr, decimalStr} = trimNumber(numStr); - const numberWithoutDecimal = `${negativeStr}${integerStr}`; - if (precision === 0) { - return integerStr; - } - return `${numberWithoutDecimal}.${decimalStr - .padEnd(precision, '0') - .slice(0, precision)}`; + // round up decimal part + const times = Math.pow(10, precision); + + const roundFn = roundUp ? Math.ceil : Math.floor; + const decimalPart = roundFn(parseFloat(`0.${decimalStr}`) * times) / times; + // add decimal part and integer part + const advancedDecimal = getMiniDecimal(integerStr).add(decimalPart); + + return toFixed(advancedDecimal.toString(), '.', precision); } /** diff --git a/tests/input.test.tsx b/tests/input.test.tsx index be4b98b2..a28cb359 100644 --- a/tests/input.test.tsx +++ b/tests/input.test.tsx @@ -59,6 +59,11 @@ describe('InputNumber.Input', () => { expect(wrapper.getInputValue()).toEqual('-98'); }); + it('input zero and precision is 0', () => { + const wrapper = prepareWrapper('0', {min: 0, precision: 0}); + expect(wrapper.getInputValue()).toEqual('0'); + }); + it('negative min with higher precision', () => { const wrapper = prepareWrapper('-4', {min: -3.5, precision: 0}); expect(wrapper.getInputValue()).toEqual('-3'); diff --git a/tests/util.test.tsx b/tests/util.test.tsx index a6702608..ffe7191e 100644 --- a/tests/util.test.tsx +++ b/tests/util.test.tsx @@ -2,8 +2,7 @@ import getMiniDecimal, { BigIntDecimal, DecimalClass, NumberDecimal, - roundDownUnsignedDecimal, - roundUpUnsignedDecimal, + roundUnsignedDecimal, toFixed, ValueType, } from '../src/utils/MiniDecimal'; @@ -154,19 +153,21 @@ describe('InputNumber.Util', () => { }); it('round down', () => { - expect(roundDownUnsignedDecimal('77.89', 1)).toEqual('77.8'); - expect(roundDownUnsignedDecimal('77.1', 2)).toEqual('77.10'); - expect(roundDownUnsignedDecimal('77.81', 1)).toEqual('77.8'); - expect(roundDownUnsignedDecimal('77.50', 1)).toEqual('77.5'); - expect(roundDownUnsignedDecimal('77.5999', 0)).toEqual('77'); - expect(roundDownUnsignedDecimal('77.0001', 0)).toEqual('77'); + expect(roundUnsignedDecimal('0', 0, false)).toEqual('0'); + expect(roundUnsignedDecimal('77.89', 1, false)).toEqual('77.8'); + expect(roundUnsignedDecimal('77.1', 2, false)).toEqual('77.10'); + expect(roundUnsignedDecimal('77.81', 1, false)).toEqual('77.8'); + expect(roundUnsignedDecimal('77.50', 1, false)).toEqual('77.5'); + expect(roundUnsignedDecimal('77.5999', 0, false)).toEqual('77'); + expect(roundUnsignedDecimal('77.0001', 0, false)).toEqual('77'); }) it('round up', () => { - expect(roundUpUnsignedDecimal('77.89', 1)).toEqual('77.9'); - expect(roundUpUnsignedDecimal('77.81', 1)).toEqual('77.9'); - expect(roundUpUnsignedDecimal('77.89', 0)).toEqual('78'); - expect(roundUpUnsignedDecimal('77.599', 0)).toEqual('78'); - expect(roundUpUnsignedDecimal('77.01', 0)).toEqual('78'); + expect(roundUnsignedDecimal('0', 0, true)).toEqual('0'); + expect(roundUnsignedDecimal('77.89', 1, true)).toEqual('77.9'); + expect(roundUnsignedDecimal('77.81', 1,true)).toEqual('77.9'); + expect(roundUnsignedDecimal('77.89', 0,true)).toEqual('78'); + expect(roundUnsignedDecimal('77.599', 0,true)).toEqual('78'); + expect(roundUnsignedDecimal('77.01', 0,true)).toEqual('78'); }) }); });