Hacker News new | past | comments | ask | show | jobs | submit login

Java and Python, for a start, have decimal number types in their standard distributions.



In Java, the java.math.BigDecimal is not a primitive data type. It also has an awkward api due to lack of operator overloading (thanks to BigDecimal not being a primitive data type it seems).

In Python, the story looks slightly better:

    from decimal import *
    >>> getcontext().prec = 6
    >>> Decimal(1) / Decimal(7)
    Decimal('0.142857')
But neither of these data types is even close to being a first class citizen in either language.


.NET at least made it a primitive, with operators and stack allocation. I had forgotten how terrible this is in Java.


Well that's true, and if you're going to argue that the lack of equally or more concise syntactic support is an omission, I agree. I think 1.23 should denote a decimal floating point constant, and a special suffix should be required if you want to use binary.

But I think it's important to make sure programmers don't end up with the idea that they might as well store money amounts in binary floating point because the language they are using doesn't support decimal.


> In Java, the java.math.BigDecimal is not a primitive data type. It also has an awkward api due to lack of operator overloading (thanks to BigDecimal not being a primitive data type it seems).

If you're on the JVM, Groovy is nicer in that regard. It uses by default BigDecimal and BigInteger for literal numeric types, and has operator overloading: http://groovy-lang.org/syntax.html


> It uses by default BigDecimal and BigInteger for literal numeric types

Apache Groovy uses by default BigDecimal for literal decimal types, but only uses BigInteger for literal integral types when it would overflow the largest available primitive type for that literal. You can force a BigInteger by using the suffix `g` on the integral literal. Perhaps misunderstanding this is the source of some hard-to-find bugs in some of your Groovy code.


  .getcontext().prec = 6
makes no sense for money. You need 2 digits after the decimal point constantly, whether it is 0.01 or 1000000.01

AFAIK (and I don't do this for work), after every calculation you manually need to call quantize as in

  cents = decimal.Decimal('.01')
  money = price.quantize(cents, decimal.ROUND_HALF_UP)


How would you handle prices for components which do have more significant digits than 2? ( I have examples if you wish ).


Of course more digits than 2 exists. In Germany petrol/gas has always been priced with 3 decimals. And in B2B it's even more common. I'm talking about 98% of consumer business where the precision is full cents for each transaction.

In general you need to know when to round and to how many digits. But my complaint was that languages have a natural API for binary floating point, which is useful for scientific number crunching, but rarely anything comparable for commercial calculations.

I have not tried to design a natural API for fixed (but parameterizable) decimal precision and the implicit rounding required. But I would be surprised if it's impossible to come up with anything less verbose (explicit constructors everywhere) and less error prone (forgetting to call rounding).


I'm not talking about money, I am talking about the decimal data type, as is OP.

https://en.wikipedia.org/wiki/Decimal_data_type

Also, I don't try to endorse the Python API. I don't even use it. I just pointed out their api is easier since the operators work with their decimal data type, as opposed to the Java version.


In Haskell you'd use Fixed (https://hackage.haskell.org/package/base-4.10.1.0/docs/Data-...) with your desired precision (E2 for most currencies). It's in base, so no third-party libraries are required.


Too bad there isn’t one in C++ — everyone rolls their own. Would really make sense to have it as part of STL.


There are arbitrary-precision math packages: gmp and MPFR are the big ones, MPDecimal is what Python uses but is in C, etc.


Perhaps he means that by default money will be handled incorrectly.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: