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
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
}
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.
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));
Related
I want to call a function parsing a number with some zeros at the left to string. But JavaScript is automatically changing the number base.
This is what I'm trying to do:
function printNum(num) {
return num.toString()
}
console.log(printNum(00000100010))
//32776
console.log(printNum(0555))
//365
I'm expecting "100010" or "00000100010" and "555" or "0555". Is that possible?
Because of how JavaScript works, a number that starts with 0 is base 8 if it only contains digits 0-7 (except for 0x, 0b, and 0o, bases 16, 2, and 8, respectively, which throw SyntaxErrors for invalid characters), otherwise it silently uses the decimal number with the zeros at the beginning chopped off. You can't change that, that's just the specification.
If you're wanting to preserve the zeros, the simple way is to just pass in a string originally.
function printNum(num) {
return num.toString()
}
console.log(printNum("00000100010"))
//00000100010
console.log(printNum("0555"))
//0555
You can also define your function to take in a length to pad 0's to or a number of zeros to pad at the start.
function printNum(num, minLength) {
return num.toString().padStart(minLength, "0");
}
console.log(printNum(100010, 11))
//00000100010
console.log(printNum(555, 4))
//0555
function printNum(num, prefixLength) {
return "0".repeat(prefixLength) + num.toString()
}
console.log(printNum(100010, 5))
//00000100010
console.log(printNum(555, 1))
//0555
function truncDigits(inputNumber, digits) {
const fact = 10 ** digits;
return Math.trunc(inputNumber * fact) / fact;
}
truncDigits(27624.399999999998,2) //27624.4 but I want 27624.39
I need to truncate a float value but don't wanna round it off. For example
27624.399999999998 // 27624.39 expected result
Also Math.trunc gives the integer part right but when you Math.trunc value 2762439.99 it does not give the integer part but gives the round off value i.e 2762434
Probably a naive way to do it:
function truncDigits(inputNumber, digits) {
return +inputNumber.toString().split('.').map((v,i) => i ? v.slice(0, digits) : v).join('.');
}
console.log(truncDigits(27624.399999999998,2))
At least it does what you asked though
Try this:
function truncDigits(inputNumber, digits){
return parseFloat((inputNumber).toFixed(digits));
}
truncDigits(27624.399999999998,2)
Your inputs are number (if you are using typescript). The method toFixed(n) truncates your number in a maximum of n digits after the decimal point and returns it as a string. Then you convert this with parseFloat and you have your number.
You can try to convert to a string and then use a RegExp to extract the required decimals
function truncDigits(inputNumber: number, digits: number) {
const match = inputNumber.toString().match(new RegExp(`^\\d+\\.[\\d]{0,${digits}}`))
if (!match) {
return inputNumber
}
return parseFloat(match[0])
}
Note: I'm using the string version of the RegExp ctor as the literal one doesn't allow for dynamic params.
I m getting two textboxes value as 5 and 10.
so i m validating them on the following if condition
var textboxvalue1 = $('#textboxvalue1' + counter).val();
var textboxvalue2 = $('#textboxvalue2' + counter).val();
if (textboxvalue1 < textboxvalue2) {
alert("error");
}
textboxvalue1 = 10
textboxvalue2 = 5
its showing an alert in this case.which it shud nt show.bt when textboxvalue1 is less than 10,it works fine.
Actually your .val() returns string you try to convert it as integer so use parseInt() in your context and check.
The parseInt() function parses a string and returns an integer.
Note:
The radix parameter is used to specify which numeral system to be
used, for example, a radix of 16 (hexadecimal) indicates that the
number in the string should be parsed from a hexadecimal number to a
decimal number.
If the radix parameter is omitted, JavaScript assumes the following:
If the string begins with "0x", the radix is 16 (hexadecimal) If the
string begins with "0", the radix is 8 (octal). This feature is
deprecated If the string begins with any other value, the radix is 10
(decimal)
var textboxvalue1= parseInt($('#textboxvalue1'+counter).val(), 10);
var textboxvalue2= parseInt($('#textboxvalue2'+counter).val(), 10);
if (textboxvalue1 < textboxvalue2) {
alert("error");
}
You have to convert your input strings to numbers like this:
var textboxvalue1=parseInt($('#textboxvalue1'+counter).val());
var textboxvalue2=parseInt($('#textboxvalue2'+counter).val());
The values are being interpreted as strings by JavaScript, not numbers. Wrap them in parseInt or parseFloat before comparing them.
Use ParseInt Because var return string default. Or you can use parseFloat
var textboxvalue1= parseInt($('#textboxvalue1'+counter).val(), 10);
var textboxvalue2= parseInt($('#textboxvalue2'+counter).val(), 10);
if (textboxvalue1 < textboxvalue2) {
alert("error");
}
I need to compare two Integers which could exceed Integer range limit. How do I get this in javascript.
Initially, I get the value as String, do a parseInt and compare them.
var test = document.getElementById("test").value;
var actual = document.getElementById("actual").value;
if ( parseInt(test) == parseInt(actual)){
return false;
}
Any options to use long ? Also, which is best to use parseInt or valueOf ??
Any suggestions appreciated,
Thanks
You'd better to assign the radix. Ex. parseInt('08') will give 0 not 8.
if (parseInt(test, 10) === parseInt(actual, 10)) {
Leave them in String and compare (after you have cleaned up the string of leading and trailing spaces, and other characters that you consider safe to remove without changing the meaning of the number).
The numbers in Javascript can go up to 53-bit precision. Check whether your number is within range.
Since the input is expected to be integer, you can be strict and only allow the input to only match the regex:
/\s*0*([1-9]\d*|0)\s*/
(Arbitrary leading spaces, arbitrary number of leading 0's, sequence of meaningful digits or single 0, arbitrary trailing spaces)
The number can be extract from the first capturing group.
Assuming integers and that you've already validated for non-numeric characters that you don't want to be part of the comparison, you can clean up some leading/trailing stuff and then just compare lengths and if lengths are equal, then do a plain ascii comparison and this will work for any arbitrary length of number:
function mTrim(val) {
var temp = val.replace(/^[\s0]+/, "").replace(/\s+$/, "");
if (!temp) {
temp = "0";
}
return(temp);
}
var test = mTrim(document.getElementById("test").value);
var actual = mTrim(document.getElementById("actual").value);
if (test.length > actual.length) {
// test is greater than actual
} else if (test.length < actual.length) {
// test is less than actual
} else {
// do a plain ascii comparison of test and actual
if (test == actual) {
// values are the same
} else if (test > ascii) {
// test is greater than actual
} else {
// test is less than actual
}
}
I store some parameters client-side in HTML and then need to compare them as integers. Unfortunately I have come across a serious bug that I cannot explain. The bug seems to be that my JS reads parameters as strings rather than integers, causing my integer comparisons to fail.
I have generated a small example of the error, which I also can't explain. The following returns 'true' when run:
console.log("2" > "10")
Parse the string into an integer using parseInt:
javascript:alert(parseInt("2", 10)>parseInt("10", 10))
Checking that strings are integers is separate to comparing if one is greater or lesser than another. You should always compare number with number and string with string as the algorithm for dealing with mixed types not easy to remember.
'00100' < '1' // true
as they are both strings so only the first zero of '00100' is compared to '1' and because it's charCode is lower, it evaluates as lower.
However:
'00100' < 1 // false
as the RHS is a number, the LHS is converted to number before the comparision.
A simple integer check is:
function isInt(n) {
return /^[+-]?\d+$/.test(n);
}
It doesn't matter if n is a number or integer, it will be converted to a string before the test.
If you really care about performance, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
return function(n) {
return re.test(n);
}
}());
Noting that numbers like 1.0 will return false. If you want to count such numbers as integers too, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
var re2 = /\.0+$/;
return function(n) {
return re.test((''+ n).replace(re2,''));
}
}());
Once that test is passed, converting to number for comparison can use a number of methods. I don't like parseInt() because it will truncate floats to make them look like ints, so all the following will be "equal":
parseInt(2.9) == parseInt('002',10) == parseInt('2wewe')
and so on.
Once numbers are tested as integers, you can use the unary + operator to convert them to numbers in the comparision:
if (isInt(a) && isInt(b)) {
if (+a < +b) {
// a and b are integers and a is less than b
}
}
Other methods are:
Number(a); // liked by some because it's clear what is happening
a * 1 // Not really obvious but it works, I don't like it
Comparing Numbers to String Equivalents Without Using parseInt
console.log(Number('2') > Number('10'));
console.log( ('2'/1) > ('10'/1) );
var item = { id: 998 }, id = '998';
var isEqual = (item.id.toString() === id.toString());
isEqual;
use parseInt and compare like below:
javascript:alert(parseInt("2")>parseInt("10"))
Always remember when we compare two strings.
the comparison happens on chacracter basis.
so '2' > '12' is true because the comparison will happen as
'2' > '1' and in alphabetical way '2' is always greater than '1' as unicode.
SO it will comeout true.
I hope this helps.
You can use Number() function also since it converts the object argument to a number that represents the object's value.
Eg: javascript:alert( Number("2") > Number("10"))
+ operator will coerce the string to a number.
console.log( +"2" > +"10" )
The answer is simple. Just divide string by 1.
Examples:
"2" > "10" - true
but
"2"/1 > "10"/1 - false
Also you can check if string value really is number:
!isNaN("1"/1) - true (number)
!isNaN("1a"/1) - false (string)
!isNaN("01"/1) - true (number)
!isNaN(" 1"/1) - true (number)
!isNaN(" 1abc"/1) - false (string)
But
!isNaN(""/1) - true (but string)
Solution
number !== "" && !isNaN(number/1)
The alert() wants to display a string, so it will interpret "2">"10" as a string.
Use the following:
var greater = parseInt("2") > parseInt("10");
alert("Is greater than? " + greater);
var less = parseInt("2") < parseInt("10");
alert("Is less than? " + less);