patternjavaMinor
Calculating Pi with Android
Viewed 0 times
withcalculatingandroid
Problem
I'm kind of new to Java but I am writing an Android app. Right now I'm working on an async task to calculate Pi but when I run it the memory usage increases alarmingly (+5MB per second). This one piece of code may need to run thousands of times so it is important that it be very optimized.
This one piece of code may need to run thousands of times so it is important that it be very optimized.
protected BigDecimal doInBackground(Object... params) {
digits = (int)params[0];
piView = (TextView)params[1];
boolean add = true;
BigDecimal pi = new BigDecimal(0.0);
for(int i=1; pi.setScale(digits, BigDecimal.ROUND_DOWN).equals(realPi) == false; i++){
if(add){
pi = pi.add(new BigDecimal(4.0 / (-1 + (i*2))));
add = false;
}
else {
pi = pi.subtract(new BigDecimal(4.0 / (-1 + (i*2))));
add = true;
}
}
return pi;
}This one piece of code may need to run thousands of times so it is important that it be very optimized.
Solution
boolean add = true;
for(int i=1; pi.setScale(digits, BigDecimal.ROUND_DOWN).equals(realPi) == false; i++){
if(add){
pi = pi.add(new BigDecimal(4.0 / (-1 + (i*2))));
add = false;
}
else {
pi = pi.subtract(new BigDecimal(4.0 / (-1 + (i*2))));
add = true;
}
}You don't need an
add variable. Consider int i = 1;
while (!pi.setScale(scale, BigDecimal.ROUND_DOWN).equals(realPi)) {
pi = pi.add(new BigDecimal(4.0 / i));
i += 2;
pi = pi.subtract(new BigDecimal(4.0 / i));
i += 2;
}This may do one extra
subtract operation, but it does half as many equals operations. And it doesn't waste time on setting and checking a variable just to alternate between two operations. We don't need the
(-1 + (i*2)) part. If we increment by 2 instead of 1, we get the same stream of values with strictly less math. 1, 3, 5, 7, 9, 11, ...I changed the
== false to the more idiomatic !. I also changed
digits to scale as I had trouble reading the original. BigDecimal gives precise results, not quick results. It is quite possible that you are hitting real limits of the format. It's unclear at the moment why you are calculating \$\pi\$. With more context, we might be able to give more help.Code Snippets
boolean add = true;
for(int i=1; pi.setScale(digits, BigDecimal.ROUND_DOWN).equals(realPi) == false; i++){
if(add){
pi = pi.add(new BigDecimal(4.0 / (-1 + (i*2))));
add = false;
}
else {
pi = pi.subtract(new BigDecimal(4.0 / (-1 + (i*2))));
add = true;
}
}int i = 1;
while (!pi.setScale(scale, BigDecimal.ROUND_DOWN).equals(realPi)) {
pi = pi.add(new BigDecimal(4.0 / i));
i += 2;
pi = pi.subtract(new BigDecimal(4.0 / i));
i += 2;
}Context
StackExchange Code Review Q#146539, answer score: 3
Revisions (0)
No revisions yet.