10

I want to parse a user input which contains longitude and latitude. What I want to do is to coerce a string to a number, preserving its sign and decimal places. But what I want to do is to display a message when user's input is invalid. Which one should I follow

parseFloat(x)

second

new Number(x)

third

~~x

fourth

+x
Om3ga
  • 30,465
  • 43
  • 141
  • 221
  • 3
    Never use `new Number()`, if any, use `Number()`. It depends on what kind of input you consider is valid. E.g. `parseFloat` will accept `"123foo"` and return `123` but `Number` (or the unary `+`) will return `NaN`. – Felix Kling Jul 23 '12 at 13:43
  • Yes good point: you can use the `Number()` constructor as a plain function though. – Pointy Jul 23 '12 at 13:55
  • Possible duplicate of [Convert a string to an integer?](https://stackoverflow.com/questions/1133770/convert-a-string-to-an-integer) – Heretic Monkey Aug 19 '19 at 11:33

4 Answers4

18

I'd use Number(x), if I had to choose between those two, because it won't allow trailing garbage. (Well, it "allows" it, but the result is a NaN.)

That is, Number("123.45balloon") is NaN, but parseFloat("123.45balloon") is 123.45 (as a number).

As Mr. Kling points out, which of those is "better" is up to you.

edit — ah, you've added back +x and ~~x. As I wrote in a comment, +x is equivalent to using the Number() constructor, but I think it's a little risky because of the syntactic flexibility of the + operator. That is, it'd be easy for a cut-and-paste to introduce an error. The ~~x form is good if you know you want an integer (a 32-bit integer) anyway. For lat/long that's probably not what you want however.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • what do you think about `+x`? – M. Abbas Jul 23 '12 at 13:46
  • @m.abbas well it's probably equivalent to `Number()` but personally I would stay away from it as it's "syntactically fragile" (I just made that term up). That's just me being paranoid however. – Pointy Jul 23 '12 at 13:47
  • Really? I love `+` :) The behaviour is well defined but it might not be obvious to everyone what it means/does (similar to `~~`). – Felix Kling Jul 23 '12 at 13:48
  • @FelixKling yes but as I note in my amendment it scares me because `+` is so crazy. Just a personal quirk I guess. – Pointy Jul 23 '12 at 13:50
  • ok @Pointy thank you for your reply! But as @Felix Kling said, it is not obvious to everyone and personally, i prefer to use `+` instead of the other functions. – M. Abbas Jul 23 '12 at 13:52
  • 1
    @Pointy The benefit of using `+` is the speed, as is shown in my answer's link. – Engineer Jul 23 '12 at 14:02
  • @Engineer interesting, but a [simple jsperf](http://jsperf.com/numbers-from-strings) suggests that in newer browsers it's probably not much of a difference. – Pointy Jul 23 '12 at 14:11
  • @Pointy I am not familiar with `jsperf`. Can you remove `Math.random()` part, and just hardcode values? That `random` could be the reason of incorrect results. – Engineer Jul 23 '12 at 14:19
  • @Engineer well the randomness just sets up a set of strings to convert, and both tests use the same strings. Feel free to play around with it; you can modify other people's tests if you like. – Pointy Jul 23 '12 at 14:26
  • @Pointy The tests show, that depends on browser, `+` can be faster or slower than `Number`. Probably in old browsers `+` is much more faster, but now it's not so. – Engineer Jul 23 '12 at 14:45
  • Yes I agree - for validating user input the performance is probably not a huge deal anyway. – Pointy Jul 23 '12 at 14:56
6

The first one is better. It is explicit, and it is correct. You said you want to parse floating point numbers. ~~x will give you an integer.

Ates Goral
  • 137,716
  • 26
  • 137
  • 190
  • could you tell me why the first one is better? – Om3ga Jul 23 '12 at 13:45
  • @al0neevenings parseFloat(x), +x, new Number(x) all perform roughly the same function, they parse the string in similar ways. parseFloat(x) returns a float every time, and is explicitly telling you that it is parsing a float. makes for readability. – Hans Z Jul 23 '12 at 13:48
  • 1
    Explicit, readable code is usually better (unless it's overly verbose). Terse hacks like `~~x` limit the readability of your code and should be avoided unless you're really tight on space for some reason (like a short JavaScript coding compo). And in your case `~~x` is not even a valid solution because it gives you an integer. – Ates Goral Jul 23 '12 at 13:48
  • @elclanrs Using +x can be confusing since + is also the string concat and addition operator. – Hans Z Jul 23 '12 at 13:49
  • How about if checking for the sign? I mean longitude or latitude could be negative. So is parseFloat(x) the best way to validate? – Om3ga Jul 23 '12 at 13:49
  • 1
    **@Hans Z** mmm...and `~~` is not confusing? I guess "confusing" depends on the developer... – elclanrs Jul 23 '12 at 13:50
  • 1
    The only problem I have with `parseFloat()` is that it ignores non-numeric characters after the number. Thus a string that starts with digits but then ends with random other characters can still be parsed, and it won't be a `NaN`. For some applications that may be OK of course. – Pointy Jul 23 '12 at 13:51
  • 1
    @al0neevenings Why don't you try and see with a few simple samples? Just write this in your JS console, or go to jsfiddle.net to experiment: `parseFloat("-42.42")` – Ates Goral Jul 23 '12 at 13:51
  • @Pointy then I think Number(x) would be the best way to go with. Is it correct? – Om3ga Jul 23 '12 at 13:59
  • 2
    Like I said, it would be my personal preference, but `+x` is shorter and there's nothing wrong with using it. (Using it in parentheses `(+x)` would solve the syntax issue anyway, and that's still shorter than `Number(x)` :-) – Pointy Jul 23 '12 at 14:01
3

To test whether input is number, use this:

function isNumeric(obj){
    return !isNaN( parseFloat(obj) ) && isFinite( obj );
}

To cast String to Number, use + ,it's the fastest method:

the unary + operator also type-converts its operand to a number and because it does not do any additional mathematical operations it is the fastest method for type-converting a string into a number

So overall, probably you need this:

if(!isNumeric(inputValue)){
    alert('invalid number');
}else{
    var num = +inputValue;
}

isNumeric borrowed from jQuery

Engineer
  • 47,849
  • 12
  • 88
  • 91
  • If you the `isNumeric` test, the efficiency of `+x` will become moot :) Maybe a `isNaN(num)` check after the conversion is better. – Ates Goral Jul 23 '12 at 14:05
  • @AtesGoral What you suggest, is not proved (I mean `isNaN`), what I have posted is already proved.So I will choose the reliable way. – Engineer Jul 23 '12 at 14:08
1

This is the code I would write to repeatedly take input until the correct one is obtained.

var d;

do {
    d = prompt("Enter a number");
    d = new Number(d);
} while( isNaN(d) );

document.write( d );

Note: new Number(d) will always give NaN if any character is non-numeric while parseFloat(d) will ignore trailing invalid characters.

M. Ahmad Zafar
  • 4,881
  • 4
  • 32
  • 44