How to prevent automatic number conversion in JavaScript - javascript

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

Related

Truncate a number

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.

Counting numbers after decimal point in JavaScript

I have a problem in JavaScript. Is it possible to check how many numbers are after the decimal point? I tried to do it using a.toString().split(".")[1]), but if there is no decimal point in the number, there is an error. What should I do if I want the system to do nothing if there is no decimal point?
You're on the right track. You can also .includes('.') to test if it contains a decimal along with .length to return the length of the decimal portion.
function decimalCount (number) {
// Convert to String
const numberAsString = number.toString();
// String Contains Decimal
if (numberAsString.includes('.')) {
return numberAsString.split('.')[1].length;
}
// String Does Not Contain Decimal
return 0;
}
console.log(decimalCount(1.123456789)) // 9
console.log(decimalCount(123456789)) // 0
Convert to a string, split on “.”, then when there is no “.” to split on, assume it’s empty string '' (the part you’re missing), then get said string’s length:
function numDigitsAfterDecimal(x) {
var afterDecimalStr = x.toString().split('.')[1] || ''
return afterDecimalStr.length
}
console.log(numDigitsAfterDecimal(1.23456))
console.log(numDigitsAfterDecimal(0))
You could check if no dot is available, then return zero, otherwise return the delta of the lenght and index with an adjustment.
function getDigits(v) {
var s = v.toString(),
i = s.indexOf('.') + 1;
return i && s.length - i;
}
console.log(getDigits(0));
console.log(getDigits(0.002));
console.log(getDigits(7.654321));
console.log(getDigits(1234567890.654321));
The condition you need is:
number.split('.')[1].length
It checks if there are any numbers after the dot which separates the number from its decimal part.
I'm not sure if you are able to use split on numbers though. If not, parse it to a string.
You first need to convert the decimal number to string and then get the count of character after decimal point,
var a = 10.4578;
var str = a.toString();
if(str){
var val = str.split('.');
if(val && val.length == 2){
alert('Length of number after decimal point is ', val[1].length);
} else {
alert('Not a decimal number');
}
}
The output is 4

parse integer with javascript using parseInt and a radix

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

Limit decimal places to specific situations (not round)

Im looking to limit a number do 2 decimal places, but only when the rest is zero. I dont want to round the numbers.
I tried using this example
(1.0000).toFixed(2)
the result would be 1.00, but if i have a number like (1.0030).toFixed(2), the result should be 1.003.
I tried using parseFloat with a combination of toFixed but doesn´t get the result i want.
Is there any function in javascript that does what im trying to achieve.
So you want a minimum of two decimals? Here's one way:
function toMinTwoDecimals(numString) {
var num = parseFloat(numString);
return num == num.toFixed(2) ? num.toFixed(2) : num.toString();
}
Examples:
toMinTwoDecimals("1.0030"); // returns "1.003"
toMinTwoDecimals("1.0000"); // returns "1.00"
toMinTwoDecimals("1"); // returns "1.00"
toMinTwoDecimals("-5.24342234"); // returns "-5.24342234"
In case you want to leave numbers with less than two decimals untouched, use this instead:
function toMinTwoDecimals(numString) {
var num = parseFloat(numString);
// Trim extra zeros for numbers with three or more
// significant decimals (e.g. "1.0030" => "1.003")
if (num != num.toFixed(2)) {
return num.toString();
}
// Leave numbers with zero or one decimal untouched
// (e.g. "5", "1.3")
if (numString === num.toFixed(0) || numString === num.toFixed(1)) {
return numString;
}
// Limit to two decimals for numbers with extra zeros
// (e.g. "1.0000" => "1.00", "1.1000000" => "1.10")
return num.toFixed(2);
}

Integer Comparison

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
}
}

Categories

Resources