 Feature Articles
 CodeSOD
 Error'd
 Forums

Other Articles
 Random Article
 Other Series
 Alex's Soapbox
 Announcements
 Best of…
 Best of Email
 Best of the Sidebar
 Bring Your Own Code
 Coded Smorgasbord
 Mandatory Fun Day
 Off Topic
 Representative Line
 News Roundup
 Editor's Soapbox
 Software on the Rocks
 Souvenir Potpourri
 Sponsor Post
 Tales from the Interview
 The Daily WTF: Live
 Virtudyne
Admin
You meant "binary floatingpoint" (at least I hope say), but you used "float". The type float generally has only 24 bit precision, and a rather limited range, while the type double has 53 bits of precision (more than 8 decimal digits more) and a much wider ange of values, so using float instead of double is asking for trouble. And without any need.
Admin
There is a big mistake made here. And that mistake is to only show examples where for some reason decimal numbers give the desired result, where binary floating point doesn't. But take $100 and divide by 3, then take the result and multiply by 3. Decimal won't give you the desired result either.
What everyone is missing is that financial calculations are usually governed by rules. There will be rules in place that specify whether a result that would mathematically (with infinite precision) be 14.375 should end up as 14.37 or 14.38 or either. These rules have to be written down and followed.
Maybe the rule is "the calculation should be done as if with infinite precision, and then rounded to two decimal digits, rounding to an even last digit for values precisely between two possible values (in other words: 14.38). That's easily achieved in double precision; you figure out from the input values that the exact result would be a number with say 7 decimal places followed by zeroes. That means if your calculated result is 14.374,999,981 then the true result must be 14.375,000,0 and gets rounded accordingly. A little bit of maths, but you write a function for it once.
If the rules are different (for example, if you buy n items for x pound each, then n times x is calculated, rounded to two decimal digits, then multiplied by 0.2 and again rounded to 2 decimal digits for VAT, then that's what you implement.
Whether you use double or decimal internally will affect your code that you use to implement the rules, but must never influence the outcome.
Admin
As one of my instructors used to put it, "Engineers are superior to accountants because they are allowed to add, multiply, divide and subtract. Accountants are only allowed to add and subtract, if they divide or multiply they get sent to prison."
Admin
:shooting_self_in_head:
Admin
There most definitely is a need.
The vast majority of scientific/technical computing is done with singleprecision, which is what you would use if we're talking about a stock price model. Saturation is what ruins your calculations because it hits it with a huge nonlinearity. Single precision is good for 1 in 100,000 to 1 in a billion, and shows up as minor, distributed noise component.
Take the latest nVidia GPUs, double is 3 times slower. Of course, double takes up twice the RAM, cache, bandwidth etc.
Admin
How do we know this (silly) code is modeling currency? Could it not be modeling the second stage LOX tank pressure in a rocket?
Admin
Nope, can't do it with double precision. What's 64.01 * 100000000000002, to the nearest integer? You can't get the correct answer of 6401000000000128 with only 53 bits of mantissa (you'd instead get 6401000000000128.53... and incorrectly round up to 6401000000000129).
Just use a decimal or integer type. End of story.
Admin
He should have used a libary.
Admin
Perhaps mentioning multicurrency was a "bridge too far", it was only included to illustrate the complexity of the issue that the Dev had. The real point was that the Dev had to find another method of accurately calculating the VAT, that could be (and anecdotal evidence seems to suggest that it would be considered :wtf: Code.
As I stated, and as has been independently pointed out, there are times when you have to bite the bullet and just do it.
That aside, and I really am pissing myself with laugher here, currency conversion was not done adhoc because any minor inaccuracies due to rounding errors paled into insignificance. because of fluctuations in exchange rate. The prices were uploaded once every 24 hours from the Accounts Package and the decision was made and go with the "get out of jail free" card of a caveat and leave it at that
Admin
This.
And This.
To state the obvious (as I'm in a pe<bold>n</bold>dantic mood today), the WTF is float to double conversion "via a string". Whether the WTF is because of the dev or the language, or some $deityawful laws that need to be complied with, I get a
FILE_NOT_FOUND
error.
Filed under: Probably some stupid law causing this. When in doubt, blame the government.
Admin
This may be irrelevant, but I was talking to a bank programmer the other day and he remarked that they still have to handle an awful lot of data in csv format, because they get sent exported data which may have huge numbers of tuples and any other format takes up more space. To quote Marvin, it sounds truly awful.
Reading csv files from various sources is a PITA  everybody has their own notion of how they need to work  and sooner or later you are going to have to work around some wtf which involves string to number conversion. I don't suppose this is the case here, but in the past I have had to have custom string to number and number to string formatters to import from, process and export to csv files.
Admin
If you are getting numbers like that in your accounting system, either something is very wrong or the Greek government would like a contribution from your petty cash drawer to pay back their debt and rebuild their economy.
Unless we get hyperinflation any time soon, any example using numbers > 10^{12} is just looking for an argument.
Admin
US national debt > 1.8 * 10^{13}
Admin
If your accounting system (the context I was referring to) is regularly handling the US national debt as a number on which it does multiplicative arithmetic, I'm glad I don't work for your company. Even Apple has a turnover < $10^{12}, though I guess if the bubble doesn't burst that might get exceeded one day. But that's going to be the biggest number in the annual statement, and nobody is going to worry about the rounding error in the last place.
Admin
My example was clearly artificial, and I agree that numbers that large aren't going to show up in any real accounting situation for the next few decades. But using "53 bits of precision should be enough for any data this software will ever process" as an excuse to write buggy software is still wrong, especially when the correct alternative is clear and usable. Every language you might possibly write new code in this days has a reasonable Decimal/BigDecimal implementation in it.
"640k should be enough for everyone", right?
Admin
Not disputing the WTF'ery. Just the target selection for the dope slap needs to be investigated.
Admin
Am I missing something here? Assuming Java's Float.toString method will return the entire float and not perform any rounding or truncation, and assuming that Double.parseDouble correctly converts whatever format Float.toString returns back into an equivalent double, wouldn't this code be entirely unnecessary?
Basically: wouldn't typecasting from float to double accomplish the exact same thing? Or is the author taking advantage of some notveryclear behavior of Float.toString that may perhaps lose precision in the process of going from float to String?
Admin
Yes, perfectly true. My point was simply that in reality and for accounting applications, 64 bit precision isn't the problem (which may be why they continue to do it.) The problem is how the underlying code handles numbers around 0.5 and 0.005, and is due to our completely artificial concept of rounding  which has just led to the English Appeal Court deciding that "1%" includes 0.5...........1%, insert as many zeroes as you like. I hope that goes to the Supreme Court and a few statisticians are allowed to testify.
Admin
Ummmm, all you say is true, but: a) Nothing to do with the article, and b) Anybody reading TDWTF will already know about representing money. Your 'wisdom' is mostly just TLDR.
Fact: A double precision float can exactly represent any number that can be represented by a single precision float. ANY number.
Nothing done by this function solves any problem. The return value is a binary fraction so it doesn't matter how you round it inside the function it can never return a 'more accurate' value. It can only return a wrong value.
Binary fractions simply can't exactly represent decimal fractions, decimal fractions can't represent numbers like one third. It's simple math and shouldn't surprise anybody (or need any prolonged explanation).
Admin
Or maybe you started reading the comments on the main page: [image] I was confused too until I read the full comment here...
Admin
Interesting Bug, or is it a Discourse design feature to encourage discourse?
Admin
Because of this, you are all pardoned for your transgressions. So I won't be making the Post I had planned to :)
Admin
Zimbabwe got to the point where the ATM's couldn't dispense a bill big enough to buy anything. They at one point issued Z$100,000,000,000,000 notes.
They redenominated again, and then.... just gave up. The Z$ won't be legal tender after this year.
Admin
I had to fix a bug in our code that produced one in one part and the other in another part. From memory it was a combination of discounts and tax that produced an "exact" $x.xx5 but different code handled this case differently so it was a cent out between the product page and checking out. A simple
sprintf("%.2f")
was not enough. It was worse because this item was generally bought in bulk so an order was often dollars incorrect. Changing it so the everywhere calls the same rounding function was the fix.Admin
People keep putting up these examples...somehow I doubt anybody is going to design an accounting system purely to deal with R. Mugabe's
fascist dictatorshipunusual state arrangements. Certainly not if they're going to be paid in his currency.Admin
I think they are on the ear standard atm. You know 1 ear = head, 1 head = 1 less body. 2 ears nullifies the current transaction because it is a blatant and fraudulent attempt to double your income.