Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/inputnumber compare #784

Merged
merged 3 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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