• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

BigDecimal divide()

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So I was noticing imprecision with division of large numbers, and have concluded by process of elimination that it stems from the divide() method. Would it be possible to fix the method to make it accurate to more sig figs? Or is there an inevitable reason for the shortcoming?

What made me notice it was calculating derangements (aka subfactorials). I used the asymptotic formula !n = n!/e. I have a method for factorials that returns a BigInteger. I initialized a BigDecimal from the BigInteger, then divided it by Math.E. When it got a slightly wrong answer I increased the precision to a few thousand, but that got the same answer. I thought maybe E didn't have enough sig figs, so I tried changing some of the last digits to see if that would make the answer more wrong. It didn't. So I'm thinking the problem resides in the divide() method itself.

It's wrong when n>=19.

For n=19 the last two digits of the integer part should be 06 or 05 (the number has to round to an integer ending in 06, shown here: http://www.wolframalpha.com/input/?i=!19). Instead they're 09 and the decimal part begins with 922 so the integer part rounds to 10.

My derangement method isn't important, I'm just curious about this for when I use BigDecimals in the future. I don't see the point in BigDecimal division if divide() isn't more precise than dividing two doubles together. Nor the point in allowing the user to set the precision so high, when all the digits are gonna be wrong anyway.

Thanks for any light you can shed.
 
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Frank Stalone wrote:I thought maybe E didn't have enough sig figs, so I tried changing some of the last digits to see if that would make the answer more wrong. It didn't.



But it doesn't have enough sig figs. It's a double, after all, so that means it only has about 16. And 19! is on the order of 10^17, so you could expect errors to creep into the units digit in that case.
 
Frank Stalone
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh, yeah you're right. Instead of changing some digits I should have just tried with more digits. I did that now, made a bigdecimal e with lots of digits and now the subfactorial method gets the right answers.

It should have been obvious, the inaccuracy was happening on the 17th digit.
 
reply
    Bookmark Topic Watch Topic
  • New Topic