Why Multiply operator does not work with BigInteger? - groovy

Can someone explain why the multiply operator throws an IllegalAccessException exception whereas all other operators works as expected?
BigInteger plus = 10000000000000000000 + 100 // 10000000000000000100
BigInteger minus = 10000000000000000000 - 100 // 9999999999999999900
BigInteger div = 10000000000000000000 / 100 // 100000000000000000
BigInteger mod = 10000000000000000000 % 100 // 0
BigInteger pow = 10000000000000000000 ** 2 // 100000000000000000000000000000000000000
BigInteger star = 10000000000000000000 * 100 // java.lang.IllegalAccessException: Reflection is not allowed on java.math.BigInteger java.math.BigInteger.multiply(long)
Groovy version: 2.4.4
Java Version: 1.7.0

It's true that this does not happen on Groovy 2.4.later (I'm trying on .13 for example). In Groovy 2.4.4 and probably earlier, this works as you would expect:
new BigInteger("10000000000000000000") * new BigInteger("100")
However, there are still overflow risks even in 2.4.13. Consider:
BigInteger b = 100000000 * 100
println b
// outputs 1410065408 because the multiplication of ints happens first, overflows, and the result is converted to BigInteger
While Groovy can convert int to BigInteger by default, mathematical operations can (and maybe should? I did not find clear guidance either way) happen first. In your example I'd guess the first is being converted and the second is not, and that is exposing some bug that has since been fixed.

Related

VC++ How to SUM two biginteger numbers

Say I have
static System::Numerics::BigInteger MinimoNumero; int16_t Uno = 1;
static System::Numerics::BigInteger MaximoNumero;
static const std::string MaximoNumeroString = "91389681247993671255432112333333333333333333333333333333333333333333333333333333333333333333333333333333";
MaximoNumero = System::Numerics::BigInteger::Parse(marshal_as<String^>(MaximoNumeroString));
MinimoNumero = System::Numerics::BigInteger::Parse("1");
How can I SUM 1 to MaximoNumero so I want a result as BigInteger as 91389681247993671255432112333333333333333333333333333333333333333333333333333333333333333333333333333334
If I use
System::Numerics::BigInteger NUM = MinimoNumero + MaximoNumero;
then I got error "more than one operator "+" matches these operands.."
You can't (generally) use the plain arithmetic operators on the BigInteger type. Instead, call the relevant member function(s) of the BigInteger type – in this case, the Add function:
System::Numerics::BigInteger NUM = System::Numerics::BigInteger::Add(MinimoNumero, MaximoNumero);

Math.Net Exponential Moving Average

I'm using simple moving average in Math.Net, but now that I also need to calculate EMA (exponential moving average) or any kind of weighted moving average, I don't find it in the library.
I looked over all methods under MathNet.Numerics.Statistics and beyond, but didn't find anything similar.
Is it missing in library or I need to reference some additional package?
I don't see any EMA in MathNet.Numerics, however it's trivial to program. The routine below is based on the definition at Investopedia.
public double[] EMA(double[] x, int N)
{
// x is the input series
// N is the notional age of the data used
// k is the smoothing constant
double k = 2.0 / (N + 1);
double[] y = new double[x.Length];
y[0] = x[0];
for (int i = 1; i < x.Length; i++) y[i] = k * x[i] + (1 - k) * y[i - 1];
return y;
}
Occasionally I found this package: https://daveskender.github.io/Stock.Indicators/docs/INDICATORS.html It targets to the latest .NET framework and has very detailed documents.
Try this:
public IEnumerable<double> EMA(IEnumerable<double> items, int notationalAge)
{
double k = 2.0d / (notationalAge + 1), prev = 0.0d;
var e = items.GetEnumerator();
if (!e.MoveNext()) yield break;
yield return prev = e.Current;
while(e.MoveNext())
{
yield return prev = (k * e.Current) + (1 - k) * prev;
}
}
It will still work with arrays, but also List, Queue, Stack, IReadOnlyCollection, etc.
Although it's not explicitly stated I also get the sense this is working with money, in which case it really ought to use decimal instead of double.

How does type promotion work in Groovy?

