|
Dang, the target users were not Voguns or have a lack of taste, so black on black not sure an issue!
|
|
|
|
|
Message Removed
modified 21-Mar-24 2:04am.
|
|
|
|
|
Message Removed
modified 21-Mar-24 2:04am.
|
|
|
|
|
but I stand corrected.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
Not sure if this counts as a programming question, since I'm not asking for code but rather preference. I'm in a project that requires complete accuracy on numbers. So, given the following...
We all know the famous of examples of stuff like this:
0.1 + 0.2
Up until now, I've been content with rounding off any operations after the fact and calling it a day, as close enough was good enough. For applications, say that deal with currency, the age old trick is to just use integers based on a cent value. So, a $1.23 would be stored as 123 in a variable. Sweet, but, consider this:
12345 / 225
If I move along powers of the base, I never run into issues. But for your typical run of the mill calculations, even with integers, you still have to deal with fractional floating points in the arithmetic.
So, I've been using integers and rounding off any calculations to their nearest integer value. Maybe sometimes I'll floor or ceil depending on context, but that's been my current solution, which is a lot more accurate but not 100% accurate. But, good enough-ish.
Soooo....
1) You guys prefer using a library to handle stuff like this? IMO I don't use one for arithmetic because most libraries for this (at least in JavaScript) are clunky and slow and don't really do a better job anyway.
2) You think integers and rounding is also the way to go? Keeps crap simple and all that, despite needing to remember to always round after division calculations or calculations against fractional types.
3) Never do arithmetic? Tell the user to go home.
Jeremy Falcon
modified 20-Mar-24 22:18pm.
|
|
|
|
|
integers with rounding (really a form of fixed decimal) is ok, but with money there may be accounting rules for rounding.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
jmaida wrote: but with money there may be accounting rules for rounding Yeah, fortunately, for this application at least... that's not a concern. I think...
Jeremy Falcon
|
|
|
|
|
Then I agree, integers with rounding is simple and should work for most applications.
Consistency is key. Pick a precision and stick with it.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
I would argue that “complete accuracy on numbers” doesn’t exist. 1/3 cannot be represented exactly. You can do tricks like working with fractions and postponing the actual division until the very end, but in the end, if you have to print the result, you will have to print an approximation.
Mircea
|
|
|
|
|
Fair enough. But the approach of using integers and rounding after the fact... that be your favorite? Does it give you warm fuzzies?
Jeremy Falcon
|
|
|
|
|
No, my favorite would be to work with rational objects (I use c++ most of the time). A library for operations with those can probably be found easily, or I can whip my own without much effort.
Edit: As expected, first Google hit was Rational Number Library - 1.58.0[^]
Mircea
|
|
|
|
|
If I understand you correctly, then you'd be in favor of your own library/class/etc. to wrap this then? For JavaScript, there's no way I'd use most libraries as they're too bloated for this. Rolling one's own would be an option, but the end result would still use approximation inside the rational class right, if there was an expression that involved a floating point?
Keep in mind, I'm not a math major.
Jeremy Falcon
|
|
|
|
|
No approximation until the very end. You keep numerator and denominator integer values and you operate with those as you learned to do it with fractions in high school.
Edit again: a few days ago I had to do something like that in JavaScript but for complex numbers. If you are interested, it’s here: Numerical Examples - Modified Stereographic Conformal Projection[^]
Mircea
|
|
|
|
|
Gotcha
Jeremy Falcon
|
|
|
|
|
I found the good link for the JS code I was talking about before: https://neacsu.net/js/mod_stereo.js[^] Look at the complex class and you can probably model a rational one based on that.
Mircea
|
|
|
|
|
Thanks for the link. My only concern with doing stuff like that, is if I start using arrays to store the fractional parts, this app is gonna slow down. Keep in mind, for this app it'll need to do thousands (potentially) of calculations per second. I may just have to settle for close enough, for this specific app.
Jeremy Falcon
|
|
|
|
|
Thousands of calculations per second still shouldn't take any time. Come back when you're talking billions and we can start to use SIMD or even WebGPU to do some heavy lifting.
Meanwhile you need to ask stakeholders when the rounding may happen. It's pretty standard that individual transactions have tax rounded, for example, and it must stay consistent. There are multiple strategies for rounding, including even or odd rounding, and it shouldn't be chosen at random. Don't forgo correctness because of some desire for speed that's ill-placed.
|
|
|
|
|
If I needed millions, I'd be using C or Rust. But point taken...
Jeremy Falcon
|
|
|
|
|
Good approach. But again be consistent.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
In good old days, we had DOUBLE PRECISION in Fortran and double in C. At least these had better precision than REAL and float .
Somehow, it seems that the designers of later languages put more emphasis on string s, perhaps, because layman-type of users/applications started outnumbering scientific/numerical users/applications.
|
|
|
|
|
Amarnath S wrote: we had DOUBLE PRECISION in Fortran and double in C.
Even with binary DOUBLE PRECISION, you would get errors in accounting formulas. This is why COBOL was specified to have a decimal type.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
Yes sir.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
Sometimes I do wish JavaScript had better types like that. I can push a precision to about 9 or 10 in JavaScript before the storable value becomes too small to be worth while. Good enough for kiddie stuff at least.
But yeah, also what Daniel said.
Jeremy Falcon
|
|
|
|
|
Javascript's innate number type is but an approximation - everybody will agree. But the serialization of those numbers in JSON makes it worse. For example, what is really meant with 0.67, 0.667, ... , 0.66666666666667 ?
Does 0.67 mean exactly 67 cents and is 0.66666666666667 to be understood as an approximation of 2/3? And does 0.667 also stand for 2/3? What does the number of decimals tell about the underlying intentions?
JSON should have a standardized notation for lossless serialization of floating point type numbers. Even C has that: the %a printf format for double in hexadecimal notation. And talking about shortcomings in JSON: please also provide a notation for bignums - both integer and rational ones.
|
|
|
|
|
This is why COBOL has a decimal type.
Your approach of using integers to represent currency will work, subject to a few caveats:
- Accounting rules require that calculations (e.g. multiplication, division) be performed with greater than 1 cent accuracy (5 decimal places, IIRC). This allows interest calculations, currency conversions etc. to work properly.
- Rounding is performed using accounting rules - round to nearest or AWAY. The difference between this and round to nearest or EVEN is when the fraction is exactly 0.5. If this case, one rounds AWAY from 0. For example, 3.145 would round to nearest or EVEN as 3.14, but round to nearest or AWAY as 3.15.
There may be other rules for accounting, but these are the major ones.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|