Skip to content

Commit 7d51c45

Browse files
committed
Calculator operators ! and !! for factorial and double factorial
1 parent 003794f commit 7d51c45

File tree

5 files changed

+80
-6
lines changed

5 files changed

+80
-6
lines changed

apfloat-calc/src/main/java/org/apfloat/calc/AbstractCalculatorImpl.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* MIT License
33
*
4-
* Copyright (c) 2002-2023 Mikko Tommila
4+
* Copyright (c) 2002-2024 Mikko Tommila
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal
@@ -35,7 +35,7 @@
3535
* Provides a storage for variables, and maps
3636
* the elementary operators to function calls.
3737
*
38-
* @version 1.9.1
38+
* @version 1.14.0
3939
* @author Mikko Tommila
4040
*/
4141

@@ -103,6 +103,20 @@ public Number pow(Number x, Number y)
103103
return function("pow", toList(x, y));
104104
}
105105

106+
@Override
107+
public Number factorial(Number x)
108+
throws ParseException
109+
{
110+
return function("factorial", toList(x));
111+
}
112+
113+
@Override
114+
public Number doubleFactorial(Number x)
115+
throws ParseException
116+
{
117+
return function("doubleFactorial", toList(x));
118+
}
119+
106120
@Override
107121
public Number getVariable(String name)
108122
throws ParseException

apfloat-calc/src/main/java/org/apfloat/calc/CalculatorImpl.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* MIT License
33
*
4-
* Copyright (c) 2002-2023 Mikko Tommila
4+
* Copyright (c) 2002-2024 Mikko Tommila
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal
@@ -29,7 +29,7 @@
2929
* Calculator implementation interface.
3030
* The calculator parser uses this interface to perform the actual calculations.
3131
*
32-
* @version 1.9.1
32+
* @version 1.14.0
3333
* @author Mikko Tommila
3434
*/
3535

@@ -132,6 +132,32 @@ public Number mod(Number x, Number y)
132132
public Number pow(Number x, Number y)
133133
throws ParseException;
134134

135+
/**
136+
* Factorial.
137+
*
138+
* @param x The argument.
139+
*
140+
* @return <code>x!</code>
141+
*
142+
* @exception ParseException In case of invalid arguments.
143+
*/
144+
145+
public Number factorial(Number x)
146+
throws ParseException;
147+
148+
/**
149+
* Double factorial.
150+
*
151+
* @param x The argument.
152+
*
153+
* @return <code>x!!</code>
154+
*
155+
* @exception ParseException In case of invalid arguments.
156+
*/
157+
158+
public Number doubleFactorial(Number x)
159+
throws ParseException;
160+
135161
/**
136162
* Arbitrary function.
137163
*

apfloat-calc/src/main/java/org/apfloat/calc/CalculatorParser.jj

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,26 @@ Number powerExpression():
163163
Number b;
164164
}
165165
{
166-
a = element()
166+
a = factorialExpression()
167167
(
168168
"^" b = unaryExpression() { a = this.calculatorImpl.pow(a, b); }
169169
)?
170170
{ return a; }
171171
}
172172

173+
Number factorialExpression():
174+
{
175+
Number a;
176+
}
177+
{
178+
a = element()
179+
(
180+
"!!" { a = this.calculatorImpl.doubleFactorial(a); }
181+
| "!" { a = this.calculatorImpl.factorial(a); }
182+
)*
183+
{ return a; }
184+
}
185+
173186
Number element():
174187
{
175188
String v;

apfloat-calc/src/test/java/org/apfloat/calc/CalculatorTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,20 @@ public static void testOperators()
167167
assertCalculation("8.8080652584e646456992", "2^2147483647.0");
168168
assertCalculation("-1", "i^2");
169169
assertCalculation("1", "1^2i");
170+
assertCalculation("2417851639229258349412352", "2^3^4");
171+
assertCalculation("120", "5!");
172+
assertCalculation("15", "5!!");
173+
assertCalculation("64", "2^3!");
174+
assertCalculation("8", "2^3!!");
175+
assertCalculation("1307674368000", "5!!!");
176+
assertCalculation("2027025", "5!!!!");
177+
assertCalculation("-24", "-4!");
178+
assertCalculation("1/16777216", "2^-4!");
179+
assertCalculation("-1/16777216", "-2^-4!");
180+
assertCalculation("8", "2^3!!!!");
181+
assertCalculation("-1/8", "-2^-3!!!!");
182+
assertCalculation("4", "2!^2!");
183+
assertCalculation("4", "2!!^2!!");
170184

171185
assertCalculationFailure("6%i");
172186
assertCalculationFailure("5e");
@@ -184,6 +198,11 @@ public static void testOperators()
184198
assertCalculationFailure("6%");
185199
assertCalculationFailure("2-");
186200
assertCalculationFailure("bogus^5");
201+
assertCalculationFailure("!");
202+
assertCalculationFailure("bogus!");
203+
assertCalculationFailure("bogus!!");
204+
assertCalculationFailure("5!=");
205+
assertCalculationFailure("5!=4");
187206
}
188207

189208
public static void testFunctions()

src/site/resources/applet/calculator-help.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ <h2>Operators</h2>
5454
<tr><td><code>/</code></td><td>division</td></tr>
5555
<tr><td><code>%</code></td><td>modulus</td></tr>
5656
<tr><td><code>^</code></td><td>power</td></tr>
57+
<tr><td><code>!</code></td><td>factorial</td></tr>
58+
<tr><td><code>!!</code></td><td>double factorial</td></tr>
5759
</table>
5860

5961
<p>For example:</p>
@@ -387,7 +389,7 @@ <h3>Fixed input precision</h3>
387389

388390
<p>Bug reports, questions and comments should be sent to <a href="mailto:Mikko.Tommila@apfloat.org">the author</a>.</p>
389391

390-
<p>Last updated: April 9th, 2024</p>
392+
<p>Last updated: April 10th, 2024</p>
391393

392394
</div>
393395

0 commit comments

Comments
 (0)