Skip to content

Commit

Permalink
fix: should process 0 correctly when precision is 0
Browse files Browse the repository at this point in the history
  • Loading branch information
wanghao committed Jan 1, 2022
1 parent d3de147 commit c9046a6
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 36 deletions.
9 changes: 4 additions & 5 deletions src/InputNumber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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));
}
};

Expand Down
29 changes: 11 additions & 18 deletions src/utils/MiniDecimal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down
5 changes: 5 additions & 0 deletions tests/input.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
27 changes: 14 additions & 13 deletions tests/util.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import getMiniDecimal, {
BigIntDecimal,
DecimalClass,
NumberDecimal,
roundDownUnsignedDecimal,
roundUpUnsignedDecimal,
roundUnsignedDecimal,
toFixed,
ValueType,
} from '../src/utils/MiniDecimal';
Expand Down Expand Up @@ -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');
})
});
});

0 comments on commit c9046a6

Please sign in to comment.