• (cs)

    nahh, I'd NEVER EVER press that funky Ctrl+Space key  :D

  • (cs)

    Heh, I hope this isn't related to the IsANumber function I suggested to replace a try/catch for errors on a string in a different thread :-D  It's nice to know that there's a built-in functionality that also compensates for different country's methods of creating number strings. In France for example numbers are written 1.000.000,00 , so IsFloat would fail.  Also if somebody were using 1,000,000.00 in US measurements it would fail too!

    I can kinda see why somebody would write this WTF though.... Unfortunately, regular C doesn't have a try_atoi or try_atof function... so you're stuck writing your own TryParse.  I don't think there's a convenient way to use try/catch either... the documentation for atof doesn't mention any exception handling.  You have to compare the result to zero or check the string beforehand.

    Maybe we need a new acronym: RTFI (read the farking intellisense)

  • Hung Lou (unregistered)

    haha....I also noticed that he named the method IsFloat, which would imply that he was trying to check to see if the value was a float....NOT a double. Which I guess is a good thing, although his implementation is horrible and will fail for a good amount of tests. Please tell me that this isn't in any system critical app.

    Also, if he was checking to see if the value was a float then he wouldn't have wanted to use the double.TryParse, since a float and a double are not one in the same. Hence, you are somewhat INCORRECT as well, although I am not saying his implentation is better but at least he knew that doubles are not floats. 

  • (cs) in reply to Hung Lou

    Sometimes "float" is a generic term for "floating point" which includes floats and doubles.  The function IsFloat doesn't care if the string is either float or double, it just takes a string and makes sure that it has numbers around a period with an optional negative sign.  Maybe a more accurrate name for this function should have been "IsDecimal".  Then one would be sure that all the function does is check for a decimal place in a number string.

  • Jeff Lewis (unregistered)

    It would also be good if TryParse were part of the current .NET framework.  It isn't.  It's part of v2.0 that is yet-to-be-shipped and hence not on your user's computers.

  • (cs) in reply to Jeff Lewis
    Anonymous:

    It would also be good if TryParse were part of the current .NET framework.  It isn't.  It's part of v2.0 that is yet-to-be-shipped and hence not on your user's computers.


    Huh?  Double.TryParse exists in 1.1.
  • (cs) in reply to Jeff Lewis
    Anonymous:

    It would also be good if TryParse were part of the current .NET framework.  It isn't.  It's part of v2.0 that is yet-to-be-shipped and hence not on your user's computers.

    What?!?[:|] I'm using VS 2003 with version 1.1 of the .NET framework and I've got it.

  • (cs) in reply to skicow

    I'm using VC++ 2003 with .NET 1.1 and I definitely do not have it.  Intellisense is like "WTF ARE YOU DOING BITCH" when I type double. (CTRL+SPACE).  It then bitch slaps me hard.  I should see if my box at home with VS 2005 + .NET 2.0 has that functionality.  Because it would roxor mah boxor.

  • Hung Lo (unregistered) in reply to Charles Nadolski

    remember TryParse is a static method, so in c++.NET you would use this syntax..... double::TryParse

  • Robin Lavallée (unregistered) in reply to Hung Lo

    [C#] public static bool TryParse( string s, NumberStyles style, IFormatProvider provider, out double result );

    [...]
    <font color="red">
    Syntax based on .NET Framework version 1.1.
    </font>

  • Hung Lou (unregistered) in reply to Charles Nadolski

    For what you are saying,  "IsDecimal" wouldn't be a proper function name either. If what you said, "Then one would be sure that all the function does is check for a decimal place in a number string.",  then the user would have just named the function HasDecimal or HasOneDecimal. And if you are using a language such as c#, then float wouldn't be a generic term to someone that is using the language...if they say IsFloat they would think of the value type float.

  • (cs) in reply to Robin Lavall&#233;e

    .NET 2.0 (aka Whidbey) will have support for things like Int32.TryParse, DateTime.TryParse, etc. 1.1 only has TryParse for Doubles, which might be where some of the confusion springs from.

    As for the WTF... ugh. I think the same developer is currently working hard on a new, revolutionary device he says will be called the "wheel".

     

  • (cs) in reply to A Wizard A True Star

    I tryied using double:: but that didn't present anything useful either.

    I also tried using Double but that doesn't seem to be a valid type (in C++ anyway).  Was the source of the WTF C# by any chance?

  • anon (unregistered)

    This must be copied C++ code. Both the method signature and this are dead giveaways:

        // return TRUE if the character is 0 (the string is over)
    if(text[i] == 0) return true

  • (cs)

    You gotta love all the negative logic too:

    else if(  !(text[i] >= '0' && text[i] <= '9') && !(i == 0 && text[i] == '-')  ) return false;
    by applying boolean logic, this could be written as:

    else if(  (text[i] < '0' || text[i] > '9') && (i != 0 || text[i] != '-')  ) return false;

    or you could check for the leading '-' before the loop, then this else could be:
    else if(text[i] < '0' || text[i] > '9') return false;

    As somebody new to .Net myself, I might not have stumbled on the name TryParse for this type of check.
    If this is part of something where processor cycles are important, I'm sure this is more efficient for this specific type of check than TryParse would be.

    nerfer

  • (cs) in reply to anon
    Anonymous:
    This must be copied C++ code. Both the method signature and this are dead giveaways:
        // return TRUE if the character is 0 (the string is over)
    if(text[i] == 0) return true



    Wait a minute... if the function terminates when the null character is found, WhyTF is the string length passed in as a parameter?!?!?  Shoot me now!
  • (cs) in reply to anon
    Anonymous:
    This must be copied C++ code. Both the method signature and this are dead giveaways:
        // return TRUE if the character is 0 (the string is over)
    if(text[i] == 0) return true
    This is C# code.
  • stoopid (unregistered) in reply to skicow

    For a long time I thought the wtf was why there was a Parse *and* a TryParse.  I'm so stupid.

  • (cs) in reply to skicow
    skicow:
    Anonymous:
    This must be copied C++ code. Both the method signature and this are dead giveaways:
        // return TRUE if the character is 0 (the string is over)
    if(text[i] == 0) return true
    This is C# code.


    That's a carry over from c using strings as char arrays, but it's read-only in C#.

    Anyway, if you start posting WTF's for people who don't know the framework things could get really out of control.  There's a learning curve before even good programmers properly leverage the built-in functionality.  In many cases instead of laughing at them we could be showing our coworkers the proper way.  Or laugh at them and then show them.  Or point and laugh.  Pointing and laughing is admittedly the most fun.
  • (cs) in reply to skicow
    skicow:
    Anonymous:
    This must be copied C++ code. Both the method signature and this are dead giveaways:
        // return TRUE if the character is 0 (the string is over)
    if(text[i] == 0) return true
    This is C# code.

    The point is that it's a common chunk of C++ code (MFC specifically), even if it's ALSO legal if stupid C# code. I've seen more than a few similar stupidities from C->Java and C->PHP direct translations. I wonder when this contingent will realize that String manipulation no longer means null-terminated 8-byte char arrays.
  • (cs) in reply to stoopid
    Anonymous:

    For a long time I thought the wtf was why there was a Parse *and* a TryParse.  I'm so stupid.

    Parse throws an exception on failure where as TryParse will simply return false. I'll use TryParse when looking at user-entered data for the first time and Parse when taking data that *should* be a decimal (such as data submitted on a web page that already passed the client-side validator).

    In tight loops and performance critical code, TryParse is most definitely the way to go as it doesn't throw exceptions.

  • cp (unregistered) in reply to Hung Lou
    Anonymous:

    For what you are saying,  "IsDecimal" wouldn't be a proper function name either. If what you said, "Then one would be sure that all the function does is check for a decimal place in a number string.",  then the user would have just named the function HasDecimal or HasOneDecimal. And if you are using a language such as c#, then float wouldn't be a generic term to someone that is using the language...if they say IsFloat they would think of the value type float.

    I would think the most exact name would be "IsReal", you know, as in mathmatics.

  • (cs) in reply to cp

    IsReal?  What about IsFake?

  • (cs) in reply to Charles Nadolski

    Charles Nadolski:
    Wait a minute... if the function terminates when the null character is found, WhyTF is the string length passed in as a parameter?!?!?  Shoot me now!

    Looks as though the code was "converted" from C / C++ -> C#. C requires the length of the array to be specified whereas C# and .NET in general do not.

  • (cs)

    Finding a locale-insensitive way of parsing floating points in C# is NOT easy for a newbie, and I speak from experience. Basically, to this day I don't know any way to do it but to explicitely pass the neutral locale.
    Admittedly, though, to this day I've done next to no coding in C#.

  • crazy canuck (unregistered) in reply to kentcb
    kentcb:

    Charles Nadolski:
    Wait a minute... if the function terminates when the null character is found, WhyTF is the string length passed in as a parameter?!?!?  Shoot me now!

    Looks as though the code was "converted" from C / C++ -> C#. C requires the length of the array to be specified whereas C# and .NET in general do not.

    Are you crazy? The function terminates on a null... this means it doesn't need the length even if you give it.  You are likely correct that the function is converted from C (hinted by the terminate on null) and in .NET you don't need to mention the length cause lenght is basically built into the string.  So asking for length is pointless in all possible versions of this code.

  • (cs)

    I've been reading this site for a few months now - It's the first thing I look at each morning before diving into c# and PL/SQL. Helps give me some perspective, I think.... anyway, no one seems to have commented on this programmer being a graduate (with honours) from the School of Inconsistant Variable Names:

    char[] text

    int nLength

    bool UsedDecimal

    Must be some wacky coding standards in that shop :]

  • Freidrich (unregistered)
    It's always entertaining to see a programmer insist upon implementing his own version of built-in functionality. Especially when the built-in method is literally right infront of you (thanks to Intellisense)

    I have to agree with wakestate - not being aware of functionality is not much of a reason for ridicule. Also, not everyone uses Intellisense. I write my .NET programs with vim and the command line.

    I also have to admit to occasionally reimplementing something because I didn't know it was already there (poring through MSDN is quite a chore), or because the method name didn't exactly suggest to me what it would do ("TryParse" doesn't sound particularly intuitive to me).

  • Freidrich (unregistered) in reply to Freidrich

    Wow, preview is so completely broken on this site!

  • (cs) in reply to Freidrich
    Anonymous:
    Also, not everyone uses Intellisense. I write my .NET programs with vim and the command line.


    Wow that's hardcore.  Kinda like building the pyramids without a level and iron tools.
  • (cs) in reply to cp

    I personally dislike the use of the word "Real" in most software, since rarely do computers deal with real numbers.  With the exception of Maple and other CAS systems, how many languages can deal with Pi or the square-root of 2 without approximating?

    It bugs me when databases and programming languages use "real" to mean floating-point, which is really a subset of real numbers.  For example, 1/10, a very common real number, is not a value in most floating-point formats.

    I suppose the same could be said about mathematical integers vs "int", but at least the only restriction on integers is usually range (actually, "Int32" is a great name, even though I use "int" most of the time). 

    So in this case, IsDecimal would probably be preferable to IsReal, but it implies any number converted from Decimal.ToString would be valid.  IsFloat is okay, since there's no "Float" type in the BCL (just in C#'s naming--and unfortunately System.Data.IDataReader (ugh)).  However, since it does not look for exponential notation, IsFloat isn't correct either.

  • (cs)

    Sadly in 1.1. of the framework, integers, singles etc lack a tryparse, leaving you with the VERY expensive parse.

    Personally, I prefer Delphi's StoTo{int|curr|Float}def(string,default) calls, and since Anders was a major driver in both Delphi and dotNet, the real WTF is why this functionality was missing to begin with.

    Not realizing that doubles have extra parsing capabilities that no other value type has?  No surprise there. Having to pass the length of an array seperately?  Again, no surprise, as its a long standing dirty trick to re-use a staticly defined char array with definable length to prevent re-allocation issues.

    Are they needed here?  Probably. dotNet's string support is both excellent and completely hideous.  Any delphi programmer out there knows that you can do re-usable strings without making them immutable.  dotNet balances the extra logic for a special case again the concept that modifying a string is a special case, after all who modifies strings, right??

  • anon (unregistered) in reply to crazy canuck

    Not necessarily pointless. Not only does it terminate on a null, it also terminates when the passed length has been reached which is useful if you don't want the whole array to be tested.

    You'll note that many of the .NET framework methods that take arrays also allow you to specify the length. You're not telling the routine the length of the array, just the maximum number of elements to be tested/used.

  • David Crosby (unregistered)

    I really think the real WTF in this one is the smug nature of most of the responses. Anyone who claims they know the .Net Framework inside out isn't a guru - they're a wanker. One of the most common issues one sees during code review is the duplication of functionality available through existing API's - this doesn't reflect poorly on the developer, it's simply a product of developing on an extremely rich and complex platform.  As has been mentioned before, the framework is somewhat inconsistent in limiting TryParse methods to the double type and it's hardly a surprise that the developer missed it.

    In summary - WORST....WTF.......EVER....

  • (cs) in reply to crazy canuck
    Anonymous:
    ...

    Are you crazy? The function terminates on a null... this means it doesn't need the length even if you give it.  You are likely correct that the function is converted from C (hinted by the terminate on null) and in .NET you don't need to mention the length cause lenght is basically built into the string.  So asking for length is pointless in all possible versions of this code.

    I hope you don't write C-code... You would just assume for the sake of simplicity that there always is a NULL termination? I wouldn't... Input can't be trusted. The fact that it has to be checked says enough to me...

    Anyway - I can see plenty of reasons why to do smth like this in this way, I've done such things in Java, and will do them again if needed (a lot of ppl will jump now [:P]). Let me explain a bit. What if someone wrote a C-program which just sends data over a communication layer (tcpip/modem/serial line/whatever)? Or writes C-structures that contain strings to a file, which you have to read?

    I had to do stuff in Java that was time-critical, and wrote such string-functions to work immediately on an input buffer (of bytes) to compare what would be the fastest. On the target-VM and machine that had to run the code (386 33mhz with 8mb ram - embedded stuff), the "C-alike" code was a lot faster than the native Java code. On PC on the otherhand, it was the other way around, but that didn't matter (yes it takes some nasty tricks to get Java responsive on such a thing...)

    I can make up more reasons to, but prolly this code is indeed just from a C/C++ coder writing code for the first time in C#. So what? Everybody does that when he worked for years in one certain language, and then suddenly has to switch to a completely new-one....

  • (cs)

    Honestly, I can hardly see a WTF in this example. (OK, we can discuss about the beauty of the variable names, but that doesn't make it a WTF).
    If checks it the first nLength characters in text are a valid floating point number in a simple style. (e.g. it does not accept "1e10")
    Maybe the array is longer but only the first 10 characters shall be a number. Since it also explicitely accepts 0-terminated Strings as valid input, TryParse would not give the same results.
    It looks like reinventing the wheel (and maybe is) but without knowing the context no-one can say for sure if there are valid reasons for creating this implementation or not.

  • Cande (unregistered) in reply to loneprogrammer
    loneprogrammer:
    IsReal?  What about IsFake?
    as opposed to IsImaginary() you know all that square-root-of-minus-one stuff!
  • (cs) in reply to Cande

    ok, so the quoting doesn't quite work as expected!

    loneprogrammer: IsReal? What about IsFake?

    as opposed to IsImaginary() you know all that square-root-of-minus-one stuff!

  • Tim Smith (unregistered)

    Length is commonly passed into routines where you wish to do inline parsing.  Otherwise you would have to copy the string to another location and null terminate it.

    Just because YOU have never seen a need for it, doesn't mean it is bad.  If I saw one of you guys copy that string to another location just so you can NULL terminate and then invoke this routine, I would be posting your code on WTF.

  • (cs) in reply to Tim Smith
    Anonymous:
    Length is commonly passed into routines where you wish to do inline parsing.  Otherwise you would have to copy the string to another location and null terminate it.

    Just because *YOU* have never seen a need for it, doesn't mean it is bad.  If I saw one of you guys copy that string to another location just so you can NULL terminate and then invoke this routine, I would be posting your code on WTF.


    Hmmm... I was also thinking, isn't there another alternative to passing in the length parameter?  Can't you use  length = sizeof (somechararray)/sizeof(char) ?

    speaking of char arrays, I see another WTF in using them for this function that are not mentioned:
     the function assumes the program isn't being executed on a machine that relies on unicode, or if this is an ASP.NET thing that the string sent by the browser isn't unicode. The person should have used LPCTSTR if this was C++.  Then again, since this is C# he/she should just have used vanilla string.
  • (cs)

    The WTF as far as I am concerned is that UsedDecimal is set but the value of UsedDecimal is never used.

  • (cs) in reply to Charles Nadolski
    Charles Nadolski:

    Hmmm... I was also thinking, isn't there another alternative to passing in the length parameter?  Can't you use  length = sizeof (somechararray)/sizeof(char) ?

    Only if you want to parse the whole array, it looks like the intention was not to do that.

    Charles Nadolski:

    speaking of char arrays, I see another WTF in using them for this function that are not mentioned:
     the function assumes the program isn't being executed on a machine that relies on unicode, or if this is an ASP.NET thing that the string sent by the browser isn't unicode. The person should have used LPCTSTR if this was C++.  Then again, since this is C# he/she should just have used vanilla string.


    The char type represents unsigned 16-bit integers with values between 0 and 65535. The set of possible values for the char type corresponds to the Unicode character set. Although char has the same representation as ushort, not all operations permitted on one type are permitted on the other.
  • (cs) in reply to dubwai
    dubwai:
    The WTF as far as I am concerned is that UsedDecimal is set but the value of UsedDecimal is never used.


    are you blind? Browser not working? UsedDecimal is used to determine wheter or not a decimal point has yet been parsed or not, to make sure there is only on decimal point in the string.
  • (cs) in reply to ammoQ

    ammoQ:
    dubwai:
    The WTF as far as I am concerned is that UsedDecimal is set but the value of UsedDecimal is never used.


    are you blind? Browser not working? UsedDecimal is used to determine wheter or not a decimal point has yet been parsed or not, to make sure there is only on decimal point in the string.

    Oops.  Missed it.

  • (cs) in reply to dubwai

    Correct me if I am wrong (again) here but wouldn't this return true for an empty String, and the Strings "." and "-"?

  • (cs) in reply to dubwai

    dubwai:
    Correct me if I am wrong (again) here but wouldn't this return true for an empty String, and the Strings "." and "-"?

    and "-."

  • (cs) in reply to dubwai
    dubwai:
    Correct me if I am wrong (again) here but wouldn't this return true for an empty String, and the Strings "." and "-"?

    You are right. Depending on the specification, this can be desired, irrelevant or bug.
  • (cs) in reply to ammoQ

    ammoQ:
    dubwai:
    Correct me if I am wrong (again) here but wouldn't this return true for an empty String, and the Strings "." and "-"?

    You are right. Depending on the specification, this can be desired, irrelevant or bug.

    It's possible that this is desired or irrelevant but if the purpose is to determine whether the value is a simple decimal or integer, it's a bug.  I don't know what numbers "", ".", "-", or "-." are, do you?  Maybe in some strange notation that's fine but I'm guessing bug.

    Doesn't .Net have any built in functionality for this type of thing?  Java has a NumberFormat class that lets you define how to parse different things like this.

  • (cs) in reply to ammoQ
    ammoQ:

    The char type represents unsigned 16-bit integers with values between 0 and 65535. The set of possible values for the char type corresponds to the Unicode character set. Although char has the same representation as ushort, not all operations permitted on one type are permitted on the other.


    Hmm, this must be a feature of C# then.  In C++, char is a number between -128 and 127 (unsigned char is 0 to 255).  If you want something that will dynamically adjust to unicode or ascii depending on machine settings, you have to use the type TCHAR, _T("some text"), LPTSTR, and finally, CString.
  • Anonymous Coward (unregistered) in reply to Charles Nadolski

    Hmmm... I was also thinking, isn't there another alternative to passing in the length parameter?  Can't you use  length = sizeof (somechararray)/sizeof(char) ?



    If this is copied from c/c++ code (I can only speak for those, since I don't know much about c#), that would not nessarily work there.  It would only work if you have an array defined:

    char   somechararray[17];

    which sizeof(somechararray) would return 17 as expected.  But if allyou have is apointer at that point, or even something like:

    char*  somesubchararray=somechararray;

    then sizeof(somesubchararray) would be '4' (at least on a 32 bit machine).  so big differnce.

Leave a comment on “Next Time, Try TryParse”

Log In or post as a guest

Replying to comment #:

« Return to Article