- 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
Other than what looks like static buffer usage (bad, but might be called for in some embedded scenarios?) and unnecessarily short variable names, I'll join the chorus of "not a WTF" here.
It looks reasonably fast, could (admittedly) be more readable, and is a tiny tool for a tiny job. If you need some general number formatting, it is not the right tool. It should work for what it strikes out to be, and that is the goal for a tiny tool.
Admin
I agree; as soon as I saw the "d = 3" and checked back to see that it returned a char*, I instantly thought it was a number prettifier. The ',' character down below just confirmed it for me. Total time to figure out what it did: about 5 seconds.
Admin
I read straight through it, understood it, didn't see any problem.
Where's the WTF?
Admin
Or, maybe, out of your league?
Admin
I might have a quarrel with the rather horrible LOC-driving formatting, the global storage it uses for a buffer, the undocumented constant 20 (which is actually a bit short, think log10(2^63)+2 for sign and terminator) and the failure to put the comma under a define or (my preference) an enum. Also a minor nit that there are at least two other characters (dot and apostrophe) used for the same function, elsewhere. But not with the method.
The
backwards'' approach to make happen what this does is pretty much the natural one. To see why, try and come up with an elegant
forwards'' method. In fact, I have a function that does variable base number-to-ascii (but without comma support) in the same way and it doesn't even add a terminating NUL. Why? The subsequent write function takes a length argument, and why not? The information is available already. Might as well use it.Admin
And right after I post it, I realise I forgot another: the 20 isn't just short, as commata take space too. whoops. Buffer overflow!
Admin
They sure are in Swedish. Thanks for pointing out my typo.
Admin
Oh, c'mon guys!
In the C99 spec you find:
strlen("-2,147,483,647") < 20Yes, this can be overridden by the implementation, but in many environments (especially embedded systems) the compiler implementation is fixed and well understood by those writing the code.
Admin
The WTF is, they could have just done this:
/* must call setlocale(LC_NUMERIC, "") before calling. */ static char *nice_num(long n) { sprintf(prtbuf, "%'ld", n); return prtbuf; }
(Meaning, the whole function is unnecessary; it's better to avoid using a static like prtbuf for this anyway)
Admin
I don't see any major problems with the code. Modulus math is the only way to do this, short of subtracting powers of ten. You can't do it three digits at a time without ending up with "1, 74" and the like. It's a bit flaky returning a pointer into a static, but not terribly bad.
I usually do this with a sprintf %d, then add the commas.
Admin
ever tried printf("%03d", 42); // prints "042"
printf can do about 80--99% of what you want and could reasonably expect it to do. If you know the magic codes.
My favorite trick is
it beats
and the code sample here is not a WTF. Is the source of WTFs drying up? Has TDWTF made an impact?
Admin
How the hell is a function called "nice_num" not a WTF?!
Admin
Admin
You can't on the one hand claim standards conformance and on the other hand say that everybody does something else anyway. Especially claiming common sense on TDWTF is a bit capricious.
The problem is that "20" is not an adequate way to document the assumptions behind that particular use. Code does get ported, so documenting platform assumptions isn't a bad thing. Not doing that arguably is.
Admin
I was thinking the same thing. Fortunately, I was able to rewrite the beast in a language that has no variables in the first place – Haskell!
Now testing the new function is as simple as
Admin
Like someone else said, the only complaint I can think of is the divide ops ..maybe the WTF is the WTF. A meta-WTF!
Admin
I found this snippet on the Web:
http://www.eskimo.com/~scs/c-faq.com/stdio/commaprint.html
Hmm, what a surprise. It uses the exact same technique, only it happens to have a bigger buffer and support for system locale.
Multiple calls will overwrite the buffer, but that's what strdup is for.
Admin
Admin
Knowledge is not the same thing as intelligence, people...
Admin
for puzzlig mix-ups, you might add:
"their" / "there" / "they're" "its" / "it's"
It's baffling me every time - judging from various online forums, chats etc. native speakers are more likely to make these mistakes.
It might be that you have to learn spelling from the ground up when learning a new language (after all you continuously have to use a dictionary even for simple words in the beginning).
Perhaps if you learn a language mainly by listening (which is the case for one's mother tongue) you tend to mix up homophones (i.e. words that sound alike) if you never get formal training and/or do not read a lot, as reading a word repeatedly helps in "anchoring" the pattern of how that word is spelled correctly.
Admin
Nicely written function. It's actually nice to see such a nice code written in pure C.
Admin
They are in Swedish? I see...
In Germany, Austria and Switzerland there was a reform of the official orthographic rules some years ago. Apart from some quite sensible stuff, the transcription of greek words was also "simplified", which is in part really stupid: "th" signifies a different letter (gr. "theta") than "t" (gr."tau"), after all, the same goes for "y" (gr. "ypsilon") and "i" (gr. "iota").
These "simplifications" therefore tend to destroy information and moreover make some classic words butt-ugly ;o) (the latter being a point of personal taste, of course... "symphonie" vs. "sinfonie" is an example)
Admin
There's no problem with the code; that's the kind of thing you expect to see in buffer-management code. I think the WTF is in the mind of the proposer: that all code should use APIs and libraries (to the extend that the proposer never actually saw such ordinary code before). It is a programmer's responsibility to know the algorithmic path of every byte in and out of memory; just relying on higher-level functions and leaving the gory details to the black box doesn't sound like the work of a senior to me.
Admin
Depending on the situation, this is may not be surprising. I have encountered situations where programmers have been forced to write such code. It could be during crunch time where they don't have the time to lookup the APIs, or the original programmer has left, leaving us with no option but to "temporarily" employ someone who we know is not qualified (in one instance, my manager), or we realize that the library that provides such functionality is not available/is too slow/consumes too much memory on the arcane target platform.
Heck! I remember code that was originally written for Windows 3.1 where we had to code some seemingly basic functions that were available in Unix (and eventually in Windows XP onwards). We have not had the time to rewrite the 15+ year old code until now (for Vista). It's more like we really did not bother to do so as the original coder understood portability issues and coded it in such a way that it could be recompiled verbatim on any OS.
I am sure that all of us will have a nice laugh at the old code, if I put it up, but we probably saved half a million dollars over all these years by not having to maintain it. I always encourage people to rewrite old code, if they are capable of coding and testing it properly.
Admin
Zomg, you're like the python of currency
Admin
Admin
Best response to my incorrect statement, not sure what the equivalent is for this site but want a cookie?
Its my bad for being a student and using non what ever the latest version of C is C compilers for embedded systems. hates having to keep things on the same line when it would be much easier to understand if they were on multiple
If this was for an embedded system sprintf might not be an option, its less so an issue now but if you are using old hardware then the standard libraries can take up a fair chunk of your rather limited resources.
Admin
You just wait 15 years. Then it's gonna be something like
And nobody will understand C code either.
Admin
A flame war about number formatting and whose code has hairier balls. It's nice to see such passion still exists. :)
Admin
Admin
Seems perfectly OK to me except that it needs some comments. I have seen much more cryptic codes than this.
Admin
Surely this submission has to have come from TopCod3r.... havn't seen an article starting a thread like this in a while - and no real mentions of TRWTF
Admin
The sentence ML wrote becomes: "Jag har många CPUer! Faktiskt har jag 96 st 386-CPUer!"
Admin
Back when I was young we'd convert longs to prettified char strings by toggling binary switches.
That's noting. All we had was a soldering iron and a bunch of magnetic relays.
Relays, eh?? Luxury. We had a ball of string, a twig and some pine cones.
Bah! You were lucky to have a twig! All we had was a pebble and a handful of river water.
Etc.
:)
Admin
I think the worst case for a long would require a 15 character buffer.
Admin
Nice catch! Reminds me of the checked integer arithmetic functions I wrote not too long ago (in C++). The division function can throw std::overflow_error on two's complement architectures. :-)
Admin
So it's not a WTF - get over it...Ignore it...wait for another one - tomorrow. (Or better still, F-off somewhere else if TDWTF annoys you so much that uyou feel you have to complain that it's not what is used to be)
FFS the one thing that Sh!ts me most on this site is the idiots that feel the need to post (often it's quite obvious they haven;t read ANY of the other posts) with "That's not a real WTF..." etc, etc, etc....
And, of course, the obligatory "Why a child of four could understand that code". Granted. But once the 15th person starts posting that, it seems more of a "I'm smart, I get it too" rather than a genuine observation...
I can't help (after reading most comments about that particular days article on TDWTF almost daily) that the IT industry is full of F-wits who all think they have to prove how smart they actually are (which to me implies that they aren't that smart at all and realise it - they are trying to prove they are smart to themselves as well as to the world {or what little of the world reads TDWTF comments, at least}).
If you don't like the article IGNORE it...we all make mistakes (some more often than others), and perhaps Alex (oops, Jake) was half asleep when he skimmed over this one and put it up...Deal with it....
[/rant]
Quite appropriately, captcha = genitus which (no not really, before you look it up) means 'Smart Dick'
Admin
This code provoked a "WTF" reaction from me, but only because I'm not a C programmer. Anyone (like me) whose primary environment is weakly-typed languages where converting numbers to strings is a simple matter of sticking '""+' in front, might take a while to understand what was going on. I'm quite pleased that I managed to figure it out - but then I use goofy modulus math on a regular basis (for example to set different properties on alternating rows in a table ;) )
For me it was a "WTF" - but not the kind of WTF that this site is about.
Admin
You guys are hilarious. Someone makes a post saying 'it takes some time to understand this code' so of course you all set out to prove how smart you all are by showing how quickly you understood it.
Why anyone would implement something like this (or congratulate the original coder on his cleverness and obviousness) and not use strfmon() (found with <30 seconds of googling) boggles the mind.
My only conclusion is that the great majority of you have your head so far up your own arses that you wouldn't see a bad idea if it came up and segfaulted on you.
Admin
Another whos's clearly read the comments before posting....
My little microcontroller has great need for all those monetary functions...lets use that library....Oh bugger - now I haven't room for anything USEFUL...Oh well, it solved he problem at hand....
Admin
In fact, better still, given that someone will point out there's probably little use for formatted numbers on a microcontroller, lets try adding that library onto my mobile phone....
Admin
whats wrong with you guys? there has to be a WTF here!
no calls to poorly implemented standard libraries? FAIL
not linking in 50kB of code to perform a simple task? FAIL
writing novel, simple AND fast code? FAIL
in all seriousness, anyone who thinks his implementation is a WTF, you are the cause of ugly, clunky software, please raise your hand so i may make note and ensure i never hire or work with you.
x
Admin
Admin
Here's my version:
Improvements:
Admin
Admin
You make a good point, but I think a lot of the vehemence is triggered by the stupid/ignorant claiming that if they can't understand it, it must be bad. That is stupid. :) Of course there are some people that hang around just to remind us how much faster they understand everything than everyone else.
Admin
So not a wtf. Taken out of context, there are some minor wtfs that were already mentioned (buffer overflow for 64-bit long, thread-unsafety), but it's entirely possible that the surrounding code makes validates them. Locking may exist on a higher level, as well as checks for numeric range. The thousands separator format for printf comes from SUSv2, not the C standard, so it's very unlikely that Microsoft's implementation includes it. Filling the buffer from the right is standard practice too, since extracting the digits with modulus starts from the least significant digit.
I've spent the last few days rewriting all of printf's formatting (with a few custom conversions) in C++, since I'm not happy with the way iostreams work in some aspects. My int_to_str function is very similar to the one in this article, although more feature-rich.
Admin
Plus it doesn't look unfamiliar for any compiler-writer, including me, who has implemented only a basic c-compiler in c (for kicks).
Admin
given that nobody (afaik) properly supports japanese number formatting (group every four digits), let alone the seriously wacky indian formatting (grouped by twos, except for the lowest order digits, which are a group of three) this is a fine start on an i18n number formatter--just make d an argument to support japan, and add another argument separating first and loop initializations of d to support india.
Admin
p.s. jspenguin's implementation FTW!