Recursion "maximum call stack size exceeded" - decimal to hexadecimal converter - javascript

I'm trying to make a decimal to hexadecimal converter without using Number.prototype.toString (this is an assignment which does not allow that function). I am attempting to use recursion to try to work it. Everything works until the else inside the main else if that makes any sense. It gives me that error when I run it for any number above 255 (i.e. any number which has more than 2 digits in hexadecimal). Does anyone know why this is the case?
var number = parseInt(prompt("Give me a number and I will turn it into hexadecimal!"));
var digit = 1;
var hexConverter = function () {
if (digit === 1) {
if (Math.floor(number / 16) === 0) {
console.log(hexDigits[number]);
} else {
digit = 16;
console.log(hexConverter(), hexDigits[number % 16]);
}
} else {
if (Math.floor(number / (digit * 16)) === 0) {
return (hexDigits[Math.floor(number / digit)]);
} else {
return (hexConverter(), hexDigits[number % (digit * 16)]);
}
digit = digit * 16;
}
};
hexConverter();

You are changing digit after making the recursive call, so it will be stuck at 16 and never get to the point where you increase it.
Move the digit = digit*16; to before the recursive call, just as you have digit = 16 in the first part.

function toHex(x) {
var res='',h;
while (x) {
res=(((h=x&15)<10)? h : String.fromCharCode(55+h)) + res;
x>>=4;
}
return res;
}
Would work quite fine.
Question to you : why only 'quite' ? :-)

Related

How do multiple else if statements work in Javascript? [duplicate]

