- 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
unbelievable.
Admin
I wonder if this, by chance, was compiled to ProgramThatComputesFractionsAndDistanceConversions.exe...
Admin
I really do not see this as that bad. It's obviously C. The conversion functions are labled inline. If someone needed a full and fast basic unit conversion library, this would do it. The const variable names sucks, but awell. Is it just me? Am I missing something?
Admin
Maybe it's just some passive-aggressive bastid who got yelled at one too many times for hardcoding. Maybe.
Admin
This was done to make the code more readable and easier to understand.
These are pretty funny though.It almost looks like the code was written by 12 year old that was practicing his leetspeak.
Admin
yeah i agree... its not great, but at least if all these functions were being used throughout the product there is one central function that exists to make things consistant. its better than hard coding the value of PI directly in the code, and differently for each use. right?
Admin
Yah
Admin
This could be to save memory. If you just type out a floating point constant everywhere, a copy of it gets stored separately in every compiled file. If you make it a named variable, it's only stored once. Not a big deal on a real computer but it could make a difference on embedded systems.
Admin
Yea, better make 1/3 a const in case it gets hardcoded differently each time...
const double OneThird = 1.0/3.0;
;)
Admin
my brain asploded
Admin
I don't see anything unreasonable with this code. It is generally much faster to multiply by the reciprocal of a constant than to divide by it.
Though I would say that this individual's naming convention is interesting...
Admin
i just read the old thread. This WTF is really not that great. The gist is that the constants are named as the number in them, rather than something like INCH_2_FEET_RATIO which makes things more useful than ONE_TWELTH.
Some people claimed that this slows down the perf of the program, e.g. "why define a constant if it is only used once", or "does he think that the division is done during compile". Obiviously a well named constant is still ok if it is used once, and also the division isn't done during runtime or it wouldn't be a very good constant would it?
Admin
yeah these suck. but obviously you want to have one verision of PI, not 3.14159265358979323846264 one time and just 3.14 another time
const <FONT size=+0>double</FONT> OneThird = 1.0/3.0;
<FONT size=+0>const</FONT> <FONT size=+0>double</FONT> One3point6th = 1.0/3.6;
<FONT size=+0>const</FONT> <FONT size=+0>double</FONT> OneTwelfth = 1.0/12.0;
<FONT size=+0>const</FONT> <FONT size=+0>double</FONT> OneThirtysixth = 1.0/36.0;
<FONT size=+0>const</FONT> <FONT size=+0>double</FONT> One1760th = 1.0/1760;
<FONT size=+0>const</FONT> <FONT size=+0>double</FONT> One5280th = 1.0/5280;
<FONT size=+0>const</FONT> <FONT size=+0>double</FONT> One63360th = 1.0/63360.0;
Admin
Some of these are bad, some of these are good. Do you really need to make another way to type pi/2? Probably not Do you really need a way to perform unit convertions without going to Google each time? Sure, that sounds useful. Does a programmer usually know what
Admin
The only reason I can see for some of these are cycle times. I had created several simulations and instead of calculating Cos(x) every time I wanted to move something on the screen, I created a 360 element array of numbers, converting radians and such to save processor cycles. It ate up a little more memory, but ran 100 times faster. Maybe this is that method taken to the extreme?
Pi/2 ... maybe this calculation takes place many thousands of times in a loop and he/she wanted to streamline the process. Why make the processor figure this out every time?
We don't really know the rest of the program to make any assumptions.
Admin
The point is, for those of you who think this is perfectly OK, that p is fine to define as a constant - but why define non-transcendental numbers (or multiplies of transcendental numbers, such as 2p) as constants and then in the conversion function use these constants? Besides, if a constant is named after its value, the programmer might as well write out the number. That is why this is a `WTF'.
I wonder why that person did not define constants named OneThousandth for the conversion between metres and kilometres, Ten for the conversion between metres and centimetres and so on - as well as why he did not use his beautifully-named and -defined constants for the conversion between inches and millimetres, for example.
Admin
It's not a big deal as long as it isn't your job to support code with names like One2Pt20462262185th.
-Mark
Admin
I'm not sure I see this as necessarily evil code. Yeah the names are long, at least they are descriptive.
You guys seem to be caught up on this being for readability. Seems to me the person wanted faster conversion functions. Yes each const is only used once in code, but the conversion could be called many times per calculation. They even inlined the methods.
I'm guessing precision was an issue, otherwise just using the commented numbers might suffice instead of doing all those intermediate calcualtions.
Admin
I can't believe people are defending this crap. Does anyone honestly believe that
const double One2Pt20462262185th = 1.0/2.20462262185;
is more readable and maintanable than
const double PoundsToKilograms = 0.453592369999748;
??
Admin
As I said it's not about readability.
Your question comes down to an issue of precision, and that is a good argument for how to clean this code up a bit. In that case you might as well remove the constant completely.
Admin
At my last job i maintained a few legacy cobol programs from time to time. all numerical values were defined as variables. for example there would be a variable for 33, another for 1 and another for 0. Having never seen any other cobol programs i'm not sure if this is a standard but the code would read like this
if input_value_from_file_file_inp33n equals zero then
...
else if input_value_from_flat_file_inp33n equals thirty_three
...
oh, and did i mention that all the variable names were overly descriptive??
Admin
I had to laugh at this one. From my expierience, cobol variable names are indeed typically overly descriptive.
Admin
Lucky sod. My last COBOL maintenance job, the variable names were not only cryptic (obscure, borderline incorrect abbreviations), they were ambiguous (different abbreviations in each record) and on occassion, wrong ("Oh, we don't track this anymore---let's just use the field for this new thing. Without renaming it.").
Admin
At my first programing job there was a COBOL programmer who was ecstatic when we moved from the old PDPen to VAXen because he was no longer constrained to 8.3 filenames, and the COBOL compiler supported *really* long and descriptive names. His files were renamed using a 64.12 format, and his variable names were at least 48 characters long.
Fortunately, his exhorbitant consumption of caffeine allowed him to type with the superhuman speed of a hyperactive meth addict.
Unfortunately, he was also dyslexic. That was fun to watch.
On topic, the WTF here is that QUARTER_pi should have been named BIG_OL_SLICE_O_pi, and Deg2Rad should have been GET_REAL_I_WANT_MORE_pi
Admin
If this was true, then, as a favor for maintenance programmers, the programmer should have put in a comment explaining that fact. "These are defined here as constants for efficiency - because the target compiler isn't smart enough to optimize them out inside a loop". That would be the perfectly valid explanation that Alex was asking after...
Admin
Admin
It would be more readable to say piOverTwo rather than 1.570795 and it would be faster than pi/2. Do the calculations once.
Some of the other stuff is reasonable as well, like the conversion functions (if they're not already avaiable). But
Admin
Are you really telling me that you've never heard of stdlib or math.h.
Admin
ANSI-C does not recognise the "inline" keyword. It is C++. But I agree wholeheartedly that it is not bad at all.
I don't know of any compiler that would do this. Every executable has a section called the LIT segment (for literals). The contents of this section are built by the linker during symbol matching - every compiler I know of performs data matching on generated symbols, this is actually quite a trivial thing to do since the only data-types that can be declared without a symbol name by the programmer are hard-coded basic types (and strings) - complex types cannot attain global scope without a symbol name, though some compilers (MSVC for one) are clever enough to match even locally scoped complex types with similar declarations from other functions and map them to the LIT segment under a single reference (assuming that the functions do not modify the contents). Moreoever, the scope of search is heavily restricted because the LIT segment is usually also ordered by type (to allow byte-swapping for portable executables) making it easier still to match similar quantities.
This code is NOT a WTF, here's why;
A MUL (multiply) instruction on Intel will complete inside 2 clock cycles everytime, regardless of input. A DIV (divide) instruction takes between 3 and 8 cycles depending on input. So replacing division with multiplication is obvious.
The conversion of a constant division to constant multiplication cannot be done for you by the compiler because the result must be stored in 64bits (a loss of precision from the 80bit intermediate value that the FPU will achieve internally) - the quantity of loss depends on the dividend. Since the compiler cannot know ahead of time what precision you want or the range of the dividend, it must choose caution and retain full precision (and thus use a DIV).
The author of this code appears to be aware that all of his conversions have inherent precision loss because most result in repeating decimals (and cannot be represented in a IEEE FP) so he has flattened them all to the fastest instructions they can be instead.
If you're going to be a critic make damn sure you know what you're talking about.
Admin
I think you especially should stick to using these functions since you obviously don't know the conversions yourself.
CM (centimetres) to MM (millimetres) is 10 not 1000.
Admin
Of course it's 1000. First you divide by 100, then multiply by 1000. Duh!
Admin
I don't get the people defending this code.
The point isn't the fact he used constants! The point is the NAMES of the constants.
Do you think you really want the remember the name of the constant for pounds to kilograms is called 'One2Pt20462262185th' ??? I guess 'Lbs2Kgs' or similar is too simple.
But, nah, let's get lost in crud about execution time.
Get real, folks.
Admin
If you're referring to M_PI, that's not in standard C++.
Admin
A worthy point. But notice that no maintenance programmer ever need know the variable names - only the names of the functions which use them (and the functions have sensible self-describing names). Given that, it's still not a big deal.
Admin
Admin
<font size="2">
the code is a WTF.
if the code makes you laugh the first time you see it - it must have some wtf'ness in it. I am just a stupid java girl- but I suppose that C(and then the ++ one) surely have the libraries for these conversions.
</font><font size="2">The constants names are deffinitely a WTF (even the author knew they were crappy that's why he commented them). </font><font size="2">A constant is something that is used a lot of times or at least may be reused in the future. I would never use a constant named One2Pt20462262185th. but maybe I am just a lame feministic bitch...
I assume you write just the same brilliant code - your last sentence makes me think so. congratulations. I deffinitely envy those who'd need to maintain your code.
But I appreciate the lesson of what was good about this code. I learned smth today. Thanks.
</font>
Admin
<font size="2">You are a dumb-arse! you didn't read that "</font><font size="2"></font><font size="2">A DIV (divide) instruction takes between 3 and 8 cycles depending on input</font>"<font size="2">?
:| remember! first the constant declaration:
double const ten = 1000/100;
then you MULTIPLY! duh! ;)
</font>
Admin
A WTF indeed. Strange that the descriptively-named functions:
<FONT size=+0>inline double</FONT> Inches2MM( <FONT size=+0>const</FONT> <FONT size=+0>double</FONT> &i ) { <FONT size=+0>return</FONT> i*25.4; }
<FONT size=+0>inline double</FONT> Inches2CM( <FONT size=+0>const</FONT> <FONT size=+0>double</FONT> &i ) { <FONT size=+0>return</FONT> i*2.54; }
<FONT size=+0>inline double</FONT> Inches2Meters( <FONT size=+0>const</FONT> <FONT size=+0>double</FONT> &i ) { <FONT size=+0>return</FONT> i*.0254; }
<FONT size=+0>inline double</FONT> Inches2KM( <FONT size=+0>const</FONT> <FONT size=+0>double</FONT> &i ) { <FONT size=+0>return</FONT> i*.0000254; }
didn't even *use* the named constants. Perhaps the programmer forgot that he even defined those constants before.
Admin
No they are not, they are pointless, why not just include <font style="color: rgb(0, 0, 0); font-family: courier new;" color="#008200">0.453592369999748</font>.
Unless your compiler is useless, 1.0/0.0000254 will be compiled to <font color="#008200">39370.0787401575. Now if it was called</font><font color="#008200"> KM_TO_INCHES noone would be compaining.</font><font color="#008200">
</font>
Admin
No, they are not descriptive.
"Blue" is not descriptive.
"SkyColour" is descriptive.
The names are entirely meaningless.
Admin
My guess is that he is going to do a lot of calculations where these constants will appear often. If it is done in a tight loop, as often is the case when trig gets involved (my guess based on the first bunch of constants), a lot of time can be saved by cutting out some divisions. I would almost be prepared to bet some money that somewhere in that program you'll also find some lookup tables for the trig functions.
It may not be the cutest solution, but it will definately be faster and sometimes it just has to be fast enough. You can't have a missile finishing its course calculations after it has passed the target, you have to have the next screen ready when it is time to display it and so on. Sometimes it's just a huge simulation where small optimizations like this can mean the difference between a 3 day run and a 1 day run.
I'll call this code suspicious but not a WTF.
Admin
LOL, that post just made my day.
Did you ever think about putting super-glue under his Backspace key? I think his head would explode! [:@]
Admin
Wow, whatever happened to people just going "You're wrong, and here's why..." Must we resort to name calling and flaming? And very thinly veiled, passive-aggressive sarcasm? Reading this forum should not bring images of "UFC'S Greatest Knockouts" to mind.
Taking that chill pill sounds like a great idea...
Admin
Admin
Silly me, failed to post anything.
Defending this code with numbers of how many CPU cycles are spent on different things on an Intel CPU?
Does anyone know for sure it is meant to run on an Intel CPU?
Does anyone know if the code will run millions of times per second so that it actually makes a difference?
Did anyone benchmark this code and see that it will actually be faster?
Premature optimization is a favourite passtime for a lot of people who have once learned a little bit more about how a CPU works. It seldom does what they expect, or at least not as much.
Still, they gladly make the most bizarre code just because "it's faster" or "saves bytes".
Then again, if seeing this code gets you thinking about CPU cycles instead of the horrible constant names, then maybe there's no point in arguing...
Admin
Admin
Admin
C99 has the inline keyword and supports // comments, true. This is still C++. Here's why:
1) All the inline functions only work if they're in a header file. This is inherent to the way inline functions work. Only some compilers support the (not required by the standard) extension of full-program optimization, and they ignore inline specifications anyway when that's enabled.
As such, all this code most definitiely is inside a header file. However, in C, const variables have external linkage by default, while in C++ they have static linkage. As a result, if this were C, including the header in multiple source files would lead to symbol redefinition linker errors.
2) I have not been able to verify this absolutely, but I found no indication that even C99 supports references. To the best of my knowledge, they're an exclusive C++ feature. This makes this code guaranteed C++.
Here are a few other comment WTFs:
1) Someone said that the constants are faster, because the division will only be executed once. This is wrong. A process called constant folding will make certain that (unless the code is structured unfortunately) all operations on constants will be performed at compile-time, once. This is one of the most basic optimizations a compiler can perform, one that CS students learn (and have to implement) in their very first course on compiler building. (At least we had to do it.)
2) The claim that constant folding is not possible is bogus. For one, I do not recall the standard requiring the compiler to execute all interim calculations at the highest possible precision. Due to this, the semantics of the calculation are not 100% defined, and thus the constant folding optimization does not change the semantics (which no optimization is allowed to). Even if it is so, however, nothing prevents the compiler from saving the folded constant at full precision - there is no requirement that the folding of two double constants is of double size, too, especially as that value never exists on the language level.
3) The argument that using these constants saves memory is just as wrong. If you want to save space, you can ask the compiler to optimize for space, and it is free to fold all constants from all over the program into one memory location, as long as they have the same value. The other way round, if you ask it to optimize for speed, it can place a copy of the constant whereever it's needed, since it's constant and thus can't be changed. This will most likely be the default: given that these (inline) functions will be spread all over the program, accessing a central constant definition will very likely result in a cache miss, which is a far more serious problem in modern computers than the four bytes a double is larger than a pointer (no space savings at all on 64-bit machines).
There is exactly one WTF in this code: naming constants after their values, which completely defeats their purpose. Nothing more, nothing less.
Admin
Admin
Yep, and what about the use of "static_cast"? No such thing in C - any version.
There seem to be a lot of people on this board willing to abuse this code even though they clearly have never written a line of C/C++ in their life. The code could be better, the names of those constants are definitely a bit... strange. But that doesn't explain why some people here think it's the worst code they've ever seen - obviously, they haven't seen much real world code. The level of ignorance in some of the above posts is breath-taking.
Somebody was wondering about premature optimisation;
This is part of a math library - no further information is provided so we can only speculate on it's uses.
Here's a review of real world math libraries; there are 2 types; deterministic & non-deterministic. A non-deterministic library is one that makes no guarantees about execution speed, it can't even guarantee that a function will complete in finite time (though it's a pretty poor library that stalls completely) - this type of library generally ships as the default with compilers, they are useful for simple things like sin, log etc. A deterministic library makes a guarantee about the execution speed of every function (even the trickier ones like acos, pow etc), and this is extremely important for games, banks, astronomy, databases and just about anything that matters - default math libraries are rarely used in places that matter.
Please note; to those who haven't been a part of a large project written in a language that runs as native code, you cannot possibly appreciate the value of this because you haven't experienced it.
Somebody was wondering about the fact that there are unnamed constants embedded in the functions (as opposed to being declared like the rest of the weird ones);
Look at the functions that use embedded constants, not one of them uses a division. This code is actually highly consistent.
Several people also chose to attack me personally, rather than actually state a valid argument - this is usually a sign that the agressor has no valid argument but their ignorance holds sway.
The names are a bit strange. It's still no big deal.