- 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 miss the point.
The actual code is kind of: DrawRect(Round(X1),Round(Y1),Round(X2),Round(Y2)).
Use: X1 = 11.5, X2 = 20.5 (Rectangle has a width of 8 pixels) X1 = 12.5, X2 = 21.5 (Rectangle has a width of 10 pixels)
There is no way I can "combine" X1 and X2. (Well I principally could take the middle point, round it, take the distance, divide by two. Round it. Then add/subract. But then we just exchange the problem with a different one.
Admin
It is standardized for binary floating-point arithmetic because it has the effect that the last binary bit is zero more often, and because of that further operations more often have no rounding error at all. For example, if you calculate 3 * (x + y) and the "round ties to even" rule is applied in the addition, then the multiplication by 3 will have no rounding error at all. If "round ties to odd" were used, then the multiplication by 3 would give another rounding error.
For rounding to integers, this rounding method is actually unusual.
Admin
I believe you are mistaken. binary 1.1 should be decimal 1.5 (2^0 + 2^-1) binary 1.01 should be decimal 1.25 (2^0 + 2^-2) and so on.
It is very natural for binary to hit a 1/2.
Admin
Admin
Set8087CW or SetRoundMode
http://docwiki.embarcadero.com/CodeExamples/XE2/en/SetRoundMode_%28Delphi%29
Admin
Only looking at the fractional part: The case of .5 is indeed very exact.
But almost any other fraction ending on 5 is not: 0.05, 0.15, 0.35, 0.005, 0.015, 0.025, 0,105, ...
Only the special cases of y*1/(2^x) are exact numbers. The more digits you use, the higher the ratio of inexact numbers.
On the other hand: if it's not an exact number, it will be rounded correctly anyway.
Admin
To be precise:
The number of "exact" values ending with a 5 at a certain digit are: 2^(digits - 1) The number of "values" ending with a 5 at a certain digit are: 10^(digits - 1)
As you can see, the values of inexact digits will grow pretty fast
Admin
Your example is incomplete and therefore misleading. Try taking the rounded value of the sequence 0.0 thru 9.9 (by hundredths) and see what it sums to for each version of rounding. Or, for that matter, generate a few thousand random floats, round them each way, and see which result sums closer to the non-rounded values. Rounding to the nearest even (or odd) will always be better.
Admin
But only 2/3 of the time, and the other time you end up rounding the number into a goat.
Admin
So, we should go back to IBM1620's (a very interesting machine by the way!).
Lacking that, packed decimal on the IBM 360 was intended for Cobol!
Admin
I've always thought that accounting was the perversion of mathematics.
Admin
Real WTF is using decimal form and currency rounding in electronic transactions. Sure I can't physically carry exact 1/3 unit of currency in my wallet but why can't I have 1/3 unit of currency as fractional part of my bank balance, buy some stuff with cost having 1/6 unit of currency as fractional part and pay the resulting credit bill directly from my electronic balance leaving a balance that has 1/6 unit of currency as fractional part?
Round away to world's end with whichever tie breaking method you like when you convert electronic currency to physical form but why not store fractions as fractions without having to convert to decimal form when it is purely electronic?
Admin
+1 This.
Admin
Currency conversion. Sure, you may have one dollar and thirteen cents, but that's not quite exactly 115.81 yen.
Also, if you have 5.5% interest on that $1.13, what happens to the 0.215 of a cent?
Especially since it's purely electronic, math sucks for money.
Admin
Admin
That's the scale of the USD. It's like multiplying a decimal(10,2) by another decimal(10,2), and wondering where part of it went.
Admin
I think the first version was from the book Numerical Recipies in Pascal.
Admin
Admin
Just a minor thing, "const Value: Extended" might favor using an fp register when possible. Also Extended is deprecated in mobile Delphi, Double and Single are ok
Admin
Admin
It's a number representing an idea that predates computers. Money wasn't created with the foresight of how computers would handle them.
Admin
Admin
Calculated JPY amounts are truncated to whole yen. Banks don't settle fractions of Yen.
Admin
Admin
Obviously, you can't do math without strings. What's the WTF?
/sarcasm
Admin
What would you rather it be?
Admin
But you are mistaken.
http://msdn.microsoft.com/en-us/library/364x0z75.aspx
It's a 128-bit floating-point data structure, not an Int32.
Admin
I'm stating a fact, not answering the question.
Admin
Somebody didn't learn how binary floating point works in college. Or slept through it (I don't blame you). In fact, half is one of the easiest values to represent in binary floating point with any accuracy.
It's been a while so bear with me here... 1 sign bit, 8 exponent bits, 23 mantissa bits... let's see...
0 (not negative) 10000000 (127 minus this value is the exponent, so -1) 00000000000000000000000 (1.this binary decimal, so 1.0)
1.0e-1 = 0.5.
Done. 0x70000000 is a 32-bit IEEE floating point value for half.
Admin
Looks like well rounded code!
Admin
Why should there be an ultimate granularity? Why not work with the assumption that money is a continuous quantity like length?
Admin
Um....
Sign has been in Delphi for MUCH longer than that. You do have to add "Math" to the uses clause...
Admin
I don't want to pay cash for gas for $3.79394857π/gallon.
Admin
Delphi still doesn't have a ternary operator, the various IfThen() overloaded functions are not the same thing. Try using somthing like
and wait for it to blow up, there is no short circuit evaluationAdmin
Packed decimal on the IBM 360 was intended for PL/I. IBM grudgingly supported Cobol because they had to. Meanwhile it was fixed point only. Even in PL/I, float decimal wasn't float decimal.
Admin
Thomas Jefferson lost the fight to put the US on the metric system. But the US was the second country to make its currency decimal. Before that, 1/3 of a dollar was a perfectly valid denomination too.
Admin
Most banks use continuously compounded interest, e.g. A = Pe^(rt), where r is the rate, t is the time, P is the principal. As A is always an irrational number, it's rather hard to store it precisely.
Admin
Getting to the bottom and finding a great solution made me involuntarily high-five my computer screen. Wonderful. Thank you for bringing joy to my evening. We're not all winners, but the occasional search of stackoverflow will result in a result like this and we'd all be better for it.
Please pardon my response for any and all fixes that have happened in the comments section, I will read them if I run into this kind of Delphi issue in the future.
Admin
FYI: GNU glibc (used by default in every Linux box) is using this bankers' rounding in printf() and friends. This is especially annoying as printf() should be used only for the final visual display output, so the error accumulation which the bankers' rounding ought to avoid just cannot happen.
Admin
Very simple: Money calculations, statistics etc: It's important that the average of the rounded values resembles the average of the original value --> Use of bankers rounding is the way to go.
Graphic calculations: It's important that we have consistent rounding (e.g. difference between two rounded values should resemble the difference between the original values) --> Use of bankers rounding is plain wrong.
The main problem is, that .5 is very common if you do integer graphic output (middle point between two values is either .0 or .5)
Admin
Let's see if I've got this right.
You're saying the number 1/2 can't be exactly represented in binary?
Admin
Exactly... And you don't have to, because, thankfully, currency IS NOT a continuous quantity. It is very discrete in nature. Try splitting that coin or tearing that note at the cash register and paying with it.
Admin
I don't understand why the author is being so high and might about mathematical rounding, given that mathematicians agree that if you have to round at all, you should usually round to even.
Admin
I want the bank to pay my 1.0% interest on EVERY SINGLE DIGIT (!) of my account!
Question: How much RAM is needed to perform the calculation?
How much time will it take?
And how much paper is needed to printout the result?
There has to be a limit of the number of digits stored, unless you accept that the answer to those three questions is infinity!
Admin
Admin
It's like that by definition. Anyone who wants to redefine currency should feel free to do so - but good luck getting the rest of the world to go along with you for it ;)
Admin
printf() -> Wodden table -> scan -> OCR -> sum, so easy.
Admin
Admin
Admin
TRWTF is twos complement arithmetic ;-P