Re: Fixed-point arithmetic library
On 22.02.2012 22:39, Tom Anderson wrote:
Evening all,
I would quite like to represent some numbers in fixed point, and do
arithmetic with them.
Fixed point math is susceptible to precision issues which can be more
severe than those of float and double: 0.01 * 0.2 -> 0.00
http://en.wikipedia.org/wiki/Fixed_point_arithmetic#Precision_loss_and_overflow
Out of curiosity: What do you want to do with that?
These numbers will mostly not be more than a bilion, and will probably
never be more than a hundred billion. Some of them, i will need to
represent to eight decimal places. I'd like to be able to multiply two
large numbers, but i suspect will not need to multiply three. 11 * 2 + 8
= 30 decimal digits; that's about 100 bits, so 128 bits would be big
enough (about 5 decimal digits of headroom).
Can anyone suggest an existing library for doing fixed-point arithmetic
which would cover this?
I have googled, but not found anything. There are a few fixed-precision
libraries aimed at J2ME (i assume because old phones didn't have
floating-point units?). There's something called jExigo, but it's 64-bit
and the code doesn't look great.
It's quite possible that there is no such library. But i thought it
prudent to ask before writing one myself.
What about BigDecimal?
http://docs.oracle.com/javase/6/docs/api/java/math/BigDecimal.html
You could either add the precision loss after operations or just apply
it for output.
package math;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class FixedPointMath {
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal("0.01");
BigDecimal bd2 = new BigDecimal("0.2");
BigDecimal bd3 = bd1.multiply(bd2);
BigDecimal bd4 = bd3.setScale(2, RoundingMode.HALF_UP);
System.out.println(bd1 + " * " + bd2 + " -> " + bd3 + " -> " +
bd4);
}
}
Alternatively you could use BigInteger and add the scaling logic
yourself when cooking your fixed math lib.
http://docs.oracle.com/javase/6/docs/api/java/math/BigInteger.html
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/