@js-draw/math 1.10.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/cjs/lib.d.ts +1 -1
  2. package/dist/cjs/lib.js +16 -3
  3. package/dist/cjs/rounding/cleanUpNumber.d.ts +3 -0
  4. package/dist/cjs/rounding/cleanUpNumber.js +35 -0
  5. package/dist/cjs/rounding/constants.d.ts +1 -0
  6. package/dist/cjs/rounding/constants.js +4 -0
  7. package/dist/cjs/rounding/getLenAfterDecimal.d.ts +10 -0
  8. package/dist/cjs/rounding/getLenAfterDecimal.js +30 -0
  9. package/dist/cjs/rounding/lib.d.ts +1 -0
  10. package/dist/cjs/rounding/lib.js +5 -0
  11. package/dist/cjs/{rounding.d.ts → rounding/toRoundedString.d.ts} +1 -3
  12. package/dist/cjs/rounding/toRoundedString.js +54 -0
  13. package/dist/cjs/rounding/toStringOfSamePrecision.d.ts +2 -0
  14. package/dist/cjs/rounding/toStringOfSamePrecision.js +58 -0
  15. package/dist/cjs/rounding/toStringOfSamePrecision.test.d.ts +1 -0
  16. package/dist/cjs/shapes/Path.js +8 -7
  17. package/dist/cjs/shapes/Triangle.js +2 -2
  18. package/dist/mjs/lib.d.ts +1 -1
  19. package/dist/mjs/lib.mjs +1 -1
  20. package/dist/mjs/rounding/cleanUpNumber.d.ts +3 -0
  21. package/dist/mjs/rounding/cleanUpNumber.mjs +31 -0
  22. package/dist/mjs/rounding/cleanUpNumber.test.d.ts +1 -0
  23. package/dist/mjs/rounding/constants.d.ts +1 -0
  24. package/dist/mjs/rounding/constants.mjs +1 -0
  25. package/dist/mjs/rounding/getLenAfterDecimal.d.ts +10 -0
  26. package/dist/mjs/rounding/getLenAfterDecimal.mjs +26 -0
  27. package/dist/mjs/rounding/lib.d.ts +1 -0
  28. package/dist/mjs/rounding/lib.mjs +1 -0
  29. package/dist/mjs/{rounding.d.ts → rounding/toRoundedString.d.ts} +1 -3
  30. package/dist/mjs/rounding/toRoundedString.mjs +47 -0
  31. package/dist/mjs/rounding/toRoundedString.test.d.ts +1 -0
  32. package/dist/mjs/rounding/toStringOfSamePrecision.d.ts +2 -0
  33. package/dist/mjs/rounding/toStringOfSamePrecision.mjs +51 -0
  34. package/dist/mjs/rounding/toStringOfSamePrecision.test.d.ts +1 -0
  35. package/dist/mjs/shapes/Path.mjs +2 -1
  36. package/dist/mjs/shapes/Triangle.mjs +2 -2
  37. package/package.json +3 -3
  38. package/src/lib.ts +1 -1
  39. package/src/rounding/cleanUpNumber.test.ts +15 -0
  40. package/src/rounding/cleanUpNumber.ts +38 -0
  41. package/src/rounding/constants.ts +3 -0
  42. package/src/rounding/getLenAfterDecimal.ts +29 -0
  43. package/src/rounding/lib.ts +2 -0
  44. package/src/rounding/toRoundedString.test.ts +32 -0
  45. package/src/rounding/toRoundedString.ts +57 -0
  46. package/src/rounding/toStringOfSamePrecision.test.ts +21 -0
  47. package/src/rounding/toStringOfSamePrecision.ts +63 -0
  48. package/src/shapes/Path.ts +2 -1
  49. package/src/shapes/Triangle.ts +2 -2
  50. package/dist/cjs/rounding.js +0 -146
  51. package/dist/mjs/rounding.mjs +0 -139
  52. package/src/rounding.test.ts +0 -65
  53. package/src/rounding.ts +0 -168
  54. /package/dist/cjs/{rounding.test.d.ts → rounding/cleanUpNumber.test.d.ts} +0 -0
  55. /package/dist/{mjs/rounding.test.d.ts → cjs/rounding/toRoundedString.test.d.ts} +0 -0
