-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Refactor BigDecimal #10641
Comments
It would be really great to have decimal implemented exclusively in Crystal. If that were the case, we could even introduce a literal for them. They are very useful, for example for representing money amounts. C# has a built-in decimal type. |
Finite precision, or arbitrary precision? (C#'s is the former, but it isn't one of the IEEE decimal formats either) |
I don't know |
Finite precision floating-pount decimal numbers should be relatively trivial to implement. For representing monetary values however, you would better use a fixed-point data type than floating-point (when precision is finite). There's no point in being able to represent values in larger orders of magnitudes, when the primary concern is to be exact down to a certain number of decimal digits (usually 4 in monetary applications). Implementing arbitrary precision floating-point decimal numbers essentially means we have to implement arbitrary precision integers ( |
That's only correct for FIAT currencies. Cryptocurrencies can have as much as 18 decimals (see Ether for example). |
Apart from making I don't think |
Technically, non-normalized values could be used to express precision. But we don't offer access to that and many implementations already apply normalization, so making it the default sounds good. |
I just created #11076 which is related to how Are there any plans for BigDecimal beyond this GitHub issue? I'm interested in contributing here, if this is an appropriate place to start. |
While looking into current issues around BigDecimal (#10502, #5714, #10599, #9547, #9578) it became apparent that the current implementation is lacking.
Our implementation is based on https://github.com/akubera/bigdecimal-rs but worse. And even that is IMO not the best role model.
A pretty extensive implementation with great documentation is Python's
decimal
library. Julia's Decimals.jl is another good example. There is actually a technical standard for decimal floating point numbers in IEEE 754.A few observations about the data format in comparison with Python/Julia implementations:
BigDecimal#scale
is an unsigned integer and represents the amount of digits the decimal point is shifted to the left, i.e. a negative exponent to the base of 10. The number is described by the formulavalue * 10 ** -scale
. In the other definitions, the scale is a signed exponent and allows shifting the decimal point in both directions. Large numbers could already be expressed by a large enough BigInt value for the coefficient, but a signed exponent expresses precision. The formula isvalue * 10 ** exponent
. Soscale
is the same value asexponent
but with opposite sign.Nan
,+Infinity
,-Infinity
are missing in our implementation.The specs for
BigDecimal
are pretty scarce for most methods, so I wouldn't be surprised to discover more bugs like (#10502).The other
Big*
types are mostly wrappers for libgmp, so there's less chance for error on our side.BigDecimal
is the only type implemented in Crystal.The text was updated successfully, but these errors were encountered: