• fbartho (unregistered) in reply to Crispy

    YES

  • Marty DiBergi (unregistered) in reply to Roby McAndrew
    Roby McAndrew:
    I recall writing very similar code, long long ago, but mine only went up to 'f' or 'F'. This goes all the way up to eleven and beyond !

    Why not make it just go up to F and define F as 11?

    Marty

  • Marty DiBergi (unregistered) in reply to Mike
    Mike:
    So, where exactly is the WTF here?

    Or is this a site for theoretical perfectionists that have nothing better to do than nit-pick.

    Without knowing the problem domain there is nothing to see here.

    theoretical perfectionists that have nothing better to do than nit-pick == thedailywtf

  • foxyshadis (unregistered) in reply to gnasher729
    gnasher729:
    skington:
    A proper Unicode-aware atoi implementation should cover non-arabic number systems as well.

    That depends. There are plenty of standards where text can contain numbers, but only in very specific formats, so let's say digits in one of the many indian scripts wouldn't be allowed. In other situations, they should be allowed. Which means you can't say "I have a function converting text to a number", you have to say "I have a function converting text to a number according to the following rules...".

    And then you might recognise roman numerals as well, so "Series 2, Episode 4" and "Series II, Episode IV" would be accepted as the same.

    Well, this function actually can recognize and convert Roman numerals! In fact, it could crunch that whole string just fine. It just won't give you back exactly what you were looking for....

  • Swedish tard (unregistered) in reply to anonymous
    anonymous:
    sztupy:
    It should only cast the stone, not return it
    A "cast" in C is completely different than a "cast" in natural language. A synonym which is more closely adhering to the original meaning would be "throw".

    http://en.wikipedia.org/wiki/Casting

  • anonymous (unregistered) in reply to Swedish tard
    Swedish tard:
    anonymous:
    sztupy:
    It should only cast the stone, not return it
    A "cast" in C is completely different than a "cast" in natural language. A synonym which is more closely adhering to the original meaning would be "throw".

    http://en.wikipedia.org/wiki/Casting

    Yes, but the "casting stones" reference refers to throwing them at fragile and/or malleable objects, not heating them to the molten point and reshaping them into five-dollar trinkets.
  • Sebastian Ramadan (unregistered) in reply to gnasher729

    Ah, so you've seen a system that translates ASCII to EBCDIC (as well as it can). In that case, consider a CGI implementation, which obviously has to interact with the rest of the world but doesn't have to expose the scripts it runs.

    I agree. This code is better written as something like:

    int transform(unsigned char c) { char charset[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; return isdigit(c) ? c - '0' : 10 + (strchr(charset, c) - c) / 2; }

  • Sebastian Ramadan (unregistered) in reply to anonymous

    Okay, umm... Does Latin matter? Please discuss with ludus (my captcha).

  • Sebastian Ramadan (unregistered) in reply to superman

    The code was written by a newb, and anyone who insists that the code is fine is also a newb. You'll understand, in five to ten lawsuits time, when you've realised the err of your ways and decided to read the C standard (and the Objective-C standard).

  • Sebastian Ramadan (unregistered) in reply to Mark F

    "Calling it atoi() might be a bit confusing to those used to C's atoi() ..."

    Yes, and the developer has agreed to write code in C. That means the developer should follow the rules of C.

    "... but if anything it's C's atoi() that's named confusingly"

    Yes, but the developer has agreed to write code in C. That means the developer should follow the rules of C.

    "... why not call that one stoi() since it clearly works on a string, while this one doesn't?"

    Presumably, atoi was named with an 'a' instead of an 's' because it operated on an "array" of decimal digits which isn't necessarily a string. That's just a guess. Since there's already an strtod, why not typedef FILE* file; typedef tss_dtor_t destructor; typedef unsigned int uint; typedef uint32_t uint32; while we discuss this?

  • pecus (unregistered) in reply to Sebastian Ramadan
    Sebastian Ramadan:
    "Calling it atoi() might be a bit confusing to those used to C's atoi() ..."

    Yes, and the developer has agreed to write code in C. That means the developer should follow the rules of C.

    a) It's Objective C, not C. b) Is there a rule in Objective C that says a method can't have the same name as a standard C function? Because if not, then it's following the rules just fine.

    "... but if anything it's C's atoi() that's named confusingly"

    Yes, but the developer has agreed to write code in C. That means the developer should follow the rules of C.

    "This one developer decided to write code in [Objective] C, therefore no-one on this forum is allowed to comment on the wisdom of C's naming conventions"?

    "... why not call that one stoi() since it clearly works on a string, while this one doesn't?"

    Presumably, atoi was named with an 'a' instead of an 's' because it operated on an "array" of decimal digits which isn't necessarily a string. That's just a guess.

    It operates on an "array" of decimal digits terminated by a NUL. Under what circumstances would that not be a string, according to the C definition?

    Since there's already an strtod, why not typedef FILE* file; typedef tss_dtor_t destructor; typedef unsigned int uint; typedef uint32_t uint32; while we discuss this?
    I can't even guess what you're trying to say here.
  • fan (unregistered) in reply to Sebastian Ramadan
    Sebastian Ramadan:
    Presumably, atoi was named with an 'a' instead of an 's' because it operated on an "array" of decimal digits which isn't necessarily a string.

    and you

    pecus:
    It operates on an "array" of decimal digits terminated by a NUL.

    Kids, it was named atoi because its accepting ASCII characters as an input.

  • Norman Diamond (unregistered) in reply to Sebastian Ramadan
    Sebastian Ramadan:
    Presumably, atoi was named with an 'a' instead of an 's' because it operated on an "array" of decimal digits which isn't necessarily a string. That's just a guess. Since there's already an strtod
    There wasn't already an strtod when atoi was invented. Meanwhile, can you figure out how atoi knew when it reached the end of the array?
  • gnasher729 (unregistered) in reply to Sebastian Ramadan
    Sebastian Ramadan:
    Ah, so you've seen a system that translates ASCII to EBCDIC (as well as it can). In that case, consider a CGI implementation, which obviously has to interact with the rest of the world but doesn't have to expose the scripts it runs.

    I agree. This code is better written as something like:

    int transform(unsigned char c) { char charset[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; return isdigit(c) ? c - '0' : 10 + (strchr(charset, c) - c) / 2; }

    I remember someone writing a function very similar to this, and everyone wondering why it was running unexpectedly slow. I mean really slow, even if you passed '0' to this one where strchr wouldn't be called. Why did you write "char charset[]" and not "char* charset"? Because the one you wrote means that an array of 53 bytes has to be initialised with the contents of the string, every time the function is called. Had you used char* charset, the string would be forever stored in a static array of const char.

    Then there's of course two awful bugs. For one, it doesn't compile because subtracting c from the result of charset gives a pointer which cannot be divided by two. Second, if you change c to charset, and c is not a letter, strchr will return a null pointer and the function will have undefined behaviour, most likely returning total rubbish.

  • gnasher729 (unregistered) in reply to fan
    fan:
    gnasher729:
    In Objective-C, assert and exceptions are there to identify errors made by the programmer which are fixed by changing the code, not unexpected situations at runtime.

    But this case looks exdctly like that. It's either -wrong item passed (semantics or encoding etc) -memory corruption -unescaped user input All of which seems coding error need to be fixed by coder

    Guess what: There's no specification for the method, so you can't say that calling it with for example '?' or 0 as an argument is an error or not.

    However, anyone with a tiny bit of experience in writing usable code will see that someone has to check whether inputs are correct, and that the rather complicated rules which inputs are correct must match between the caller and the callee, and that since the method checks all these cases anyway, it is by far the best solution if the method does the checking itself and informs the caller if the argument is wrong.

    That way we save lots of work on the caller side, and make sure automatically that any checks will be performed in a consistent way. So a reasonable specification would define what inputs are accepted as valid numerical values, what inputs are not, and what would be returned for inputs that are not numerical values.

  • immitto (unregistered) in reply to fan
    fan:
    and you
    pecus:
    It operates on an "array" of decimal digits terminated by a NUL.
    You are a fucking idiot piece of shit who clearly didn't bother either reading or understanding my post before jumping in and insinuating that I don't know what I'm talking about.
  • zennnnnn (unregistered) in reply to slipstream

    This is for hex and works because it is one char at a time. There must be an atoi somewhere for sequences that does the product from the end to the beginning into an int.

  • zennnnnn (unregistered) in reply to slipstream

    This is for hex and works because it is one char at a time. There must be an atoi somewhere for sequences that does the product from the end to the beginning into an int.

  • zennnnnn (unregistered) in reply to zennnnnn

    Additionally, supporting upto Z could be because why not or because some people use base 36 in formats that must support string representations of numbers such as XML for a poor man's compression.

    I could question this code, the error handling or lack thereof, the function name and wonder that surely there must be some library function to do the same but I wouldn't mock it that harshly without seeing the context.

  • dkechag (unregistered) in reply to faoileag
    faoileag:
    Of course I meant the hextricontesimal system, not the hexacosimal. Sheesh, these numerical multipliers are difficult :-)

    Well, no, it is would not be hextricontesimal either. If we attempted to use the Greek root system for base36 it would be triacontaheximal. But of course such a word is not used, nobody has proposed naming base36. However, the equivalent "triacontahexadic" is a perfectly valid word in modern Greek. Ok, not many uses since base36 is not popular (yet?)!

  • Sebastian Ramadan (unregistered) in reply to Norman Diamond
    Norman Diamond:
    Sebastian Ramadan:
    Presumably, atoi was named with an 'a' instead of an 's' because it operated on an "array" of decimal digits which isn't necessarily a string. That's just a guess. Since there's already an strtod
    There wasn't already an strtod when atoi was invented. Meanwhile, can you figure out how atoi knew when it reached the end of the array?

    atoi doesn't know when it reaches the end of the array. To the contrary, it knows nothing about the size of the array, or even if it is an array. atoi parses a sequence of decimal-digit characters, and stops parsing when it reaches a non-decimal-digit character. It's not specifically a string function, because it can operate on non-strings.

    ps. I hope you guys aren't using your real names, here...

  • Sebastian Ramadan (unregistered) in reply to pecus
    pecus:
    a) It's Objective C, not C.

    If you bother to read the Objective C specification, you'll realise that Objective C is a strict superset of C. This means that atoi() in Objective C is required to behave as it does in C.

    b) Is there a rule in Objective C that says a method can't have the same name as a standard C function? Because if not, then it's following the rules just fine.

    Yes. Read the Objective C language specification, and you'll realise that Objective C is a strict superset of C.

    It operates on an "array" of decimal digits terminated by a NUL.

    No. If you bother to read the specification, you'll find that atoi operates on a "sequence" of decimal digit characters terminated by a non-decimal-digit character. The sequence doesn't have to be in an array, nor does it have to be "terminated by a NUL".

    Under what circumstances would that not be a string, according to the C definition?

    Under the same circumstances where the sequence of decimal digit characters is terminated by some other non-decimal-digit character.

    Since there's already an strtod, why not typedef FILE* file; typedef tss_dtor_t destructor; typedef unsigned int uint; typedef uint32_t uint32; while we discuss this?
    I can't even guess what you're trying to say here.

    Of course not, because it's become clear that you don't like to read/research. Anyone else would have googled those keywords to develop an understanding.

  • Sebastian Ramadan (unregistered) in reply to gnasher729
    gnasher729:
    I remember someone writing a function very similar to this, and everyone wondering why it was running unexpectedly slow. I mean really slow, even if you passed '0' to this one where strchr wouldn't be called. Why did you write "char charset[]" and not "char* charset"? Because the one you wrote means that an array of 53 bytes has to be initialised with the contents of the string, every time the function is called. Had you used char* charset, the string would be forever stored in a static array of const char.

    Slow using which compiler? I could build a compiler that produces awful machine code... Does that help you? No. Stop gibbering. C code doesn't have speed; That's an aspect introduced by implementations (eg. my suboptimal compiler). Most common C compilers will optimise things such as strlen("hello") AOT, and they can do something fairly similar in this case.

    Stop guessing. Get your meaningful, actual problem solved. If it's too slow, profile it and use the results to determine where to optimise.

    Then there's of course two awful bugs.

    Okay. Let us run through these one by one.

    For one, it doesn't compile because subtracting c from the result of charset gives a pointer ...

    No. Subtracting one pointer from another pointer of the same type results in a ptrdiff_t, which is not a pointer, but an integer capable of representing the difference between two pointers.

    ... which cannot be divided by two.

    An integer cannot be divided by two? You're cooked!

    Second, if you change c to charset, and c is not a letter, strchr will return a null pointer and the function will have undefined behaviour, most likely returning total rubbish.

    Yes. I knew of this beforehand.

    I reiterate: Something like the code I originally posted would do. Please read and comprehend more carefully, in the future.

Leave a comment on “Best atoi() Implementation Ever”

Log In or post as a guest

Replying to comment #:

« Return to Article