- 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
nahh, I'd NEVER EVER press that funky Ctrl+Space key :D
Admin
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)
Admin
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.
Admin
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.
Admin
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.
Admin
Huh? Double.TryParse exists in 1.1.
Admin
What?!?[:|] I'm using VS 2003 with version 1.1 of the .NET framework and I've got it.
Admin
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.
Admin
remember TryParse is a static method, so in c++.NET you would use this syntax..... double::TryParse
Admin
[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>
Admin
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.
Admin
.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".
Admin
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?
Admin
This must be copied C++ code. Both the method signature and this are dead giveaways:
Admin
You gotta love all the negative logic too:
by applying boolean logic, this could be written as:Admin
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!
Admin
Admin
For a long time I thought the wtf was why there was a Parse *and* a TryParse. I'm so stupid.
Admin
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.
Admin
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.
Admin
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.
Admin
I would think the most exact name would be "IsReal", you know, as in mathmatics.
Admin
IsReal? What about IsFake?
Admin
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.
Admin
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#.
Admin
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.
Admin
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 :]
Admin
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).
Admin
Wow, preview is so completely broken on this site!
Admin
Wow that's hardcore. Kinda like building the pyramids without a level and iron tools.
Admin
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.
Admin
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??
Admin
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.
Admin
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....
Admin
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....
Admin
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.
Admin
Admin
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!
Admin
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.
Admin
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.
Admin
The WTF as far as I am concerned is that UsedDecimal is set but the value of UsedDecimal is never used.
Admin
Only if you want to parse the whole array, it looks like the intention was not to do that.
The
char
type represents unsigned 16-bit integers with values between 0 and 65535. The set of possible values for thechar
type corresponds to the Unicode character set. Althoughchar
has the same representation asushort
, not all operations permitted on one type are permitted on the other.Admin
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.
Admin
Oops. Missed it.
Admin
Correct me if I am wrong (again) here but wouldn't this return true for an empty String, and the Strings "." and "-"?
Admin
and "-."
Admin
You are right. Depending on the specification, this can be desired, irrelevant or bug.
Admin
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.
Admin
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.
Admin
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.