Skip to content

Commit 0847281

Browse files
authored
Merge pull request #12 from SundaeSwap-finance/fix/fration-to-string
fix: toString method from Fraction not working properly for negative values
2 parents 5f3dda5 + c37ac39 commit 0847281

File tree

2 files changed

+15
-110
lines changed

2 files changed

+15
-110
lines changed

packages/fraction/src/Fraction.ts

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,7 @@ export class Fraction {
3131
: Fraction.parseString(fraction.toString());
3232
}
3333

34-
// static fromLocaleString(numStr: string, locale?: string): Fraction {
35-
// const { decimalSeparator, groupSeparator } = getLocaleFormatOptions(locale);
36-
// const [integerPart, fractionalPart] = numStr.split(decimalSeparator);
37-
// const quotient = BigInt(integerPart.split(groupSeparator).join(""));
38-
// if (!fractionalPart?.length) return new Fraction(quotient);
39-
// const denominator = 10n ** BigInt(fractionalPart.length);
40-
// return new Fraction(
41-
// quotient * denominator + BigInt(fractionalPart),
42-
// denominator
43-
// );
44-
// }
45-
4634
static parseString(fractionString: string): Fraction {
47-
// Parse a number in various forms (1000, 1.0003, 1.23e4, 1.23e-4) into a numerator and denominator
4835
fractionString = fractionString.replace(/,/g, "");
4936

5037
if (fractionString.match(/[eE]/)) {
@@ -62,8 +49,7 @@ export class Fraction {
6249
const numerator = BigInt(integerPart + fractionalPart);
6350
const denominator = 10n ** BigInt(fractionalPart.length);
6451

65-
// Simplify the fraction using the GCD function
66-
const gcd = (a, b) => (b === 0n ? a : gcd(b, a % b));
52+
const gcd = (a: bigint, b: bigint) => (b === 0n ? a : gcd(b, a % b));
6753
const divisor = gcd(numerator, denominator);
6854
return new Fraction(numerator / divisor, denominator / divisor);
6955
}
@@ -82,7 +68,7 @@ export class Fraction {
8268
[numerator, denominator] = numerator;
8369
}
8470
this.numerator = BigInt(numerator);
85-
this.denominator = BigInt(denominator || 1n);
71+
this.denominator = BigInt(denominator ?? 1n);
8672
if (this.denominator === 0n) throw new Error(FractionError.DivisionByZero);
8773
}
8874

@@ -210,11 +196,13 @@ export class Fraction {
210196
}
211197

212198
toString(decimals = Fraction.MAX_DECIMALS): string {
213-
const formattedIntegerPart = this.getQuotient().toString();
214-
const formattedFractionalPart = this.remainderToString(decimals);
199+
const sign = this.lessThan(Fraction.ZERO) ? "-" : "";
200+
const absFrac = this.abs();
201+
const formattedIntegerPart = absFrac.getQuotient().toString();
202+
const formattedFractionalPart = absFrac.remainderToString(decimals);
215203
return formattedFractionalPart
216-
? `${formattedIntegerPart}.${formattedFractionalPart}`
217-
: formattedIntegerPart;
204+
? `${sign}${formattedIntegerPart}.${formattedFractionalPart}`
205+
: `${sign}${formattedIntegerPart}`;
218206
}
219207

220208
/**

packages/fraction/src/__tests__/Fraction.test.ts

Lines changed: 7 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,19 @@ describe("Fraction", () => {
3838

3939
test(".toString()", () => {
4040
expect(new Fraction(1, 25).toString()).toBe("0.04");
41+
expect(new Fraction(-123090, 1000000).toString()).toBe("-0.12309");
4142
expect(new Fraction(1_000_000 * 25 + 1, 25).toString()).toBe("1000000.04");
4243
expect(Fraction.ZERO.toString()).toBe("0");
4344
expect(Fraction.ONE.toString()).toBe("1");
4445
expect(Fraction.HUNDRED.toString()).toBe("100");
4546
});
4647

48+
test(".toNumber()", () => {
49+
expect(new Fraction(1, 25).toNumber()).toBe(0.04);
50+
expect(new Fraction(-123090, 1000000).toNumber()).toBe(-0.12309);
51+
expect(new Fraction(1, 3).toNumber(2)).toBe(0.33);
52+
});
53+
4754
test(".parseString()", () => {
4855
expect(Fraction.parseString("0.04").eq(new Fraction(1, 25))).toBe(true);
4956
expect(
@@ -83,94 +90,4 @@ describe("Fraction", () => {
8390
),
8491
);
8592
});
86-
87-
// test("#toLocaleString()", () => {
88-
// expect(new Fraction(1, 25).toLocaleString()).toBe("0.04");
89-
// expect(new Fraction(1_000_000 * 25 + 1, 25).toLocaleString()).toBe(
90-
// "1,000,000.04"
91-
// );
92-
// const testFraction = new Fraction(1_000_000 * 25_000 + 1, 25_000);
93-
// expect(testFraction.toLocaleString()).toBe("1,000,000.00004");
94-
// expect(testFraction.toLocaleString("en-US", 1)).toBe("1,000,000");
95-
// expect(testFraction.toLocaleString("en-US", 4)).toBe("1,000,000");
96-
// expect(testFraction.toLocaleString("en-US", 5)).toBe("1,000,000.00004");
97-
// expect(testFraction.toLocaleString("de-DE")).toBe("1.000.000,00004");
98-
// expect(testFraction.toLocaleString("it-CH")).toBe("1’000’000.00004");
99-
// expect(testFraction.toLocaleString("hu-HU")).toBe("1\xa0000\xa0000,00004");
100-
// expect(testFraction.toLocaleString("fr-FR")).toBe(
101-
// "1\u202f000\u202f000,00004"
102-
// );
103-
// expect(Fraction.ZERO.toLocaleString()).toBe("0");
104-
// expect(Fraction.ONE.toLocaleString()).toBe("1");
105-
// expect(Fraction.HUNDRED.toLocaleString()).toBe("100");
106-
// });
107-
108-
// test(".fromLocaleString()", () => {
109-
// const testFraction = new Fraction(1_000_000 * 25_000 + 1, 25_000);
110-
// expect(
111-
// Fraction.fromLocaleString("1.000.000,00004", "de-DE").eq(testFraction)
112-
// ).toBe(true);
113-
// expect(
114-
// Fraction.fromLocaleString("1’000’000.00004", "it-CH").eq(testFraction)
115-
// ).toBe(true);
116-
// expect(
117-
// Fraction.fromLocaleString("1\xa0000\xa0000,00004", "hu-HU").eq(
118-
// testFraction
119-
// )
120-
// ).toBe(true);
121-
// expect(
122-
// Fraction.fromLocaleString("1\u202f000\u202f000,00004", "fr-FR").eq(
123-
// testFraction
124-
// )
125-
// ).toBe(true);
126-
// expect(
127-
// Fraction.fromLocaleString("1,000,000.00004").eq(testFraction)
128-
// ).toBe(true);
129-
// expect(Fraction.fromLocaleString("0.04").eq(new Fraction(1, 25))).toBe(
130-
// true
131-
// );
132-
// expect(Fraction.fromLocaleString("0").eq(Fraction.ZERO)).toBe(true);
133-
// expect(Fraction.fromLocaleString("1").eq(Fraction.ONE)).toBe(true);
134-
// expect(Fraction.fromLocaleString("1000").eq(Fraction.THOUSAND)).toBe(
135-
// true
136-
// );
137-
// });
138-
139-
// test(".lessThanOrEqual()", () => {
140-
// const testFraction = new Fraction(1_000_000);
141-
// expect(
142-
// Fraction.fromLocaleString("1.000.000", "de-DE").lessThanOrEqual(
143-
// testFraction
144-
// )
145-
// ).toBe(true);
146-
// expect(
147-
// Fraction.fromLocaleString("999.999", "de-DE").lessThanOrEqual(
148-
// testFraction
149-
// )
150-
// ).toBe(true);
151-
// expect(
152-
// Fraction.fromLocaleString("1.000.001", "de-DE").lessThanOrEqual(
153-
// testFraction
154-
// )
155-
// ).toBe(false);
156-
// });
157-
158-
// test(".greaterThanOrEqual()", () => {
159-
// const testFraction = new Fraction(1_000_000);
160-
// expect(
161-
// Fraction.fromLocaleString("1.000.000", "de-DE").greaterThanOrEqual(
162-
// testFraction
163-
// )
164-
// ).toBe(true);
165-
// expect(
166-
// Fraction.fromLocaleString("999.999", "de-DE").greaterThanOrEqual(
167-
// testFraction
168-
// )
169-
// ).toBe(false);
170-
// expect(
171-
// Fraction.fromLocaleString("1.000.001", "de-DE").greaterThanOrEqual(
172-
// testFraction
173-
// )
174-
// ).toBe(true);
175-
// });
17693
});

0 commit comments

Comments
 (0)