Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Survey use cases for BigDecimal (or similar types) #3

Open
littledan opened this issue Nov 13, 2019 · 7 comments
Open

Survey use cases for BigDecimal (or similar types) #3

littledan opened this issue Nov 13, 2019 · 7 comments

Comments

@littledan
Copy link
Owner

@littledan littledan commented Nov 13, 2019

Would BigDecimal be useful for you? (Or, would Rational, Decimal128, or some other type be useful for you?) Why? Reports on this thread are encouraged to include:

  • Code samples (either current code or ideal/hoped-for code)
  • Context of how this shows up in an application and why you need it

Let's just collect use cases in this thread, and then we can consolidate/analyze it all in other issues.

Cases where you're not using a decimal type, and it's causing a bug (with code samples and context/motivation, and how a decimal type could fix it) are also welcome.

@MaxGraey

This comment has been minimized.

Copy link

@MaxGraey MaxGraey commented Nov 13, 2019

I'm also wondering is it necessary implement all methods of Math namespace for BigDecimal?

@littledan

This comment has been minimized.

Copy link
Owner Author

@littledan littledan commented Nov 13, 2019

@MaxGraey Would it be useful for you to do so?

@MaxGraey

This comment has been minimized.

Copy link

@MaxGraey MaxGraey commented Nov 13, 2019

It's hard to tell. Even Julia and R-lang hasn't builtin arbitrary precision decimal arithmetic. Julia has only Rational. And decimal numbers implement as third party libs which it seems not really popular 1 and 2

@littledan

This comment has been minimized.

Copy link
Owner Author

@littledan littledan commented Nov 13, 2019

I guess I am not so surprised if rational took the wind out of decimal's sails in these cases; that matches what I have seen in other languages that include either fixed precision or arbitrary precision decimal: that there isn't a very popular ecosystem library for the other choice. Having a "standard" option is just so useful that it's not worth it to develop or seek out alternatives, even if they may be somewhat technically better for a particular case.

My understanding of the JS ecosystem is that the libraries for decimal are rather popular, and rational libraries are not so popular. Let's discuss the rational alternative in #6 and the JS ecosystem in #22 .

@qzb

This comment has been minimized.

Copy link

@qzb qzb commented Nov 15, 2019

In company I currently work for (@g2a-com), we are dealing with a lot of financial data, which (obviously) cannot be safely represented using floats. We had to solve two problems with representing such data - how to store it in JSON and how to transform it within application.

From my experience currently there are three ways for solving these problems.

1. Integers using number type

Financial amounts can be represented with number type using the lowest subdivision of particular currency (euro cent for euro, kopek for ruble, yen for yen, etc). Such value has to be treated as an integer.

Pros

  • Doesn't require additional steps during deserialization.
  • Supports operators (+, -, *, /, ===, etc).

Cons

  • When comes to representing amounts lesser than lowest subdivision it can be tricky. Obviously developers can use lower denominator, but it falls apart when comes to cryptocurrencies - there is no enough digits of precision to reliably represent them in all cases.
  • You have to settle on some minimal precision. In our case this wasn't a problem, we have some some requirements for smallest amounts that can be stored by our systems.
  • Developers need to take care getting rid of fraction amounts after divisions.
  • Nothing prevents developers to stop treating amount as an "integer".

2. Integers using BigInt

Instead of using number to represent integers, you can use BigInts. By default BigInts aren't JSON serializable, but in this case they should be represented by strings.

Pros

  • Supports operators (+, -, *, /, ===, etc).
  • Although precision still need to be fixed, but there is not limit for it (so it can be used for cryptocurrencies).
  • It makes difficult to use floats for amounts (either by mistake or lack of knowledge).

Cons

  • You (still) have to settle on some minimal precision.
  • Both serialization and deserailization require additional steps.

3. Strings and decimals

Amounts can be stored in JSON using strings, which can be later wrapped with some decimals library (like decimal.js) for enabling making operations on them.

Pros

  • You don't have to worry about precision.
  • It makes difficult to use floats for amounts.

Cons

  • Additional work during deserialization (all amounts have to be converted to decimals).
  • No support for arithmetic operators, all operations have to be done with methods (.plus(), .times(), .equals(), etc).

Native Decimal type would be obvious enhancement for 3rd solution, support for arithmetic operators would make working with decimals much easier. AFAIK Decimal128 have sufficient precision to deal with financial amounts (even when cryptocurrencies with come to play). Personally I would prefer to have BigDecimal over Decimal128, but in this case Decimal128 is enough.

I don't see any advantages of using Rational type for storing financial amounts.

@DavidBM

This comment has been minimized.

Copy link

@DavidBM DavidBM commented Nov 16, 2019

I'm working at @omnea. We don't execute many monetary operations, but we want to have enough precision in the language to be safe. What we deal with more frequently are annoying issues with the DB and third party apps.

In our case:

MySQL decimal type

We would like to have a type to match the DECIMAL SQL type. One problem we recently hit is: sequelize/sequelize#7465

This forces the libraries to use strings in order to cover all cases. A native type would solve the issues and provide the DB libraries with a type able to match the DB types.

Third party systems

Our system communicates with many third party systems that, for some reason, send long decimals. It would help us if the language has the same capacities as the JSON format ones as it doesn't have a precision limit. Sometimes, parsing a JSON with a number field generated by another language can mean data loss.

Sometimes these decimals are there because other systems are not doing things "the correct way" but at the end we need to deal with it. Almost every other language has bigger floats types and that ends making harder to pass data between systems when one system has no way to parse data from the other system.

In summary, in our case BigDecimal would help us to communicate with other services with less effort. For us is more about having the ability to represent data without loosing precision rather than doing operations with it.

@littledan

This comment has been minimized.

Copy link
Owner Author

@littledan littledan commented Nov 17, 2019

By the way, PRs to the README to add realistic code samples are very much welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.