-
Notifications
You must be signed in to change notification settings - Fork 0
/
edition.js
284 lines (230 loc) · 18.5 KB
/
edition.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
/*
Fōrmulæ arithmetic package. Module for edition.
Copyright (C) 2015-2025 Laurence R. Ugalde
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
'use strict';
export class Arithmetic extends Formulae.EditionPackage {};
Arithmetic.editionNumber = function() {
let number, s;
while (true) {
s = prompt(Arithmetic.messages.enterNumber, s);
if (s === null) return;
try {
number = s.includes(".") ? new Decimal(s) : BigInt(s);
break;
}
catch (error) {
continue;
}
}
let n = Formulae.createExpression("Math.Number");
n.set("Value", number);
Formulae.sExpression.replaceBy(n);
Formulae.sHandler.prepareDisplay();
Formulae.sHandler.display();
Formulae.setSelected(Formulae.sHandler, n, false);
}
Arithmetic.actionNumber = {
isAvailableNow: () => Formulae.sHandler.type != Formulae.ROW_OUTPUT,
getDescription: () => Arithmetic.messages.actionNumber,
doAction: () => {
let s;
{
let x = Formulae.sExpression.get("Value");
if (typeof x === "bigint") {
s = x.toString();
}
else { // Decimal
if (x.isInteger()) {
s = x.toFixed() + ".";
}
else {
s = x.toFixed();
}
}
}
let number;
while (true) {
s = prompt(Arithmetic.messages.enterNumber, s);
if (s === null) return;
try {
number = s.includes(".") ? new Decimal(s) : BigInt(s);
break;
}
catch (error) {
continue;
}
}
let n = Formulae.createExpression("Math.Number");
n.set("Value", number);
Formulae.sExpression.replaceBy(n);
Formulae.sHandler.prepareDisplay();
Formulae.sHandler.display();
Formulae.setSelected(Formulae.sHandler, n, false);
}
};
Arithmetic.editionNegative = function() {
let negative = Formulae.createExpression("Math.Arithmetic.Negative");
Formulae.sExpression.replaceBy(negative);
negative.addChild(Formulae.sExpression);
Formulae.sHandler.prepareDisplay();
Formulae.sHandler.display();
Formulae.setSelected(Formulae.sHandler, Formulae.sExpression, false);
}
Arithmetic.operatorEdition = function(tag, next, forced, negative) {
let nullExpr = new Expression.Null();
let newExpr;
if (negative) {
newExpr = Formulae.createExpression("Math.Arithmetic.Negative");
newExpr.addChild(nullExpr);
}
else {
newExpr = nullExpr;
}
if (!forced && Formulae.sExpression.parent instanceof Expression && Formulae.sExpression.parent.getTag() == tag) {
Formulae.sExpression.parent.addChildAt(Formulae.sExpression.index + (next ? 1 : 0), newExpr);
}
else {
let expr = Formulae.createExpression(tag);
Formulae.sExpression.replaceBy(expr);
expr.addChild(next ? Formulae.sExpression : newExpr);
expr.addChild(next ? newExpr : Formulae.sExpression);
}
Formulae.sHandler.prepareDisplay();
Formulae.sHandler.display();
Formulae.setSelected(Formulae.sHandler, nullExpr, false);
};
Arithmetic.setEditions = function() {
Formulae.addEdition(this.messages.pathMath, null, this.messages.leafNumber, Formulae.editionNumber = Arithmetic.editionNumber);
Formulae.addEdition(this.messages.pathMath, null, this.messages.leafNumeric, () => Expression.wrapperEdition("Math.Numeric"));
Formulae.addEdition(this.messages.pathMath, null, this.messages.leafSetNoSymbolic, () => Expression.replacingEdition("Math.SetNoSymbolic"));
Formulae.addEdition(this.messages.pathMath, null, "∞", () => Expression.replacingEdition("Math.Infinity"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafNegative, Formulae.editionNegative = Arithmetic.editionNegative);
Formulae.addEdition(this.messages.pathAddition, null, this.messages.leafAdditionAfter, Formulae.editionAddition = () => Arithmetic.operatorEdition("Math.Arithmetic.Addition", true, false, false));
Formulae.addEdition(this.messages.pathAddition, null, this.messages.leafAdditionAfterForced, () => Arithmetic.operatorEdition("Math.Arithmetic.Addition", true, true, false));
Formulae.addEdition(this.messages.pathAddition, null, this.messages.leafAdditionBefore, Formulae.editionAdditionAlt = () => Arithmetic.operatorEdition("Math.Arithmetic.Addition", false, false, false));
Formulae.addEdition(this.messages.pathAddition, null, this.messages.leafAdditionBeforeForced, () => Arithmetic.operatorEdition("Math.Arithmetic.Addition", false, true, false));
Formulae.addEdition(this.messages.pathSubtraction, null, this.messages.leafSubtractionAfter, Formulae.editionSubtraction = () => Arithmetic.operatorEdition("Math.Arithmetic.Addition", true, false, true));
Formulae.addEdition(this.messages.pathSubtraction, null, this.messages.leafSubtractionAfterForced, () => Arithmetic.operatorEdition("Math.Arithmetic.Addition", true, true, true));
Formulae.addEdition(this.messages.pathSubtraction, null, this.messages.leafSubtractionBefore, Formulae.aditionSubtractionAlt = () => Arithmetic.operatorEdition("Math.Arithmetic.Addition", false, false, true));
Formulae.addEdition(this.messages.pathSubtraction, null, this.messages.leafSubtractionBeforeForced, () => Arithmetic.operatorEdition("Math.Arithmetic.Addition", false, true, true));
Formulae.addEdition(this.messages.pathMultiplication, null, this.messages.leafMultiplicationAfter, Formulae.editionMultiplication = () => Arithmetic.operatorEdition("Math.Arithmetic.Multiplication", true, false, false));
Formulae.addEdition(this.messages.pathMultiplication, null, this.messages.leafMultiplicationAfterForced, () => Arithmetic.operatorEdition("Math.Arithmetic.Multiplication", true, true, false));
Formulae.addEdition(this.messages.pathMultiplication, null, this.messages.leafMultiplicationBefore, Formulae.editionMultiplicationAlt = () => Arithmetic.operatorEdition("Math.Arithmetic.Multiplication", false, false, false));
Formulae.addEdition(this.messages.pathMultiplication, null, this.messages.leafMultiplicationBeforeForced, () => Arithmetic.operatorEdition("Math.Arithmetic.Multiplication", false, true, false));
Formulae.addEdition(this.messages.pathDivision, null, this.messages.leafDenominator, () => Expression.binaryEdition("Math.Arithmetic.Division", false));
Formulae.addEdition(this.messages.pathDivision, null, this.messages.leafNumerator, () => Expression.binaryEdition("Math.Arithmetic.Division", true));
Formulae.addEdition(this.messages.pathExponentiation, null, this.messages.leafExponent, () => Expression.binaryEdition("Math.Arithmetic.Exponentiation", false));
Formulae.addEdition(this.messages.pathExponentiation, null, this.messages.leafBase, () => Expression.binaryEdition("Math.Arithmetic.Exponentiation", true));
// precision
Formulae.addEdition(this.messages.pathPrecision, null, this.messages.leafSignificantDigits, () => Expression.wrapperEdition ("Math.Arithmetic.SignificantDigits"));
Formulae.addEdition(this.messages.pathPrecision, null, this.messages.leafSetPrecision, () => Expression.wrapperEdition ("Math.Arithmetic.SetPrecision"));
Formulae.addEdition(this.messages.pathPrecision, null, this.messages.leafGetPrecision, () => Expression.replacingEdition("Math.Arithmetic.GetPrecision"));
Formulae.addEdition(this.messages.pathPrecision, null, this.messages.leafWithPrecision, () => Expression.binaryEdition("Math.Arithmetic.WithPrecision", false));
// rounding mode
Formulae.addEdition(this.messages.pathRoundingMode, null, this.messages.leafSetRoundingMode, () => Expression.wrapperEdition("Math.Arithmetic.SetRoundingMode"));
Formulae.addEdition(this.messages.pathRoundingMode, null, this.messages.leafGetRoundingMode, () => Expression.replacingEdition("Math.Arithmetic.GetRoundingMode"));
// rounding modes
[
"TowardsZero", "AwayFromZero", "TowardsMinusInfinity", "TowardsInfinity",
"Nearest.HalfTowardsZero", "Nearest.HalfAwayFromZero", "Nearest.HalfTowardsMinusInfinity", "Nearest.HalfTowardsInfinity",
"Nearest.HalfEven"
].forEach(tag => {
Formulae.addEdition(
Arithmetic.messages.pathRoundingModes,
null,
Arithmetic.messages["labelRoundingMode" + tag],
() => Expression.replacingEdition("Math.Arithmetic.RoundingMode." + tag)
)
});
// rounding
Formulae.addEdition(this.messages.pathRounding, null, this.messages.leafRoundToPrecision, () => Expression.multipleEdition("Math.Arithmetic.RoundToPrecision", 2, 0));
Formulae.addEdition(this.messages.pathRounding, null, this.messages.leafRoundToInteger, () => Expression.wrapperEdition ("Math.Arithmetic.RoundToInteger"));
Formulae.addEdition(this.messages.pathRounding, null, this.messages.leafRoundToDecimalPlaces, () => Expression.multipleEdition("Math.Arithmetic.RoundToDecimalPlaces", 2, 0));
Formulae.addEdition(this.messages.pathRounding, null, this.messages.leafRoundToMultiple, () => Expression.multipleEdition("Math.Arithmetic.RoundToMultiple", 2, 0));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafRationalize, () => Expression.wrapperEdition("Math.Arithmetic.Rationalize"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafSquareRoot, () => Expression.wrapperEdition("Math.Arithmetic.SquareRoot"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafFactorial, () => Expression.wrapperEdition("Math.Arithmetic.Factorial"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafAbsoluteValue, () => Expression.wrapperEdition("Math.Arithmetic.AbsoluteValue"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafFloor, () => Expression.wrapperEdition("Math.Arithmetic.Floor"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafCeiling, () => Expression.wrapperEdition("Math.Arithmetic.Ceiling"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafTruncate, () => Expression.wrapperEdition("Math.Arithmetic.Truncate"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafRound , () => Expression.wrapperEdition("Math.Arithmetic.Round"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafSign, () => Expression.wrapperEdition("Math.Arithmetic.Sign"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafIntegerPart, () => Expression.wrapperEdition("Math.Arithmetic.IntegerPart"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafFractionalPart, () => Expression.wrapperEdition("Math.Arithmetic.FractionalPart"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafDecimalPlaces, () => Expression.wrapperEdition("Math.Arithmetic.DecimalPlaces"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafFactors, () => Expression.wrapperEdition("Math.Arithmetic.Factors"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafDigits, () => Expression.wrapperEdition("Math.Arithmetic.Digits"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafGreatestCommonDivisor, () => Expression.wrapperEdition("Math.Arithmetic.GreatestCommonDivisor"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafLeastCommonMultiple, () => Expression.wrapperEdition("Math.Arithmetic.LeastCommonMultiple"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafRandom, () => Expression.replacingEdition("Math.Arithmetic.Random"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafRandomPrecision, () => Expression.wrapperEdition ("Math.Arithmetic.Random"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafRandomInRange, () => Expression.binaryEdition("Math.Arithmetic.RandomInRange", false));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsRealNumber, () => Expression.wrapperEdition("Math.Arithmetic.IsRealNumber"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsRationalNumber, () => Expression.wrapperEdition("Math.Arithmetic.IsRationalNumber"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsNumeric, () => Expression.wrapperEdition("Math.Arithmetic.IsNumeric"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsIntegerValue, () => Expression.wrapperEdition("Math.Arithmetic.IsIntegerValue"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsInteger, () => Expression.wrapperEdition("Math.Arithmetic.IsInteger"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsDecimal, () => Expression.wrapperEdition("Math.Arithmetic.IsDecimal"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsPositiveNumber, () => Expression.wrapperEdition("Math.Arithmetic.IsPositiveNumber"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsNegativeNumber, () => Expression.wrapperEdition("Math.Arithmetic.IsNegativeNumber"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsNumberZero, () => Expression.wrapperEdition("Math.Arithmetic.IsNumberZero"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsEven, () => Expression.wrapperEdition("Math.Arithmetic.IsEven"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsOdd, () => Expression.wrapperEdition("Math.Arithmetic.IsOdd"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafIsPrime, () => Expression.wrapperEdition("Math.Arithmetic.IsPrime"));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafDivides, () => Expression.binaryEdition("Math.Arithmetic.Divides", false));
Formulae.addEdition(this.messages.pathTesting, null, this.messages.leafDoesNotDivide, () => Expression.binaryEdition("Math.Arithmetic.DoesNotDivide", false));
Formulae.addEdition(this.messages.pathConversion, null, this.messages.leafToInteger, () => Expression.wrapperEdition("Math.Arithmetic.ToInteger"));
Formulae.addEdition(this.messages.pathConversion, null, this.messages.leafToIfInteger, () => Expression.wrapperEdition("Math.Arithmetic.ToIfInteger"));
Formulae.addEdition(this.messages.pathConversion, null, this.messages.leafToDecimal, () => Expression.wrapperEdition("Math.Arithmetic.ToDecimal"));
Formulae.addEdition(this.messages.pathConversion, null, this.messages.leafToNumber, () => Expression.wrapperEdition("Math.Arithmetic.ToNumber"));
Formulae.addEdition(this.messages.pathEuclideanDivision, null, this.messages.leafDiv, () => Expression.binaryEdition("Math.Arithmetic.Div", false));
Formulae.addEdition(this.messages.pathEuclideanDivision, null, this.messages.leafMod, () => Expression.binaryEdition("Math.Arithmetic.Mod", false));
Formulae.addEdition(this.messages.pathEuclideanDivision, null, this.messages.leafDivMod, () => Expression.binaryEdition("Math.Arithmetic.DivMod", false));
Formulae.addEdition(this.messages.PathEuclideanDivisionMode, null, this.messages.leafSetEuclideanDivisionMode, () => Expression.wrapperEdition("Math.Arithmetic.SetEuclideanDivisionMode"));
Formulae.addEdition(this.messages.PathEuclideanDivisionMode, null, this.messages.leafGetEuclideanDivisionMode, () => Expression.replacingEdition("Math.Arithmetic.GetEuclideanDivisionMode"));
Formulae.addEdition(this.messages.PathEuclideanDivisionMode, null, this.messages.leafEuclideanMode, () => Expression.replacingEdition("Math.Arithmetic.EuclideanMode"));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafModularExponentiation, () => Expression.multipleEdition("Math.Arithmetic.ModularExponentiation", 3, 0));
Formulae.addEdition(this.messages.pathArithmetic, null, this.messages.leafModularMultiplicativeInverse, () => Expression.multipleEdition("Math.Arithmetic.ModularMultiplicativeInverse", 2, 0));
Formulae.addEdition(this.messages.pathArithmetic, null, "Piecewise", () => Expression.multipleEdition("Math.Arithmetic.Piecewise", 2, 0));
[ 4, 5, 3, 2 ].forEach(type => {
Formulae.addEdition(
Arithmetic.messages.pathSummation, "packages/org.formulae.math.arithmetic/img/summation" + type + ".png", null,
() => Expression.multipleEdition("Math.Arithmetic.Summation", type, 0)
);
Formulae.addEdition(
Arithmetic.messages.pathProduct, "packages/org.formulae.math.arithmetic/img/product" + type + ".png", null,
() => Expression.multipleEdition("Math.Arithmetic.Product", type, 0)
);
});
Formulae.addEdition(this.messages.pathTranscendental, null, this.messages.leafDecimalLogarithm, () => Expression.wrapperEdition("Math.Transcendental.DecimalLogarithm"));
Formulae.addEdition(this.messages.pathTranscendental, null, this.messages.leafNaturalLogarithm, () => Expression.wrapperEdition("Math.Transcendental.NaturalLogarithm"));
Formulae.addEdition(this.messages.pathTranscendental, null, this.messages.leafBinaryLogarithm, () => Expression.wrapperEdition("Math.Transcendental.BinaryLogarithm"));
Formulae.addEdition(this.messages.pathTranscendental, null, this.messages.leafLogarithm, () => Expression.binaryEdition("Math.Transcendental.Logarithm", false));
[
"Sine", "Cosine", "Tangent",
"Cotangent", "Secant", "Cosecant",
"ArcSine", "ArcCosine", "ArcTangent",
"ArcCotangent", "ArcSecant", "ArcCosecant"
].forEach(tag => {
Formulae.addEdition(this.messages.pathTrigonometric, null, Arithmetic.messages["leaf" + tag], () => Expression.wrapperEdition("Math.Trigonometric." + tag));
Formulae.addEdition(this.messages.pathHyperbolic, null, Arithmetic.messages["leaf" + tag], () => Expression.wrapperEdition("Math.Hyperbolic." + tag));
});
Formulae.addEdition(this.messages.pathTrigonometric, null, Arithmetic.messages.leafArcTangent2, () => Expression.binaryEdition("Math.Trigonometric.ArcTangent2"));
Formulae.addEdition(this.messages.pathConstant, null, "π", () => Expression.replacingEdition("Math.Constant.Pi"));
Formulae.addEdition(this.messages.pathConstant, null, "e", () => Expression.replacingEdition("Math.Constant.Euler"));
};
Arithmetic.setActions = function() {
Formulae.addAction("Math.Number", Arithmetic.actionNumber);
};