Skip to content

Commit

Permalink
Fix/inputnumber compare (#784)
Browse files Browse the repository at this point in the history
* chore(inputNumber): add unit test

* chore: ci add unit test

* fix: string and number equal
  • Loading branch information
uyarn authored Aug 30, 2022
1 parent 939e1fd commit c7678fd
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 14 deletions.
1 change: 1 addition & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
${{ runner.os }}-
- run: npm install
- run: npm run lint
- run: npm run test

modify:
runs-on: ubuntu-latest
Expand Down
33 changes: 27 additions & 6 deletions js/input-number/large-number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,10 @@ function compareLargeDecimalNumber(num1: string, num2: string) {
/**
* 比较两个大数的大小
*/
export function compareLargeNumber(num1: string | number, num2: string | number): 1 | -1 | 0 {
if (typeof num1 === 'number' || typeof num2 === 'number') {
if (num1 === num2) return 0;
return num1 > num2 ? 1 : -1;
}
export function compareLargeNumber(
num1: string,
num2: string,
): 1 | -1 | 0 {
const [integer1, decimal1] = num1.split('.');
const [integer2, decimal2] = num2.split('.');
const result = compareLargeIntegerNumber(integer1.replace('-', ''), integer2.replace('-', ''));
Expand All @@ -160,6 +159,28 @@ export function compareLargeNumber(num1: string | number, num2: string | number)
return result;
}

// 确认是否是大数
export function isSafeNumber(num: string | number) {
return Number(num) < Number.MAX_SAFE_INTEGER && Number(num) > Number.MIN_SAFE_INTEGER;
}

/**
* 比较两个数的大小
*/
export function compareNumber(
num1: string | number,
num2: string | number,
largeNumber?: boolean,
) {
if (isSafeNumber(num1) && isSafeNumber(num2) && !largeNumber) {
// 比较两个非大数的大小
if (Number(num1) === Number(num2)) return 0;
return Number(num1) > Number(num2) ? 1 : -1;
}
// 比较两个大数的大小
return compareLargeNumber(String(num1), String(num2));
}

/**
* 大数减法,仅支持整数
* @param num1 被减数
Expand Down Expand Up @@ -209,7 +230,7 @@ export function largeIntegerNumberSubtract(
*/
export function largePositiveNumberSubtract(num1: string, num2: string): string {
if (num1 === num2) return '0';
const isFirstLarger = compareLargeNumber(num1, num2) > 0;
const isFirstLarger = compareNumber(num1, num2, true) > 0;
const maxNumber = isFirstLarger ? num1 : num2;
const minNumber = isFirstLarger ? num2 : num1;
// 整数部分和小数部分分开处理
Expand Down
14 changes: 7 additions & 7 deletions js/input-number/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import isString from 'lodash/isString';
import isNumber from 'lodash/isNumber';
import {
compareLargeNumber,
compareNumber,
formatENumber,
largeNumberToFixed,
isInputNumber,
Expand All @@ -23,7 +23,7 @@ export function canAddNumber(
): boolean {
if (!num) return true;
if (largeNumber && isString(num)) {
return compareLargeNumber(num, max) < 0;
return compareNumber(num, max, largeNumber) < 0;
}
return num < max;
}
Expand All @@ -36,7 +36,7 @@ export function canReduceNumber(
): boolean {
if (!num) return true;
if (largeNumber && isString(num)) {
return compareLargeNumber(num, min) > 0;
return compareNumber(num, min, largeNumber) > 0;
}
return num > min;
}
Expand Down Expand Up @@ -89,8 +89,8 @@ export function putInRangeNumber(
const { max, min, lastValue, largeNumber } = params;
if (!isInputNumber(val)) return lastValue;
if (largeNumber && (isString(max) || max === Infinity) && (isString(min) || min === -Infinity)) {
if (compareLargeNumber(max, val) < 0) return max;
if (compareLargeNumber(min, val) > 0) return min;
if (compareNumber(max, val, largeNumber) < 0) return max;
if (compareNumber(min, val, largeNumber) > 0) return min;
return val;
}
return Math.max(Number(min), Math.min(Number(max), Number(val)));
Expand Down Expand Up @@ -219,9 +219,9 @@ export function getMaxOrMinValidateResult(p: {
log.warn('InputNumber', 'largeNumber value must be a string.');
}
let error: InputNumberErrorType;
if (compareLargeNumber(value, max) > 0) {
if (compareNumber(value, max, largeNumber) > 0) {
error = 'exceed-maximum';
} else if (compareLargeNumber(value, min) < 0) {
} else if (compareNumber(value, min, largeNumber) < 0) {
error = 'below-minimum';
} else {
error = undefined;
Expand Down
23 changes: 22 additions & 1 deletion test/unit/input-number/compareLargeNumber.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
import { compareLargeNumber, isInputNumber, formatENumber } from '../../../js/input-number/large-number';
import { compareNumber, compareLargeNumber, isInputNumber, formatENumber } from '../../../js/input-number/large-number';

describe('compareNumber', () => {
it('number 2, string 2', () => {
expect(compareNumber('2', 2)).toBe(0);
});
it('string 1234567891234567890, string 1234567891234567891', () => {
expect(compareNumber('1234567891234567890', '1234567891234567891')).toBe(-1);
});

it('string 1234567891234567890, number 1234567891234567891', () => {
expect(compareNumber('1234567891234567890', 1234567891234567891)).toBe(-1);
});

it('number 1234567891234567891, string 1234567891234567890', () => {
expect(compareNumber(1234567891234567891, '1234567891234567890')).toBe(1);
});

it('number 1234567891234567891, string 1234567891234567890', () => {
expect(compareNumber(1234567891234567891, '1234567891234567890')).toBe(1);
});
});

describe('compareLargeNumber', () => {
it('0.1, 0.2', () => {
Expand Down

0 comments on commit c7678fd

Please sign in to comment.