-
Notifications
You must be signed in to change notification settings - Fork 183
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
checked_add() not catching underflow/overflow when adding a very large number to a very small number #511
Comments
Hmm, this is an interesting case. The reason why this is happening is because when adding together the two numbers the resulting value has a bits in underflow. For underflow, we attempt to round the number to "make it fit" - of course, useful for scenarios where the number may be repeating (e.g. I'd need to have a think about this one, as the behavior is explicitly for underflow handling (even though it results in an overflow). Ultimately, it is expected behavior even if it's slightly ambiguous. That being said, I do agree that it isn't immediately obvious and in some cases you may actually want underflow to be ignored. I'll need to mull on that one and perhaps do some research on how we could handle this ergonomically. |
As a side note, something I'd like to see is delayed evaluation - retaining precision until point of evaluation back into a Something like this would be useful for a lot of the mathematical functions, but could also be used for features such as this. i.e. it could return an error on underflow unless an explicit call to |
How does this make the lib any different from just 128bit floating point numbers?
Following a rudimentary description of fixed-point-arithmetic (https://en.wikipedia.org/wiki/Fixed-point_arithmetic)
This library clearly has floating point and can result in underflow and a loss of precision. The primary use of fixed-point financial libraries is to avoid a loss of precision within the fixed bounds. |
The major difference between a typical IEEE-754 floating point number and this library is that we store numbers as By storing the number with a base 10 exponent we effectively are storing the number of decimal places. For example, if the mantissa is Of course, the issue is that we have limited space to be able to store everything. This was a design choice for this library so that we could leverage some optimizations. Due to the space limitations, the library takes some liberties to ensure that everything works as expected - that is, it will try to round underflow where it makes sense. With the introduction of const generics there is the opportunity to extend this libraries optimizations to allow greater precision with little compromise - which is definitely something I'm looking into. Though, there will always be an underflow component somewhere which needs to be handled - which could turn into overflow as it reaches storage limitations. I certainly don't intend to mislead here - I don't think we've used the term fixed-point anywhere but if fixed-precision is being misconstrued then I'm more than happy to clarify this in the blurb. |
Technically speaking, there is no difference. Both are represented by an integral mantissa plus an integral exponent. For floating-point numbers, both the mantissa and the exponent are base 2. For this library, the mantissa is base 2 while the exponent is base 10. And therefore, precision is not really the issue here. This library has no more precision than a 128-bit floating-point. They are equivalent. The difference is representation. This library can represent all decimal numbers within range (because it is base-10). A floating-point number cannot represent all decimal numbers because the exponent is base-2: there are numbers that cannot be exactly represented, thus requiring mapping to an alternate representation, resulting in "loss of precision". Understand that it is not precision that is lost here... it is a failure of representation that forces an artificial difference. In a world where people have two fingers and count in base-2 (say, an apple is priced at $100.1 dollars -- $4.5 in decimal), then the IEEE floating-point format is exact and has no more "loss of precision" than this library. In such a world, the happy programmers has no need for |
Hello and first off, thank you for this crate.
It seems that checked_add() does not catch addition overflow when adding a very large number to a very small number.
For example,
My guess is that this has something to do with the potential loss of precision when adding a very large number to a very small number. checked_add() will try to round up dec!(0.45) before performing the addition.
Is this expected? Is there a way to prevent this from happening?
The text was updated successfully, but these errors were encountered: