• (cs) in reply to Zlodo
    Anonymous:

    Oh, and I do want you to have a heart attack. I used c++ and templates in a gameboy advance game, running on an arm7. And also on a nintendo ds. I may have violated some sacred law of embedded system programming there. The gods of misguided optimization are probably not amused.

     

    You are trying to kill Achille ? Oh noooooo, come on, would you kill Jerry Lewis, Jim Carey, Steve Martin ? We need to laugh SOMETIME, man ! ;o)

  • (cs)

    Nice to see that some people are still passionate about code optimization...

    - Someone who used to write video games in 6502 assembly language many, many, many winters ago

  • (cs) in reply to Bill

    Anonymous:

    Now the REAL WTF is why the author didn't grab one of MANY acceptably debugged atoi funcitons available and modify it for the platform - so at least the basic structure of the function call was correct.  The real WTF is why don't people just grab an implementation that you have sitting on your machine (and if you don't have an implementation there is another WTF).

    Solving trivial programming tasks by copying someone else's code is nothing to be proud of. If you think it is then your coworkers probably hate you.

     

  • Joe H. (unregistered) in reply to Watson

    Sure:

     The << is a left shift operator.  If you look at the binary representation of the number 4 in 8 bit binary notation you get 00000100.  If you shift it left by 1 step you instead get 00001000.  The effect of a left shit by 1 is to multiple the number by 2 (assuming you don't shift any 1's off the left side)

    m << 3 means to shift it left 3 times.  Our number 4 then becomes 00100000 or 32.  Which is exactly the same as 4 * (2^3)

    m << 1 means to multiply it by 2 as we already said.

    m * 2 + m * (2^3)

    m * 2 + m * 8

    2m + 8m

    10m


  • (cs) in reply to Kevin Puetz
    Anonymous:

    Actually, the use of shifts to do the (fast m* 10) is not particularly unusual, since m is a long and this is an "embedded" target. A fair number of 16bit micros don't have long multiplication in hardware, and if one of the two numbers is fixed a significant speed gain can be had by unrolling it to shifts vs. calling a library function to do it. Additionally, such lib functions are almost never reentrancy-safe, so they call all manner of bad things if you have interrupts.

    I know we're all used to assuming the compiler will do this sort of transformation, but platforms that don't have long multiply don't tend to have particularly stellar compilers either :-)

    While this is quite true, that statement is also what struck me. All that stupidity and I bet the original programmer was proudest of using the shift trick to speed up multiplication. Never mind the glaring errors and possible problems with the function. Never mind documenting that if you give it an empty string you only get the right answer by accident. No, the important thing is that this function has a fast multiplication by 10 in it!

  • Matt (unregistered)
    Anonymous:

    int atoi(const char *str) { return((int)strtol(str, (char **)NULL, 10)); }

    Was that written by a Java programmer ??? Better:

       int atoi(const char *str) { return strtol(str, NULL, 10); }

     

  • njkayaker (unregistered) in reply to DaBookshah
    DaBookshah:

    I was beaten to it, but yeah, the TRUE WTF is that the article writer thought the multiply by 10 was a WTF. we have (2^3)*m + 2*m = 10*m. Makes perfect sense.

     What is the point of making it fast if it is wrong?

  • njkayaker (unregistered) in reply to njkayaker
    Anonymous:
    DaBookshah:

    I was beaten to it, but yeah, the TRUE WTF is that the article writer thought the multiply by 10 was a WTF. we have (2^3)*m + 2*m = 10*m. Makes perfect sense.

     What is the point of making it fast if it is wrong?

    "wrong" applied to the function as a whole (not the single "fast" line).

  • Tom (unregistered) in reply to Clinton Pierce
    An "OSS" implementation of this is a legal nightmare.  Taking it from a GNU implementation, for example, binds you to all of the copyleft licensing crap.

    So take it from a BSD implementation. No problem at all. You do have to include an attribution in your documentation, but it's a few lines to copy and paste, and there's definitely no copyleft licensing crap. And the BSD code tends to be better :).

     

    -- tom 

    --

    Linux is like a FreeBSD fork maintained by 10 year old retards. -- Encyclopedia Dramatica

     

  • Tom (unregistered) in reply to Matt
    Better: int atoi(const char *str) { return strtol(str, NULL, 10); }

    Except that srtol returns a long, and atoi returns an int. Hence, you know, THE LETTERS AFTER THE 'TO' IN THEIR NAMES.

    -- tom

  • (cs) in reply to gwenhwyfaer

    I think you missed my punchline at the end

    >> Do not speculate

    We don't know the ISA for whatever processor that is, we don't know how whether the ALU supports multiplication or or shifting etc.

    I was trying to be (apparently unsucessfully) facetious. 

  • Reinoud Zandijk (unregistered) in reply to Azrael

    You have a point but you're missing the clue... The real problem is:

    1) when you evuate isspace(*p++), p is increased if isspace() returns 0 or 1 so its always off

    2) isspace() could be implemented as a macro!!! giving very wierd results indeed! as in +1, +2,... +8 ? since *p++ would be inserted in every if() in the macro and thus randomly adds a number to the pointer.

     

  • kaa (unregistered) in reply to Clinton Pierce

    The K&R version -- or any other published version

     

    historical unix is public domain

    BSD stdlib is, well, BSD-licensed. 

  • Megabug (unregistered) in reply to kaa

    It is one thing to impliment a standard library routine because you have to. It is another thing altogether to impliment a library routine to obfuscate your code - even worse than implimenting it because you don't know it exists!

    I have a vendor that implimented their 'own' version of LDAP ... basically they took open LDAP, made modifications to it, then renamed the resultant files. Every so often the application crashes with some heisenbug in the modified code. Standard LDAP tools will not work with the directory at all. They'll open up various branches of the highly modified treen in their tool - if you pay the price.

    Management doesn't care, as long as they can hold the vendor's balls over an open fire when it breaks. Even if they manage to recover some of the $millions they paid for the system, the resultant profit margin would still not match what we could make if we simply used open LDAP and built the application around the open standard ourselves. And it would just work... ARRRGGHH!!! WTF!!?

    I have only seen one sane development environment -- FOSS. Everyone else does insane things to stick it to the other guy, or on some questionable (false) money saving schemes.

  • eagle275 (unregistered)

    nice article .... but really - why did the programmer of atoi decide to check the first character to be in [0...9] and ONLY the first character ...

    second why start at the last char - would have been simpler to start with the first char after the optional sign that is a number - then loop by all following chars : multiply what you have by 10 , add next numeric char

    for the math part .... sqrt 10000 ... in what calculation-method do you get something different from 100 ?

Leave a comment on “The Magnitude of Ineptitude”

Log In or post as a guest

Replying to comment #:

« Return to Article