- 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
The author was very wise to make the code robust, because everybody knows that just by sampling a character in a string the string itself might suddenly change in lenght (this is also known the Heisenberg Uncertainty Principle amongst Quantum Physicists).
Hence the: (int)_tcslen(tmpStr)
The (int) cast is probably there just in case _tcslen() returns a floating-point number. It remains unclear though why the author has not applied the proper rounding scheme there also.
Admin
Why do you even give them the option? For anything involving VAT, National Insurance or taxes in the UK, HM Revenue & Customs (which is the correct name now - Inland Revenue and HM Customs & Excise merged) has very specific rules about what types of rounding are allowed, and tends to get rather upset if their auditors find you've deviated from the required rounding rules in any way that leads to underpayment (particularly of VAT).
For NI, for instance, amounts (both the tax amounts and rebates etc.) should generally be rounded up to the nearest whole pound - or at least that's what the last edition of their software developers manual specified last time I checked. For tax/NI it isn't too serious to get it wrong, as the worst thing that happens is that it gets adjusted once the employee hands in their self assessment.
For VAT, though, there are potential criminal liabilities for the company directors, so it's worthwhile being very careful. The rounding rules that apply are set out in "The Vat Guide", section 17.5 (HMRC Notice 700, available from http://customs.hmrc.gov.uk/channelsPortalWebApp/channelsPortalWebApp.portal?_nfpb=true&_pageLabel=pageExcise_ShowContent&columns=1&id=LIB_PN_VAT ). In general the following applies for VAT invoices, for instance:
- You EITHER round VAT down to the nearest penny on the entire VAT liable amount on a per invoice basis,
- OR _down_ to the nearest 0.1p per line item on the invoice
- OR to the nearest 1p or 0.5p per line item on the invoice
(Whichever method you choose, you must apply it consistently - you can't use one method for some invoices and another for others unless you particularly want to spend time explaining to an auditor why they should believe you aren't trying to manipulate your way to lower VAT payments)
Vidar
Admin
Let us endeavour to unite Univeral String theory with Programming String theory.
Admin
I wonder what he'd have done if he needed to work to a variable number of decimal points - or worse - significant figures!
Here's a C# example of a round function that I came up with when I was bored... using Math.Pow and Math.Log10, but not Math.Round.
<FONT color=#0000ff size=2>public </FONT><FONT color=#a52a2a size=2>static </FONT><FONT color=#ff0000 size=2>double </FONT><FONT color=#191970 size=2>Round</FONT><FONT color=#006400 size=2>(</FONT><FONT color=#ff0000 size=2>double </FONT><FONT size=2>number</FONT><FONT color=#006400 size=2>, </FONT><FONT color=#ff0000 size=2>int </FONT><FONT size=2>sigFig</FONT><FONT color=#006400 size=2>)
{
</FONT><FONT color=#ff0000 size=2>int </FONT><FONT size=2>decPlaces </FONT><FONT color=#006400 size=2>= </FONT><FONT size=2>sigFig </FONT><FONT color=#006400 size=2>- (</FONT><FONT color=#ff0000 size=2>int</FONT><FONT color=#006400 size=2>)(</FONT><FONT size=2>Math</FONT><FONT color=#006400 size=2>.</FONT><FONT color=#191970 size=2>Log10</FONT><FONT color=#006400 size=2>(</FONT><FONT size=2>Math</FONT><FONT color=#006400 size=2>.</FONT><FONT color=#191970 size=2>Abs</FONT><FONT color=#006400 size=2>(</FONT><FONT size=2>number</FONT><FONT color=#006400 size=2>)));
</FONT><FONT color=#ff0000 size=2>double </FONT><FONT size=2>result </FONT><FONT color=#006400 size=2>= </FONT><FONT size=2>number </FONT><FONT color=#006400 size=2>* (</FONT><FONT size=2>Math</FONT><FONT color=#006400 size=2>.</FONT><FONT color=#191970 size=2>Pow</FONT><FONT color=#006400 size=2>(</FONT><FONT color=#00008b size=2>10</FONT><FONT color=#006400 size=2>, </FONT><FONT size=2>decPlaces</FONT><FONT color=#006400 size=2>));
</FONT><FONT size=2>result </FONT><FONT color=#006400 size=2>= (</FONT><FONT color=#ff0000 size=2>int</FONT><FONT color=#006400 size=2>)(</FONT><FONT size=2>result</FONT><FONT color=#006400 size=2>+</FONT><FONT color=#00008b size=2>0.5</FONT><FONT color=#006400 size=2>);
</FONT><FONT size=2>result </FONT><FONT color=#006400 size=2>= </FONT><FONT size=2>result </FONT><FONT color=#006400 size=2>/ (</FONT><FONT size=2>Math</FONT><FONT color=#006400 size=2>.</FONT><FONT color=#191970 size=2>Pow</FONT><FONT color=#006400 size=2>(</FONT><FONT color=#00008b size=2>10</FONT><FONT color=#006400 size=2>, </FONT><FONT size=2>decPlaces</FONT><FONT color=#006400 size=2>));
</FONT><FONT color=#000080 size=2>return </FONT><FONT size=2>result</FONT><FONT color=#006400 size=2>;
}
</FONT><FONT color=#006400 size=2><FONT color=#000000>And yes, I didn't compress it all onto one line, :) - That was reserved for the VB6 version...</FONT>
</FONT></FONT>Admin
Even if the core of these functions is fundamentally wrong, clear comments on why the developer did what he/she did would go a long way to reduce the WTF-edness of this one.
----
Do these functions blow up into funny shapes? Nope, not unless round is funny.
Admin
Round... RoundCorrect.... So the WTF is that he called the third function RoundCorrect2, rather than RoundCorrectReally.
Coming soon: RoundCorrectNoTrustMeTHISOneWillWork.
--Rank
Admin
Looks like someone is trying to program too hard!
Admin
Actually numbers make more sense - you can see which version is the latter. Otherwise you would have to comment them somehow in order to know which is better - RoundCorrectIfThisWontWorkThenIGiveUp or RoundCorrectAhIFinallyGotWhatWasWrong or even RoundCorrectFrankSaysThisIsOK
Admin
Can't correct a mistake with another mistake... and another mistake... and another mistake...
Admin
No they don't. If version 1 of a function does not work the way its name implies, it should be rewritten - not left in.
Your suggestion that there is some correctness in appending version numbers to every subsequent correction to the rounding function is akin to the people who make backups of source by creating zip files with the date in the file name instead of using source control software.
Admin
That's an excellent point. On the other hand, the spec clearly must call for different kinds of correctness for different parts of the code. Why else would he write new functions rather than rewriting Round? Given that, I want my function name to qualitatively describe the correctiptude. Which function number was the one Frank said would work again?
Hmm... of course the way to have it both ways is to have a global array of function pointers. Just choose your desired correcticacity.
<FONT face="Courier New" size=2>int roundval = round[correcticacity](initialvalue);</FONT>
--Rank
Admin
Given the number of attempts at getting this right, shouldsn't the title of this WTF be, "Rounding Third"?
Admin
And the award for "joke post taken too seriously" goes to... Richard Nixon!
Admin
Don't do it in K&R C either. False is zero, True is any other number.
Admin
Sorry, forgot quote
return (int)(number + (number > 0) - 0.5);
Don't do this in VB. True is not what you think it is :)
Don't do it in K&R C either.
Admin
PerlFAQ is more fundamental than a cookbooks, isn't it? So, look it (perlfaq4):
*********
Rounding in financial applications can have serious implications, and the rounding method used should be specified precisely. In these cases, it probably pays not to trust whichever system rounding is being used by Perl, but to instead implement the rounding function you need yourself.
*********
Admin
I don't believe it was a joke.
Admin
Saying TRUE is any non-zero number is like saying a rectangle is any square.
Admin
I suspect you were being sarcastic but I know someone who really and truly did that.
Admin
There are two related but different concepts here.
1. In a Boolean context, all non-zero values evaluate to true, and 0 evaluates to false.
2. The result of any relational or equality expression (<, <=, >, >=, ==, and !=) will always be either 0 or 1, and will always be of type int.
The above expression has any number of problems (again, what if number >= INT_MAX), but the expression (number > 0) will always evaluate to either 0 or 1 depending on the value of number.
Admin
Underrated movie, actually.
Admin
Perl is a WTF in itself. I've never seen a line of Perl that wouldn't qualify for this site.
Admin
Uh, that confirms what I said doesn't it? :-/
Admin
Just in case you're curious, the first function does this:
1. Convert float to string with just 1 decimal place.
2. Convert string to int (basically a floor())
3. Scan string for the first non-digit character. Presumably the decimal separator
4. Convert everything the decimal to an integer
5. If the second integer is less than 4, return the first integer.
6. Otherwise, return the original value.
Which brings up at least two WTF's in one function:
- It fails to round 1.4 -> 1, though it will round 1.3 -> 1
- If the original value should have been rounded up, it doesn't round AT ALL.
Round(1.3) -> 1
Round(1.4) -> 1.4
Round(1.6) -> 1.6
Admin
Because "that's what matches Sage". Apparently Sage knows all, so if our program agrees with it then everything's OK, it seems.
Yeah, it all seems a bit dubious, but I take the line that our software's just a tool to produce the numbers they want (though I've just realised that's a tad too close to "I was following orders"...)
Admin
Ah, well... It's their accountants, company secretary or directors that risk going to jail if they underreport their VAT liabilities, not you, at least as long as it's obvious they knew how the numbers were calculated. Would have to be a pretty serious case for things to go that far though, but if I was you I'd make sure to document who signs off on those decisions :)
Vidar
Admin
[U][U][U][U][U]
Admin
I can forgive the use of strings, but... ugh, patchwork programming. I see it all the time in interviews. I give someone a programming problem. He writes some code. I point out a failure case. He tacks on an if statement to handle it. I point out another case, etc. No matter how worthless the original code proves to be, a patchwork programmer always thinks about what he can tack on to pass the tests, never how to make the code work.
Patchwork programmers are fundamentally broken and should not be hired to program, although they may improve in time. They're completely unaware of any connection between the code they write and what it does.
The worst part is that certain promoters of extreme programming (Robert Martin) are encouraging and teaching such crap.