2

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
8
  • 1
    parseInt will parse values up to the point it fails. EG parseInt("10px", 10) is 10. In this case A is 10 and S is invalid Commented Apr 27, 2017 at 16:11
  • "It asks me to parse a numberic string and convert it to a number" if (isNaN("ASD")) return -1 or if(!/\d/.test("ASD")) return -1 Commented Apr 27, 2017 at 16:11
  • But "ASD" is a valid number in bases over 29+ Commented Apr 27, 2017 at 16:13
  • @Nick The requirement is not to only checking for digit characters [0-9]? Commented Apr 27, 2017 at 16:14
  • No it's for all bases. So for example convert("AF", 16) returns 175 which is correct Commented Apr 27, 2017 at 16:15

3 Answers 3

1

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
}
Sign up to request clarification or add additional context in comments.

2 Comments

That did it! Thanks!!
Radix value should be no more then 36. If bigger then this code will break.
1

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.

1 Comment

Can we check which letters are allowed based on the radix? That will be the correct answer
1

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)); 

6 Comments

But "AAA" is valid with base 15. Your code fails the test.
You are right, this validation is no applicable for the none 10-base system, I am not sure if there is a function for it in JavaScript. In worst case you can define it yourself.
I have added a function to validate string per radix
You should probably should include up to 36 (max for parseInt)
No, it should be enough as it handles any radix up to HEX
|

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.