Results 1 to 18 of 18
Thread: BIG decimals
- 09-29-2010, 05:33 PM #1
Member
- Join Date
- Sep 2010
- Posts
- 31
- Rep Power
- 0
BIG decimals
Hey,
I'm working on a program that will calculate pi, and I need a way to store digits beyond the 16 that a double can hold. I've looked into BigDecimals, but can't find out how many digits of a number that they can hold. Does anyone know how many digits bigdecimals hold or another way to store many digits usable in math (so not a string)?
Thanks
- 09-29-2010, 05:46 PM #2
Member
- Join Date
- Sep 2010
- Posts
- 31
- Rep Power
- 0
I meant, is there something more precise than a LONG? BigDecimal question still standing.
- 09-29-2010, 06:02 PM #3
BigDecimal is basically an integer without a maximum size that is scaled, using 10^(-scale). Therefore, because it is arbitrary precision, it does not have a maximum size until the computer runs out of memory.
- 09-29-2010, 06:37 PM #4
Member
- Join Date
- Sep 2010
- Posts
- 31
- Rep Power
- 0
So... is it as accurate as an int (not to very many places)?
- 09-29-2010, 07:33 PM #5
An Integer is a wrapper for the primitive type, int.
- Range: -2^31 to 2^31 - 1
A BigInteger is an arbitrary-precision type of integer, capable of storying any integer of any size, so long as the computer has enough memory to store it.
- Range: -infinity to +infinity (no decimal precision)
A BigDecimal is essentially a BigInteger multiplied by 10^(-x) where x is some scale (0 to infinity, as far as I'm aware), which means that it can be infinitely precise if your computer is powerful enough.
- Range: -0.999999999999999 to +0.999999999999999 (both repeated to infinity)
- 09-29-2010, 10:21 PM #6
Member
- Join Date
- Sep 2010
- Posts
- 31
- Rep Power
- 0
Fantastic! The arbitrary precision aspect is awesome... in concept. Whenever I go to divide two BigDecimals though, the result is either a total loss of precision in rounding or an error. Say I wanted to divide a big decimal equal to two by another equal to three, I could round and have a result of one, or I'd get an error saying "Exception in thread "main" java.lang.ArithmeticException: Rounding necessary". I understand what that means... but is there a way around this?? I tried multiplying the numerator up by a constant then performing the division with rounding, then dividing the quotient by the above constant. Like so:
Java Code://numer=numerator, digitcount= "constant", denom= denominator, //local = quotient numer=numer.multiply(digitcount); BigDecimal local = numer.divide(denom, RoundingMode.CEILING); local=local.divide(digitcount, RoundingMode.UNNECESSARY); numer=numer.divide(digitcount, RoundingMode.UNNECESSARY);
- 09-29-2010, 11:29 PM #7
This is because BigDecimal cannot handle non-terminating sequences, which is a bit unfortunate. However, there is a bit of a work around:
Create a function that "tries" to divide using BigDecimal; if it fails, "catch" the error and return a double division instead. Something like this:
The result of such a program is:Java Code:{ BigDecimal two = new BigDecimal(2); BigDecimal three = new BigDecimal(3); System.out.println(base.DivideDecimals(two,three).toString()); System.out.println(base.DivideDecimals(three,two).toString()); } public static BigDecimal DivideDecimals(BigDecimal a, BigDecimal b) { try { System.out.println("Attempting BigDecimal division.."); return a.divide(b); // Don't attempt to round here. } catch (ArithmeticException ae) { System.out.println("BigDecimal division failed. Using doubles."); return new BigDecimal(a.doubleValue() / b.doubleValue()); } }
Java Code:run: Attempting BigDecimal division.. BigDecimal division failed. Using doubles. 0.66666666666666662965923251249478198587894439697265625 Attempting BigDecimal division.. 1.5 BUILD SUCCESSFUL (total time: 1 second)
Much luck!
- 09-30-2010, 12:16 AM #8
Member
- Join Date
- Sep 2010
- Posts
- 31
- Rep Power
- 0
Hey sick it worked! Only one more thing... is there a way to limit the number of digits used? Although I want a lot of digits, I don't want so many that it's too much for the the output pane so it tells me to put it in wrap mode. I've tried multiplying by X then dividing by X with rounding... no difference. Ideas?
- 09-30-2010, 01:53 AM #9
Member
- Join Date
- Sep 2010
- Posts
- 31
- Rep Power
- 0
Forget the last one... found the beauty of MathContexts... thanks for all your help, Zack
- 09-30-2010, 09:24 AM #10
Moderator
- Join Date
- Apr 2009
- Posts
- 10,484
- Rep Power
- 16
Dividing doubles as a replacement for BigDecimal isn't a good idea. Presumably your are using BigDecimal (in part) to avoid the inevitable imprecision of a float-based number. Dividing doubles will simply mean re-introducing that imprecision.
What you want to do is provide a scale to the BigDecimal, which tells it how many decimal places to use. divide() has a scale parameter. So this:
will fail witht he exception you gave, but this:Java Code:BigDecimal bd1 = new BigDecimal(2); BigDecimal bd2 = new BigDecimal(3); BigDecimal result = bd1.divide(bd2); System.out.println(result);
gives an output ofJava Code:BigDecimal bd1 = new BigDecimal(2); BigDecimal bd2 = new BigDecimal(3); BigDecimal result = bd1.divide(bd2, 20, RoundingMode.HALF_UP); System.out.println(result);
0.66666666666666666667
(20 decimal places)
- 09-30-2010, 05:48 PM #11
The double is simply an alternative because most numbers dividing into non-terminating sequences can easily be scaled to doubles. Both methods work.
- 09-30-2010, 08:13 PM #12
Moderator
- Join Date
- Apr 2009
- Posts
- 10,484
- Rep Power
- 16
Except if you want something accurate (which you will do if you are trying to calculate pi to some number of decimal places) a float-based thing won't do, due to the inevitable innacuracies of a float.
It's why currency is always held as a BigDecimal.
- 09-30-2010, 08:50 PM #13
Since when is currency always held as a BigDecimal? That doesn't make intuitive sense. Currency is only ever held to two decimal places, with the third as a reference ($0.00 ± $0.001). As you saw in my output above, the double was accurate to 17 decimal places + a rounding decimal place. If you carried five decimal places, that would be excessively accurate for currency.
- 10-01-2010, 08:42 AM #14
Moderator
- Join Date
- Apr 2009
- Posts
- 10,484
- Rep Power
- 16
In any financial system I have worked on, that's where.
Currency conversion, for example is usually held to 5 decimal places, and you'll start to lose more than pennies if that isn't accurate...
- 10-02-2010, 12:21 AM #15
I just converted an arbitrary value of the highest-value currency (Kuwait Dinar) to the lowest-value currency (Zimbabwe Dollar), and didn't lose any precision by trimming to 5 decimal places.
Where is the precision loss here? And we can make that number as big as we want--12,345 trillion, if you please--anything to the left of the decimal has no place in this.Java Code:12,345.67891 KWD = 15,724,848.09 ZWD 12,345.67891234568015 KWD = 15,724,848.09015080519021 ZWD
- 10-03-2010, 04:43 PM #16
Moderator
- Join Date
- Apr 2009
- Posts
- 10,484
- Rep Power
- 16
Except you have introduced a problem as soon as you are dealing in such imprecision.
Having calculations that result in 1.99999999 instead of 2.0 (just an example) means you have introduced an incorrect value into your financial data. And since these calculations usually involve large numbers of numbers, each with their own potential innacuracy, you will (yes will, I have seen it) get results that are wrong. And these results leave you liable when the tax man comes to visit (or a client queries a total).
There is a reason that Sun, Oracle, IBM (to name but three) point out that all financial data should be handled using BigDecimals, or longs, rather than float/double.
- 10-04-2010, 03:40 AM #17
You're still truncating the data to 20 decimal places though in the example above, whilst mine basically truncates it to 16-ish. I know that's a factor of 10^4 but is it likely that you're going to be adding so many numbers that 1*10^-17 is important? Likely not.
- 10-04-2010, 10:14 AM #18
Moderator
- Join Date
- Apr 2009
- Posts
- 10,484
- Rep Power
- 16
Similar Threads
-
Formatting numbers or decimals (around comma)
By Joris in forum Advanced JavaReplies: 1Last Post: 04-22-2010, 05:46 PM -
Decimals in java help!!
By Gold in forum New To JavaReplies: 3Last Post: 12-09-2009, 11:25 PM -
number to word with decimals
By fertas in forum New To JavaReplies: 3Last Post: 08-30-2008, 03:12 AM -
Java Program To Convert A Number In To Words With Decimals
By javanewbie in forum New To JavaReplies: 1Last Post: 07-02-2008, 01:58 PM -
get more decimals?!?! please help!
By michcio in forum New To JavaReplies: 7Last Post: 05-22-2008, 10:26 PM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks