1

I have a number in the format of (13,2) 13 digits and 2 decimal places. I need to do some calculation on it (like multiplication, division). I am planning to use BigDecimal for the calculations. Shall i use double or float for the calculation as BigDecimal is bit on slower side?

user207421
  • 305,947
  • 44
  • 307
  • 483
suraj bahl
  • 2,864
  • 6
  • 31
  • 42
  • Possible duplicate of [How using BigDecimal would affect application performance?](http://stackoverflow.com/questions/1378044/how-using-bigdecimal-would-affect-application-performance) – azurefrog Jan 29 '16 at 01:50
  • 1
    What precision do you need for the calculations? And what are your performance requirements? – Elliott Frisch Jan 29 '16 at 01:50
  • 1
    What precision do you need? When you divide, do you need only the whole number or also the fraction? – Gavriel Jan 29 '16 at 01:50
  • 3
    What is the data? If it's money, *never* use `double,` always `BigDecimal.` Or get the database to do the calculations for you, if there's a database. NB These are decimal *places,* not 'decimals', and it's 'multiplication', not 'multiple'. – user207421 Jan 29 '16 at 01:54
  • how often do you use the number for calculation?! do you use the whole number or just decimals?! – Kenny Tai Huynh Jan 29 '16 at 01:57
  • 1
    @KennyTaiHuynh and others: Can we **PLEASE** get out of this meaningless habit of using the word 'decimals' where 'decimal *places*' is meant? 'Decimal' is a radix, not a part of a number. I've also seen it used to mean 'decimal point', which shows how futile it all is. – user207421 Jan 29 '16 at 01:59
  • Thanks EJP. will care this from now on. – Kenny Tai Huynh Jan 29 '16 at 02:01
  • Also, what is the size of the dataset? If you're doing BigDecimal calculations (vs. float) on 100 values the performance difference is meaningless, where 100 million values it might be a consideration (but always _behind_ correctness, as Daniel Pryden answers). – Stephen P Jan 29 '16 at 02:02
  • @EJP: [It can also mean decimal places](https://en.wikipedia.org/wiki/Decimal_%28disambiguation%29). – Rudy Velthuis Feb 10 '16 at 10:06

2 Answers2

7

The most important consideration is not speed but correctness.

If your value is a sample of a continuous value, like a measurement of a real-world property like size, distance, weight, angle, etc., then an IEEE-754 double or float is probably a better choice. This is because in this case powers of ten are not necessarily "rounder" than other values (e.g. angular measurements in radians can be transcendental numbers but still "round").

If your value is a discrete value like a measurement of money, then double is incorrect and a floating-point decimal type like BigDecimal is correct. This is because, in this case, discrete increments are meaningful, and a value of "0.01" is "rounder" and more correct than a number like "0.009999999999999" or "0.010000000000000001".

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
  • Exactly. You can get the wrong answer in zero time, if time is your only consideration. – user207421 Jan 29 '16 at 01:59
  • does your answer change for base 2 "round" values? like binary byte values, `Mib, TiB,..` etc. I'm guessing not, because the binary values are descrete. – activedecay Jan 29 '16 at 02:00
  • @activedecay: People don't usually talk about base-2 in the context of values between 0 and 1, but if you mean negative powers of two, then that's exactly how IEEE 754 floating-point works. It will "round off" to 1/256, but not to 1/100. – Daniel Pryden Jan 29 '16 at 02:01
  • Let me clarify, @Dan, if I convert values from GiB to TiB, there will sometimes be a fractional component. When I store the TiB number, should I use BigDecimal because the TiB values are descrete? Said another way, converting back from TiB to GiB shouldn't be lossy. – activedecay Jan 29 '16 at 02:09
  • ah I think i get it now Dan. `1/(2^x)` will easily be represented by IEEE-754 floating point, as long as x is small. – activedecay Jan 29 '16 at 02:31
  • 1
    @activedecay: Bytes are a discrete measurement, so I would just store an integer in bytes and then handle GiB, TiB etc in formatting. Modern CPUs can handle 128-bit integers, which will be more than enough. – Daniel Pryden Jan 29 '16 at 05:42
0

The simplest, most natural representation for data with two decimal places is BigDecimal with scale factor 2. Start with that. In most cases it will be fast enough.

If, when measured, it really is a serious performance problem, there are two more options:

  1. Use long to represent the number of hundredths. For example, US currency can be represented exactly as a long number of cents. Be very careful to ensure variable names and comments make it clear where dollars are being used, and where cents are being used.
  2. Use double to represent the amount as a fraction. This avoids the dollars-vs-cents bookkeeping, at the expense of rounding issues. You may need to periodically correct the rounding by multiplying by 100, rounding to nearest integer, and dividing by 100 again
Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75