10

I want to test if a string can be cast as a float. I have been trying to use parseFloat to achieve this.

console.log(!isNaN(parseFloat("10000"))); // should return true
console.log(!isNaN(parseFloat("100T0"))); // should return false (but doesn't)

Turns out that parseFloat just stops reading a string as soon as it hits a character that's not a digit, then returns whatever it has passed over so far. So parseFloat("100T0") actually returns 100 and not NaN.

What's a better js test to see if a string can be cast as a float?

5 Answers 5

9

There's no one built-in operation provided by default in JavaScript that matches a reasonable "is this string a number" definition (to my mind, anyway). You can get close with Number, unary +, or implicit conversion (just passing the string into isNaN directly), with the caveat that they all do the same thing, which includes considering "" to be 0:

// Number
console.log(!isNaN(Number("10000"))); // true
console.log(!isNaN(Number("100T0"))); // false
console.log(!isNaN(Number("")));      // true (!)

// Same as implicit (here triggered with a unary +)
console.log(!isNaN(+"10000")); // true
console.log(!isNaN(+"100T0")); // false
console.log(!isNaN(+""));      // true (!)


// Same as implicit
console.log(!isNaN("10000")); // true
console.log(!isNaN("100T0")); // false
console.log(!isNaN(""));      // true (!)

My answer to a related question goes into your options in detail.

Consequently, you can either do a regular expression (be sure to allow for scientific notation!) or a check for "" up-front:

function toNumber(str) {
  str = String(str).trim();
  return !str ? NaN : Number(str);
}
console.log(!isNaN(toNumber("10000"))); // true
console.log(!isNaN(toNumber("100T0"))); // false
console.log(!isNaN(toNumber("")));      // false

Sign up to request clarification or add additional context in comments.

Comments

9

You won't get what you expect with parseFloat(), because it tries to parse 100T0 and returns 100, so it's a valid Number.

Instead of using isNaN() you can just use regex, to check if the given string is only composed of numbers.

This is the regex /^\-?[0-9]+(e[0-9]+)?(\.[0-9]+)?$/ you need, and this is how should be your code:

function isItNumber(str) {
  return /^\-?[0-9]+(e[0-9]+)?(\.[0-9]+)?$/.test(str);
}

Demo:

function isItNumber(str) {
  return /^\-?[0-9]+(e[0-9]+)?(\.[0-9]+)?$/.test(str);
}

console.log(isItNumber("10000")) // should return true
console.log(isItNumber("100T0"))
console.log(isItNumber("10e5"))
console.log(isItNumber("100.50"))

2 Comments

Although I did not note this in the question, it needs to handle decimal points
@rvictordelta I edited the answer, with an updated regex.
3

You could try with a regular expresion:

> (/^-?[\d]*(\.[\d]+)?$/g).test('0');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('1000');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('10E0');
false
> (/^-?[\d]*(\.[\d]+)?$/g).test('1000.E');
false
> (/^-?[\d]*(\.[\d]+)?$/g).test('1000.1');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('1.1000');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('.1000');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('1000.');
false
> (/^-?[\d]*(\.[\d]+)?$/g).test('-.1');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('-1000.1');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('-1000');
true

With a function:

function isValidFloat(str) {
    return (/^-?[\d]*(\.[\d]+)?$/g).test(str);
}

Comments

0

You can try a regex to match only float format strings. Hope this helps.

const reg = /^-?([0-9]+\.[0-9]+)$/g;

console.log("Should match");
console.log("123.2".match(reg));
console.log("12.000".match(reg));
console.log("-12.000".match(reg));

console.log("Should not match");
console.log("123".match(reg));
console.log("123a123".match(reg));
console.log("1e2".match(reg));

Comments

0

Another idea in psuedocode

1) Loop through string substrings (imitating parseFloat)
2) Get the substring that parseFloat stops at
3) Compare this substring to the original

Old psuedocode - does not work totally - maybe with modifications

What you can do is this (psuedocode)

if (parseFloat (value)).toString() <> value then
   you know that the parse float only converted part of the value

Basically you are saying that string > float > (back to) string should give the same string if the conversations work "correctly".

1 Comment

Agreed. Edit with a new approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.