I want to check if a value is in an accepted range. If yes, to do something; otherwise, something else.
The range is 0.001-0.009. I know how to use multiple if to check this, but I want to know if there is any way to check it in a single if statement.
You're asking a question about numeric comparisons, so regular expressions really have nothing to do with the issue. You don't need "multiple if" statements to do it, either:
if (x >= 0.001 && x <= 0.009) {
// something
}
You could write yourself a "between()" function:
function between(x, min, max) {
return x >= min && x <= max;
}
// ...
if (between(x, 0.001, 0.009)) {
// something
}
Here is an option with only a single comparison.
// return true if in range, otherwise false
function inRange(x, min, max) {
return ((x-min)*(x-max) <= 0);
}
console.log(inRange(5, 1, 10)); // true
console.log(inRange(-5, 1, 10)); // false
console.log(inRange(20, 1, 10)); // false
If you must use a regexp (and really, you shouldn't!) this will work:
/^0\.00([1-8]\d*|90*)$/
should work, i.e.
^ nothing before,
followed by 0.00 (nb: backslash escape for the . character)
followed by 1 through 8, and any number of additional digits
or 9, followed by any number of zeroes
$: followed by nothing else
If you're already using lodash, you could use the inRange() function:
https://lodash.com/docs/4.17.15#inRange
_.inRange(3, 2, 4);
// => true
_.inRange(4, 8);
// => true
_.inRange(4, 2);
// => false
_.inRange(2, 2);
// => false
_.inRange(1.2, 2);
// => true
_.inRange(5.2, 4);
// => false
_.inRange(-3, -2, -6);
// => true
I like Pointy's between function so I wrote a similar one that worked well for my scenario.
/**
* Checks if an integer is within ±x another integer.
* #param {int} op - The integer in question
* #param {int} target - The integer to compare to
* #param {int} range - the range ±
*/
function nearInt(op, target, range) {
return op < target + range && op > target - range;
}
so if you wanted to see if x was within ±10 of y:
var x = 100;
var y = 115;
nearInt(x,y,10) = false
I'm using it for detecting a long-press on mobile:
//make sure they haven't moved too much during long press.
if (!nearInt(Last.x,Start.x,5) || !nearInt(Last.y, Start.y,5)) clearTimeout(t);
If you want your code to pick a specific range of digits, be sure to use the && operator instead of the ||.
if (x >= 4 && x <= 9) {
// do something
} else {
// do something else
}
// be sure not to do this
if (x >= 4 || x <= 9) {
// do something
} else {
// do something else
}
You must want to determine the lower and upper bound before writing the condition
function between(value,first,last) {
let lower = Math.min(first,last) , upper = Math.max(first,last);
return value >= lower && value <= upper ;
}
const inRange = (num, num1, num2) => Math.min(num1, num2) <= num && Math.max(num1, num2) >= num;
Could be like this if you want to make inRange inclusive and not depend on order of range numbers (num1, num2).

Check Odd numbers without modulo operator

I am creating a function that returns whether the passed in number is odd Without the modulo operator. The tricky part is that it should work for NEGATIVE numbers and ZERO.
here's my codes so far:
function testodd(num) {
return (num/2)*2==num;
}
var output = testodd(17);
console.log(output); // --> true
Am I making some mistakes here? Or is there a better way to do this?
you can use Bitwise operator and get same result. does this help.
<script type="text/javascript">
function oddOrEven(x) {
return ( x & 1 ) ? "odd" : "even";
}
console.log(oddOrEven(10));
</script>
For more detail about bitwise operator
Hi you can do it with bitwise AND (&) operator to check if a number is even or odd.
function testodd(num) {
if((num & 1) == 0){
return true
}
return false;
}
var output = testodd(17);
console.log(output); // --> false
var output = testodd(-16);
console.log(output); // --> true
var output = testodd(0);
console.log(output); // --> true
Try a bit-wise operation
function testodd(num) {
return num & 1; // num AND 0x1 checks for the least significant bit, indicating true or falsey
}
Remove the decimal part after division using Math.floor.
Math.floor(num / 2) * 2 === num;
For even numbers, there is no loss in decimal value. For odd numbers, decimal point value will be lost and comparison will falsy.
Here is a horribly inefficient method using recursion:
function checkOdd(num)
{
num = Math.abs(num);
if(num==0)
return false;
else if(num==1)
return true;
else
return checkOdd(num-2);
}
Of course you should never use it.
Since there's already an answer I will show you an alternative away of doing it with regex
function checkOdd(num){
console.log(/^\d*[13579]$/.test(num));
}
checkOdd(105);
Would only work with reasonably sized integers
Try
function testodd(num){
if num < 0{
var number = -num
}
int i = 1;
int product = 0;
while (product <= num)
{
product = divisor * i;
i++;
}
// return remainder
return num - (product - divisor);
}
Use this function to check if a number is odd or even, without using the modulo operator %. This should work for negative numbers and zero.
function checkOdd(num) {
// your code here
if(num<0){ //Check if number is negative
num=-num; //Convert it into positive number
}
let b=Math.floor(num/2) //Taking value for loop iteration
for(var i=1;i<=b;i++){
num=num-2; //Will check the number is odd if it subtraction end to 1 by decrementing -2 to the number
if(num==1){
return true; //return true if number is odd
}
}
return false; //return false if number is even
}
You can use isInteger method
function isEven(n){
return Number.isInteger(n / 2);
}
function odd(num) {
if (num === 0) {
return false;
}
num = Math.abs(num);
while (num >= 2) {
num = num - 2;
}
if (num === 1) {
return true;
} else {
return false;
}
}
Even number
lets take an even number say 6;
6 divided by 2 is 3;
Math.round(3) is 3;
Math.floor(3) is 3;
3===3 eveluates to true so 6 is an even number;
Odd number
lets take an odd number say 9;
9 divided by 2 is 4.5;
Math.round(4.5) is 5;
Math.floor(4.5) is 4;
5===4 evaluates to false so 9 is an odd number;
function evenChecked(num) {
if (Math.round(num / 2) === Math.floor(num / 2)) {
return `${num} is even`;
} else {
return `${num} is odd`;
}
}
console.log(evenChecked(23));
console.log(evenChecked(90));
console.log(evenChecked(56));
console.log(evenChecked(49));

Javascript Function defaulting to wrong answer (I think)

Hi can somebody tell me why the output to my function defaults to even when you insert over 17 numbers? It's probably super simple, please go easy on me!
function oddOrEven(number) {
var number = document.getElementById('number').value;
if(number % 2 != 0) {
document.getElementById('demo').innerHTML = "Odd";
}
else {
document.getElementById('demo').innerHTML = "Even";
}
if (number.length === 0) {
document.getElementById('demo').innerHTML = "Odd / Even";
}
}
You can simplify this whole thing. If you are always grabbing the input with id 'number' you don't need to pass a param, and then after a simple test you can inline the answer you want:
function oddOrEven(){
var val = document.getElementById('number').value;
var number = parseInt(val, 10);
// if it's not a valid number, you'll have NaN here which is falsy
if (number) {
document.getElementById('demo').innerHTML = (number % 2) ? "Even" : "Odd";
}
}
All that said, I just caught that you're talking about 17 digits (thanks to #JJJ's comment) rather than using the function more than once. The problem in this case is that JS integers have a size limit. If you parse anything larger it returns a number you're not going to expect. There are a lot of discussion of general handling of very large numbers here: http://2ality.com/2012/07/large-integers.html, but for your modulus problem you could take the last digit and check if that's odd or even like so:
function oddOrEven(){
var val = document.getElementById('number').value;
var number = parseInt(val, 10);
// if it's not a valid number, you'll have NaN here which is falsy
if (number) {
var lastDigit = val[val.length-1];
document.getElementById('demo').innerHTML = (parseInt(lastDigit, 10) % 2) ? "Even" : "Odd";
}
}

Reduce a multi-digit to one-digit -guidance not answer please

