Reputation: 2907
I am doing an online test and it asks me to write basic javascript code.
It asks me to parse a numberic string and convert it to a number of a different base. It needs me to return -1 if for whatever reason the conversion cannot be done.
I have written this:
function convert(strNumber, radix) {
var result = parseInt(strNumber, radix);
if(isNaN(result))
{return -1;}
return result;
}
Then it runs my code through various tests and all pass. Except one.
Apparently convert("ASD", 15)
should be invalid according to the test and it expects it to be -1.
But Javascript happily converts it to number 10
I tried various things such as to add a try{}catch{} block and other things, but javascript never complains about converting "ASD" to base 15.
Is the test wrong, or is parseInt
wrong?
By the way strNumber can be any base under 36. So for instance:
convert("Z", 36) is 35
Upvotes: 2
Views: 940
Reputation: 7753
As per official documentation the parseInt
function behaves as following
For radices above 10, the letters of the alphabet indicate numerals greater than 9. For example, for hexadecimal numbers (base 16), A through F are used.
and
If parseInt encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters and returns the integer value parsed up to that point.
Thus to prevent invalid arguments from being parsed they have to be validated first
function convert(strNumber, radix) {
if (isValidRadix(radix) && isValidInteger(strNumber, radix))
return parseInt(strNumber, radix);
return -1;
}
function isValidInteger(str, radix) {
var letters = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'].slice(0,radix);
str = str.toUpperCase();
for (var i=0; i<str.length; i++) {
var s = str.charAt(i);
if (letters.indexOf(s) == -1) return false;
}
return true;
}
function isValidRadix(radix) {
// 16 up to HEX system
return radix > 0 && radix <= 16;
}
console.log(convert("ASD", 15));
console.log(parseInt("ASD", 15));
console.log(convert("AAA", 15));
Upvotes: 1
Reputation: 207521
As I stated in the comment, parseInt will convert up to the point where it fails. So "A" is valid in that radix and "S" is not. So you would need to add a check.
var nums = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".substr(0, radix)
var re = new RegExp("^[" + nums + "]+$","i")
if (!re.test(strNumber)) {
return -1
}
Upvotes: 1
Reputation: 3109
parseInt
is behaving normally and is converting the letter A
into 10 in base 15 (similar to how hex uses A
for the number 10). The S
and D
are discarded, as parseInt
accepts this type of malformed input.
From the parseInt
documentation:
If
parseInt
encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters and returns the integer value parsed up to that point.
Upvotes: 1