Consider the following code snippet -
def factorial(number) {
if(number == 1)
return number;
else
return number * factorial(number - 1);
}
println factorial(50)
println factorial(50).getClass()
println()
println 45**20
println ((45**20).getClass())
The output is -
0
class java.lang.Integer
1159445329576199417209625244140625
class java.math.BigInteger
Questions -
Why doesn't groovy automatically promote the result of number * factorial(number-1) to a BigInt in the first case?
Why is the output 0? Why isn't it some random number that we should get after integer overflow?
Old question but I'll try to answer both parts of the question:
Groovy documentation on arithmetic operations states that
binary operations involving subclasses of java.lang.Number automatically convert their arguments according to the following matrix (except for division, which is discussed below)
I won't paste the matrix but it specifies no casting to BigInteger or BigDecimal unless one of the operators is of one of these types.
In the case of division:
The division operators "/" and "/=" produce a Double result if either operand is either Float or Double and a BigDecimal result otherwise
I think that the table is not considering the power operator (**) since it's not present in Java and as stated in #tim_yates comment, power implementation uses BigInteger by default.
The code in DefaultGroovyMethods.java shows clearly that the power of int's is calculated using BigInteger's and if the result is small then is cast down to int again (And that's why (2**4).class is java.lang.Integer):
public static Number power(Integer self, Integer exponent) {
if (exponent >= 0) {
BigInteger answer = BigInteger.valueOf(self).pow(exponent);
if (answer.compareTo(BI_INT_MIN) >= 0 && answer.compareTo(BI_INT_MAX) <= 0) {
return answer.intValue();
} else {
return answer;
}
} else {
return power(self, (double) exponent);
}
}
To confirm the behaviour of other operations you can go to IntegerMath, LongMath or other classes in the org.codehaus.groovy.runtime.typehandling package
With Groovy, Integer.multiply( Integer ) always returns an Integer.
The factorial method starts overflowing around step 16.
At step 34, you end up with -2147483648 * -2147483648 which returns 0 so the result will always be 0
One fix is to change your method declaration to:
def factorial( BigInteger number ) {

Tail recursion with Groovy

I coded 3 factorial algorithms:
I expect to fail by stack overflow. No problem.
I try a tail recursive call, and convert the previous algorithm from recursive to iterative. It doesn't work, but I don't understand why.
I use trampoline() method and it works fine as I expect.
def factorial
factorial = { BigInteger n ->
if (n == 1) return 1
n * factorial(n - 1)
}
factorial(1000) // stack overflow
factorial = { Integer n, BigInteger acc = 1 ->
if (n == 1) return acc
factorial(n - 1, n * acc)
}
factorial(1000) // stack overflow, why?
factorial = { Integer n, BigInteger acc = 1 ->
if (n == 1) return acc
factorial.trampoline(n - 1, n * acc)
}.trampoline()
factorial(1000) // It works.
There is no tail recursion in Java, and hence there is none in Groovy either (without using something like trampoline() as you have shown)
The closest I have seen to this, is an AST transformation which cleverly wraps the return recursion into a while loop
Edit
You're right, Java (and hence Groovy) do support this sort of tail-call iteration, however, it doesn't seem to work with Closures...
This code however (using a method rather than a closure for the fact call):
public class Test {
BigInteger fact( Integer a, BigInteger acc = 1 ) {
if( a == 1 ) return acc
fact( a - 1, a * acc )
}
static main( args ) {
def t = new Test()
println "${t.fact( 1000 )}"
}
}
When saved as Test.groovy and executed with groovy Test.groovy runs, and prints the answer:
402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
As a guess, I would say that the JVM does not know how to optimise closures (like it does with methods), so this tail call does not get optimised out in the bytecode before it is executed
Starting with version 2.3 Groovy supports tail recursion with the #TailRecursive annotation for methods:
http://java.dzone.com/articles/groovy-goodness-more-efficient

Divide up money evenly in C# using a functional approach

I have these 2 values:
decimal totalAmountDue = 1332.29m;
short installmentCount = 3;
I want to create 3 installments that have an even amount based on the totalAmountDue (extra pennies apply starting with the lowest installment number going to the highest installment number) using this class:
public class Installment
{
public Installment( short installmentNumber, decimal amount )
{
InstallmentNumber = installmentNumber;
Amount = amount;
}
public short InstallmentNumber { get; private set; }
public decimal Amount { get; private set; }
}
The installments should be as follows:
{ InstallmentNumber = 1, Amount = 444.10m }
{ InstallmentNumber = 2, Amount = 444.10m }
{ InstallmentNumber = 3, Amount = 444.09m }
I am looking for an interesting way to create my 3 installments. Using a simple LINQ to objects method would be nice. I have been trying to understand more about functional programming lately and this seems like it could be a fairly good exercise in recursion. The only decent way I can think of doing this is with a traditional while or for loop at the moment...
There's not a whole lot here that is "functional". I would approach the problem like this:
var pennies = (totalAmountDue * 100) % installmentCount;
var monthlyPayment = totalAmountDue / installmentCount;
var installments = from installment in Enumerable.Range(1, installmentCount)
let amount = monthlyPayment + (Math.Max(pennies--, 0m) / 100)
select new Installment(installment, amount);
You might be able to work something out where you constantly subtract the previous payment from the total amount and do the division rounding up to the nearest penny. In F# (C# is too wordy for this) it might be something like:
let calculatePayments totalAmountDue installmentCount =
let rec getPayments l (amountLeft:decimal) = function
| 0 -> l
| count -> let paymentAmount =
(truncate (amountLeft / (decimal)count * 100m)) / 100m
getPayments (new Installment(count, paymentAmount)::l)
(amountLeft - paymentAmount)
(count - 1)
getPayments [] totalAmountDue installmentCount
For those unfamiliar with F#, what that code is doing is setting up a recursive function (getPayments) and bootstrapping it with some initial values (empty list, starting values). Using match expressions it sets up a terminator (if installmentCount is 0) returning the list so far. Otherwise it calculates the payment amount and calls the recursive method adding the new installment to the front of the list, subtracting the payment amount from the amount left, and subtracting the count.
This is actually building the list in reverse (adding on to the front each time), so we throw away the extra pennies (the truncate) and eventually it catches up with us so the penny rounding works as expected. This is obviously more math intensive than the add/subtract code above since we divide and multiply in every iteration. But it is fully recursive and takes advantage of tail recursion so we'll never run out of stack.
The trouble with C# here is that you want a sequence of installments and recursion and there's no idiomatic built-in structure for doing that in C#. Here I'm using F#'s list which is immutable and O(1) operation to prepend.
You could possibly build something using the Scan() method in the Reactive Extensions to pass state from once instance to another.
Talljoe,
I think you are pushing me in the right direction. This code below seems to work. I had to switch out how the penny math was working but this looks pretty good (I think)
decimal totalAmountDue = 1332.29m;
short installmentCount = 8;
var pennies = (totalAmountDue * 100) % installmentCount;
var monthlyPayment = Math.Floor(totalAmountDue / installmentCount * 100);
var installments = from installmentNumber in Enumerable.Range(1, installmentCount)
let extraPenny = pennies-- > 0 ? 1 : 0
let amount = (monthlyPayment + extraPenny) / 100
select new Installment(installmentNumber, amount);

Resources