MCPcopy
hub / github.com/formatjs/formatjs / findN1E1R1

Function findN1E1R1

packages/ecma402-abstract/NumberFormat/ToRawPrecision.ts:12–72  ·  view source on GitHub ↗
(x: Decimal, p: number)

Source from the content-addressed store, hash-verified

10
11//IMPL: Helper function to find n1, e1, and r1 using direct calculation
12function findN1E1R1(x: Decimal, p: number) {
13 const maxN1 = getPowerOf10(p)
14 const minN1 = getPowerOf10(p - 1)
15
16 // Direct calculation: compute e1 from logarithm
17 // e1 is the exponent such that n1 * 10^(e1-p+1) <= x
18 // Taking log: log(n1) + (e1-p+1)*log(10) <= log(x)
19 // Since n1 is between 10^(p-1) and 10^p, we have:
20 // (p-1) + (e1-p+1) <= log10(x) < p + (e1-p+1)
21 // Simplifying: e1 <= log10(x) < e1 + 1
22 // Therefore: e1 = floor(log10(x))
23 const log10x = x.log(10)
24 let e1 = log10x.floor()
25
26 // Calculate n1 and r1 from e1
27 const divisor = getPowerOf10(e1.minus(p).plus(1))
28 let n1 = x.div(divisor).floor()
29 let r1 = n1.times(divisor)
30
31 // Verify and adjust if n1 is out of bounds
32 // This handles edge cases near powers of 10
33 if (n1.greaterThanOrEqualTo(maxN1)) {
34 e1 = e1.plus(1)
35 const newDivisor = getPowerOf10(e1.minus(p).plus(1))
36 n1 = x.div(newDivisor).floor()
37 r1 = n1.times(newDivisor)
38 } else if (n1.lessThan(minN1)) {
39 e1 = e1.minus(1)
40 const newDivisor = getPowerOf10(e1.minus(p).plus(1))
41 n1 = x.div(newDivisor).floor()
42 r1 = n1.times(newDivisor)
43 }
44
45 // Final verification with fallback to iterative search if needed
46 if (
47 r1.lessThanOrEqualTo(x) &&
48 n1.lessThan(maxN1) &&
49 n1.greaterThanOrEqualTo(minN1)
50 ) {
51 return {n1, e1, r1}
52 }
53
54 // Fallback: iterative search (should rarely be needed)
55 const maxE1 = x.div(minN1).log(10).plus(p).minus(1).ceil()
56 let currentE1 = maxE1
57 while (true) {
58 const currentDivisor = getPowerOf10(currentE1.minus(p).plus(1))
59 let currentN1 = x.div(currentDivisor).floor()
60 if (currentN1.lessThan(maxN1) && currentN1.greaterThanOrEqualTo(minN1)) {
61 const currentR1 = currentN1.times(currentDivisor)
62 if (currentR1.lessThanOrEqualTo(x)) {
63 return {
64 n1: currentN1,
65 e1: currentE1,
66 r1: currentR1,
67 }
68 }
69 }

Callers 1

ToRawPrecisionFunction · 0.85

Calls 10

logMethod · 0.80
floorMethod · 0.80
plusMethod · 0.80
minusMethod · 0.80
divMethod · 0.80
timesMethod · 0.80
greaterThanOrEqualToMethod · 0.80
lessThanMethod · 0.80
lessThanOrEqualToMethod · 0.80
ceilMethod · 0.80

Tested by

no test coverage detected