package/src/rounding.ts DELETED
@@ -1,168 +0,0 @@
1
- // @packageDocumentation @internal
2
-
3
- // Clean up stringified numbers
4
- export const cleanUpNumber = (text: string) => {
5
- // Regular expression substitions can be somewhat expensive. Only do them
6
- // if necessary.
7
-
8
- if (text.indexOf('e') > 0) {
9
- // Round to zero.
10
- if (text.match(/[eE][-]\d{2,}$/)) {
11
- return '0';
12
- }
13
- }
14
-
15
- const lastChar = text.charAt(text.length - 1);
16
- if (lastChar === '0' || lastChar === '.') {
17
- // Remove trailing zeroes
18
- text = text.replace(/([.]\d*[^0]+)0+$/, '$1');
19
- text = text.replace(/[.]0+$/, '.');
20
-
21
- // Remove trailing period
22
- text = text.replace(/[.]$/, '');
23
- }
24
-
25
- const firstChar = text.charAt(0);
26
- if (firstChar === '0' || firstChar === '-') {
27
- // Remove unnecessary leading zeroes.
28
- text = text.replace(/^(0+)[.]/, '.');
29
- text = text.replace(/^-(0+)[.]/, '-.');
30
- text = text.replace(/^(-?)0+$/, '$10');
31
- }
32
-
33
- if (text === '-0') {
34
- return '0';
35
- }
36
-
37
- return text;
38
- };
39
-
40
- /**
41
- * Converts `num` to a string, removing trailing digits that were likely caused by
42
- * precision errors.
43
- *
44
- * @example
45
- * ```ts,runnable,console
46
- * import { toRoundedString } from '@js-draw/math';
47
- *
48
- * console.log('Rounded: ', toRoundedString(1.000000011));
49
- * ```
50
- */
51
- export const toRoundedString = (num: number): string => {
52
- // Try to remove rounding errors. If the number ends in at least three/four zeroes
53
- // (or nines) just one or two digits, it's probably a rounding error.
54
- const fixRoundingUpExp = /^([-]?\d*\.\d{3,})0{4,}\d{1,4}$/;
55
- const hasRoundingDownExp = /^([-]?)(\d*)\.(\d{3,}9{4,})\d{1,4}$/;
56
-
57
- let text = num.toString(10);
58
- if (text.indexOf('.') === -1) {
59
- return text;
60
- }
61
-
62
- const roundingDownMatch = hasRoundingDownExp.exec(text);
63
- if (roundingDownMatch) {
64
- const negativeSign = roundingDownMatch[1];
65
- const postDecimalString = roundingDownMatch[3];
66
- const lastDigit = parseInt(postDecimalString.charAt(postDecimalString.length - 1), 10);
67
- const postDecimal = parseInt(postDecimalString, 10);
68
- const preDecimal = parseInt(roundingDownMatch[2], 10);
69
-
70
- const origPostDecimalString = roundingDownMatch[3];
71
-
72
- let newPostDecimal = (postDecimal + 10 - lastDigit).toString();
73
- let carry = 0;
74
- if (newPostDecimal.length > postDecimal.toString().length) {
75
- // Left-shift
76
- newPostDecimal = newPostDecimal.substring(1);
77
- carry = 1;
78
- }
79
-
80
- // parseInt(...).toString() removes leading zeroes. Add them back.
81
- while (newPostDecimal.length < origPostDecimalString.length) {
82
- newPostDecimal = carry.toString(10) + newPostDecimal;
83
- carry = 0;
84
- }
85
-
86
- text = `${negativeSign + (preDecimal + carry).toString()}.${newPostDecimal}`;
87
- }
88
-
89
- text = text.replace(fixRoundingUpExp, '$1');
90
-
91
- return cleanUpNumber(text);
92
- };
93
-
94
- const numberExp = /^([-]?)(\d*)[.](\d+)$/;
95
- export const getLenAfterDecimal = (numberAsString: string) => {
96
- const numberMatch = numberExp.exec(numberAsString);
97
- if (!numberMatch) {
98
- // If not a match, either the number is exponential notation (or is something
99
- // like NaN or Infinity)
100
- if (numberAsString.search(/[eE]/) !== -1 || /^[a-zA-Z]+$/.exec(numberAsString)) {
101
- return -1;
102
- // Or it has no decimal point
103
- } else {
104
- return 0;
105
- }
106
- }
107
-
108
- const afterDecimalLen = numberMatch[3].length;
109
- return afterDecimalLen;
110
- };
111
-
112
- // [reference] should be a string representation of a base-10 number (no exponential (e.g. 10e10))
113
- export const toStringOfSamePrecision = (num: number, ...references: string[]): string => {
114
- const text = num.toString(10);
115
- const textMatch = numberExp.exec(text);
116
- if (!textMatch) {
117
- return text;
118
- }
119
-
120
- let decimalPlaces = -1;
121
- for (const reference of references) {
122
- decimalPlaces = Math.max(getLenAfterDecimal(reference), decimalPlaces);
123
- }
124
-
125
- if (decimalPlaces === -1) {
126
- return toRoundedString(num);
127
- }
128
-
129
- // Make text's after decimal length match [afterDecimalLen].
130
- let postDecimal = textMatch[3].substring(0, decimalPlaces);
131
- let preDecimal = textMatch[2];
132
- const nextDigit = textMatch[3].charAt(decimalPlaces);
133
-
134
- if (nextDigit !== '') {
135
- const asNumber = parseInt(nextDigit, 10);
136
- if (asNumber >= 5) {
137
- // Don't attempt to parseInt() an empty string.
138
- if (postDecimal.length > 0) {
139
- const leadingZeroMatch = /^(0+)(\d*)$/.exec(postDecimal);
140
-
141
- let leadingZeroes = '';
142
- let postLeading = postDecimal;
143
- if (leadingZeroMatch) {
144
- leadingZeroes = leadingZeroMatch[1];
145
- postLeading = leadingZeroMatch[2];
146
- }
147
-
148
- postDecimal = (parseInt(postDecimal) + 1).toString();
149
-
150
- // If postDecimal got longer, remove leading zeroes if possible
151
- if (postDecimal.length > postLeading.length && leadingZeroes.length > 0) {
152
- leadingZeroes = leadingZeroes.substring(1);
153
- }
154
-
155
- postDecimal = leadingZeroes + postDecimal;
156
- }
157
-
158
- if (postDecimal.length === 0 || postDecimal.length > decimalPlaces) {
159
- preDecimal = (parseInt(preDecimal) + 1).toString();
160
- postDecimal = postDecimal.substring(1);
161
- }
162
- }
163
- }
164
-
165
- const negativeSign = textMatch[1];
166
- return cleanUpNumber(`${negativeSign}${preDecimal}.${postDecimal}`);
167
- };
168
-