goal: take a number like 54321, add the numbers together (5+4+3+2+1 = 15), then take that number (15) add the digits (1+5 = 6), so return 6;
here is my code:
function digital_root(n) {
if (n >=10) {
var digits = n.toString().split('').map(function(item, index) {return parseInt(item)}).reduce(function(a,b){ return a+b});
console.log(digits);
}
}
digital_root(1632)
Can't figure out: How to get that function to repeat over and over until digits is just one number (i.e. less than 10). I have tried a variety of nested functions, but can't seem to get it right.
If possible please point me in the direction to the solution ("try a nesting in a while... or read up on..."), but don't give me the complete code solution ("Use this code chunk:...."). I've developed a bad habit of just reading and copying...
Thank you!
Try this: reference HERE
function digital_root(n) {
var singlesum = 0;
while (n >= 10 ) {
singlesum=0;
while (n > 0) {
var rem;
rem = n % 10;
singlesum = singlesum + rem;
n = parseInt(n / 10);
}
n = singlesum;
}
console.log(singlesum);
}
digital_root(1632)
You can use recursion to solve this.
Write a function makeSingleDigit, which argument will be your number.
You need a base condition with the base step, which in your case stops the recursion when received number is one-digit and returns the number.
If condition is not true, you just need to get another digit from the number by n%10 and sum it with the makeSingleDigit(Math.floor(n/10)). By this, you repeatedly sum digits of new numbers, until function receives one-digit number.
Mathematical solution just for your information: the number, which you want to find is n % 9 === 0 ? 9 : n % 9, thus it is the remainder of the division by 9 if it is not 0, otherwise it is 9.
Here is a very optimal solution to the problem:
function digital_root(n) {
return (n - 1) % 9 + 1;
}
const result = digital_root(1632);
console.log(result);
Well, not a very good solution but you can give a hit.
function digital_root(n) {
if (n >=10) {
var digits = n.toString().split('').map(function(item, index) {return parseInt(item)}).reduce(function(a,b){ return a+b});
console.log(digits);
return(digits);
}
}
var num = 1632;
do{
num = digital_root(num);
}while(num>10);

how to write javascript code to get three significant digit after decimal

I have a requirement to format a no to get 3 significant digit after a decimal in javascript..
detail about the significant digit can be found here http://www.usca.edu/chemistry/genchem/sigfig.htm
here are the rule for significant digit
1) ALL non-zero numbers (1,2,3,4,5,6,7,8,9) are ALWAYS significant.
2) ALL zeroes between non-zero numbers are ALWAYS significant.
3) ALL zeroes which are SIMULTANEOUSLY to the right of the decimal point AND at
the end of the number are ALWAYS significant.
4) ALL zeroes which are to the left of a written decimal point and are in a number >= 10 are ALWAYS significant.
i want function like
function significantDigit(no, noOfDecimal)
{
return signifcantNo
}
Example of significant digits.
48,923 has five significant digit..significantDigit(no,3) should return 48923
3.967 has four significant digit..significantDigit(no,3) should return 3.967
0.00104009 has six significant digit,..significantDigit(no,3) should return .00104
hope this helps
var anumber=123.45
anumber.toPrecision(6) //returns 123.450 (padding)
anumber.toPrecision(4) //returns 123.5 (round up)
anumber.toPrecision(2) //returns 1.2e+2 (you figure it out!)
thanks for the edited question
this one ll solve your requirement
var anumber = 123.4050877
var str = anumber.toPrecision(6)
var a = [];
a= JSON.parse("[" + str + "]");
alert(a.length)
for(var i=6;i<=a.length;i--){
if(a[i]=="0"){
a.splice(i, 1);
}
}
alert(a)
i have found a java code here thanks to Pyrolistical
Rounding to an arbitrary number of significant digits
public static double roundToSignificantFigures(double num, int n) {
if(num == 0) {
return 0;
}
final double d = Math.ceil(Math.log10(num < 0 ? -num: num));
final int power = n - (int) d;
final double magnitude = Math.pow(10, power);
final long shifted = Math.round(num*magnitude);
return shifted/magnitude;}
i have converted this to a javascript code, this can be found at http://jsfiddle.net/f6hdvLjb/4/
javascript code is
function roundToSignificantFigures(num, n) {
if(num === 0) {
return 0;
}
var d = Math.ceil(Math.log10(num < 0 ? -num: num));
var power = n - parseInt(d);
var magnitude = Math.pow(10, power);
var shifted = Math.round(num*magnitude);
alert(shifted/magnitude);
return shifted/magnitude;
}
roundToSignificantFigures(6666666.0412222919999,3);
i think this is what the significant digit logic.
this may not be the complete solution..but its correct to the most extent (i think) it works really great for very big decimal no..this will give you most significant digit after decimal
function signiDigit(val, noOfdecimalPoint) {
debugger;
var noString = String(val);
var splitNo = noString.split(".");
if (splitNo.length > 1) {
if(parseInt(splitNo[0])!==0 ||splitNo[0]==='' )
{
if(noString.length - 1 > noOfdecimalPoint)
{
return Math.round(val);
}else
{
return val;
}
}else
{
var noafterDecimal =String(parseInt(splitNo[1]));
if(noafterDecimal.length > noOfdecimalPoint)
{
return parseFloat(val.toFixed(splitNo[1].indexOf(noafterDecimal) + noafterDecimal.length-1));
}
else{
return val;
}
}
}}
var no = signiDigit(9.999,3);
alert(no);
here is the fiddeler link http://jsfiddle.net/n1gt4k90/4/
this is not the complete significant no but mix of significant and rounding.

Categories