mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-02-23 02:02:18 +01:00
feat(utils): add a util for float approx comparison
This commit is contained in:
committed by
Jiri Zbytovsky
parent
7ae05a7602
commit
24f4d182bc
@@ -32,6 +32,7 @@ export * from './getWeakRandomNumberInRange';
|
||||
export * from './hasUppercaseLetter';
|
||||
export { hexToRgba } from './hexToRgba';
|
||||
export { hexToRgbaArray } from './hexToRgbaArray';
|
||||
export { isApproximatelyEqual } from './isApproximatelyEqual';
|
||||
export * from './isArrayMember';
|
||||
export * from './isFullPath';
|
||||
export * from './isHex';
|
||||
|
||||
24
packages/utils/src/isApproximatelyEqual.ts
Normal file
24
packages/utils/src/isApproximatelyEqual.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { BigNumber, BigNumberValue } from './bigNumber';
|
||||
|
||||
/**
|
||||
* Check if two BigNumber values are approximately equal based on relative difference
|
||||
* @param value1
|
||||
* @param value2
|
||||
* @param relativeTolerance maximum threshold for relative difference of values to declare them approx. equal
|
||||
*/
|
||||
export const isApproximatelyEqual = (
|
||||
value1: BigNumberValue,
|
||||
value2: BigNumberValue,
|
||||
relativeTolerance: BigNumberValue,
|
||||
): boolean => {
|
||||
value1 = new BigNumber(value1);
|
||||
value2 = new BigNumber(value2);
|
||||
relativeTolerance = new BigNumber(relativeTolerance);
|
||||
|
||||
// Cannot calculate relative difference if one value is zero, but then they must be equal
|
||||
if (value1.eq(0)) return value1.eq(value2);
|
||||
|
||||
const relativeDifference = value2.minus(value1).abs().dividedBy(value1);
|
||||
|
||||
return relativeDifference.lte(relativeTolerance);
|
||||
};
|
||||
32
packages/utils/tests/isApproximatelyEqual.test.ts
Normal file
32
packages/utils/tests/isApproximatelyEqual.test.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { BigNumber } from '../src/bigNumber';
|
||||
import { isApproximatelyEqual } from '../src/isApproximatelyEqual';
|
||||
|
||||
describe(isApproximatelyEqual.name, () => {
|
||||
it('always returns true for equal values', () => {
|
||||
expect(isApproximatelyEqual(100, 100, 0.001)).toBe(true);
|
||||
expect(isApproximatelyEqual(100, '100', 0.001)).toBe(true);
|
||||
expect(isApproximatelyEqual('100', '100', 0.001)).toBe(true);
|
||||
expect(isApproximatelyEqual(new BigNumber(-123), '-123', 0.001)).toBe(true);
|
||||
expect(isApproximatelyEqual('-123.001', '-123.001000', 0.001)).toBe(true);
|
||||
});
|
||||
|
||||
it('handles zero values correctly', () => {
|
||||
expect(isApproximatelyEqual(0, 0, 0.01)).toBe(true);
|
||||
expect(isApproximatelyEqual(0, 1, 0.01)).toBe(false);
|
||||
});
|
||||
|
||||
it('handles relative tolerance', () => {
|
||||
expect(isApproximatelyEqual(100, 101, 0.005)).toBe(false);
|
||||
expect(isApproximatelyEqual(100, 101, 0.01)).toBe(true);
|
||||
expect(isApproximatelyEqual(100, 101, 0.02)).toBe(true);
|
||||
});
|
||||
|
||||
it('handles NaN values', () => {
|
||||
expect(isApproximatelyEqual(100, NaN, 0.01)).toBe(false);
|
||||
expect(isApproximatelyEqual(NaN, 100, 0.01)).toBe(false);
|
||||
expect(isApproximatelyEqual(NaN, NaN, 0.01)).toBe(false);
|
||||
expect(isApproximatelyEqual('nonsense', '123', 0.01)).toBe(false);
|
||||
expect(isApproximatelyEqual('123', 'nonsense', 0.01)).toBe(false);
|
||||
expect(isApproximatelyEqual('nonsense', '', 0.01)).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user