How to count digits of given number? - javascript

I want the user to enter a number and print back the amount of digits of that number.
I know that I can use length, but my homework asking for while loop.
This is what I have so far:
var num;
var count = 0;
num = prompt('Enter number: ');
function counter(x, y) {
while (x > 0) {
y++;
x /= 10;
}
return y;
}
var result = counter(num, count);
console.log(result);
When I give the number 3456 (example), I get back the number 328. I want it to print back the number 4.

This line:
x /= 10;
Should be changed to:
x = Math.floor(x / 10);
The logic assumes integer division: 1234 is supposed to become 123, 12, 1 and 0. JavaScript does not have built in integer division so you need to use Math.floor to emulate it. Complete example with some fixes:
function countDigits(num) {
var count = 0;
while (num > 0) {
num = Math.floor(num / 10);
count++;
}
return count;
}
var num;
do {
num = Number(prompt("Enter number:"));
} while (Number.isNaN(num));
num = Math.abs(num); // just in case you want to handle -ve numbers
var result = countDigits(num);
console.log(result);

The problem is that the division operation will eventually end up converting x to a float and you'll have something like:
x / 10 === 0.1;
x / 10 === 0.01;
x / 10 === 0.001;
....
if you always parse (round) the result of the division to an integer, you'll get the expected result.
var num;
var count = 0;
num = prompt('Enter number: ');
function counter(x, y) {
while (x > 0) {
y++;
x = parseInt(x / 10);
}
return y;
}
var result = counter(num, count);
console.log(result);

You could check againt a number by taking the power of a decimal count.
function counter(value) {
var decimals = 0;
do {
decimals++;
} while (value >= 10 ** decimals)
return decimals;
}
console.log(counter(0));
console.log(counter(1));
console.log(counter(7));
console.log(counter(42));
console.log(counter(999));
console.log(counter(1000));
console.log(counter(1001));

First of all you should convert the input into a number, preferably using the Number function (using unary + has the same effect).
Secondly a division like 5 / 10 will return 0.5 which is bigger than 0. You should instead check if the number is bigger than or equal to 1.
function counter(num) {
num = Math.abs(num) / 10;
var count = 1;
while (num >= 1) {
count++;
num /= 10;
}
return count;
}
console.log(counter(+prompt('Enter number: ')));
You could also use a do while loop and avoid having an extra division outside the loop.

As others have pointed out, y doesn't need to be a parameter, it can be a local variable. But that's not your problem; let's add some extra logging to your loop:
function counter(x) {
let y=0;
while (x > 0) {
console.log("x=" + x + ", y=" + y);
y++;
x /= 10;
}
return y;
}
counter(3456);
The output looks like this:
x=3456, y=0
x=345.6, y=1
x=34.56, y=2
x=3.4560000000000004, y=3
x=0.3456, y=4
x=0.03456, y=5
...
You wanted the loop to stop at 0.3456, but that's still more than 0. (This mistake actually gives you a chance to learn something extra: can you explain why the loop ever finishes at all?)
Hopefully this will give you enough of a hint to complete the homework assignment - remember that debugging is an extremely important part of programming.

Please don't use cycles to measure length of an integer...
Use math instead! Logarithm will do much better job for you.
function numberLength(number) {
return Math.floor(Math.log10(Math.abs(number))) + 1
}
console.log(numberLength(YOUR_NUMBER));
This code returns NaN when the input is 0. I think it depends on your philosophy what length the 0 should have, so I am leaving that case unhandled.

Related

Rounding-off from whole numbers to whole numbers in JavaScript?

So I have some numbers x = 320232 y = 2301 z = 12020305. I want to round these numbers off using JavaScript so that they become x = 320000 y = 2300 z = 12000000.
I tried Math.round and Math.floor but turns out that they only work with decimal values like
a = 3.1; Math.round(a); // Outputs 3 and not whole numbers.
So my question is can we round of whole numbers using JavaScript and If yes then how?
Edit: I want it to the round of to the starting 3 digit places as seen in the variables above. Like If there was another variable called c = 423841 It should round off to become c = 424000.
You could work with the logarithm of ten and adjust the digits.
const
format = n => v => {
if (!v) return 0;
const l = Math.floor(Math.log10(Math.abs(v))) - n + 1;
return Math.round(v / 10 ** l) * 10 ** l;
};
console.log([0, -9876, 320232, 2301, 12020305, 123456789].map(format(3)));
The solution is to first calculate how many numbers need to be rounded away, and then use that in a round.
Math.round(1234/100)*100 would round to 1200 so we can use this to round. We then only need to determan what to replace 100 with in this example.
That is that would be a 1 followed by LENGTH - 3 zeros. That number can be calculated as it is 10 to the power of LENGTH - 3, in JS: 10 ** (length - 3).
var x = 320232;
var y = 2301;
var z = 12020305;
function my_round(number){
var org_number = number;
// calculate integer number
var count = 0;
if (number >= 1) ++count;
while (number / 10 >= 1) {
number /= 10;
++count;
}
// length - 3
count = Math.round(count) - 3;
if (count < 0){
count = 0;
}
// 10 to the power of (length - 3)
var helper = 10 ** count;
return Math.round(org_number/helper)*helper;
}
alert(my_round(x));
alert(my_round(y));
alert(my_round(z));
It is not the prettiest code, though I tried to make it explainable code.
This should work:
function roundToNthPlace(input, n) {
let powerOfTen = 10 ** n
return Math.round(input/powerOfTen) * powerOfTen;
}
console.log([320232, 2301,12020305, 423841].map(input => roundToNthPlace(input, 3)));
Output: [320000, 2000, 12020000, 424000]

How do i create a function, which takes one parameter - a number, and returns the sum of numbers from 1 -> number - without creating an infinite loop?

How do i create a function, which takes one parameter - a number, and returns the sum of numbers from 1 -> number - without creating an infinite loop?
Example:
function(100)
= 5050
Ive come as far as creating a finite for loop as so:
let sum = 0
for (let i = 1; i <= 100; i++) {
sum = sum + i;
//thanks in advance
Well, it looks like you've got the basic premise sussed out for 1 to 100 - you're cycling through to the value and summing up. To put it into a bit of a nicer format:
const n = 100;
console.log(GetSumTo(n))
function GetSumTo(x) {
var sum = 0;
for (var i = 1; i <= x; i++) {
sum = sum + i;
}
return sum;
}
Another option would be do it recursively:
const n = 100;
console.log(RecursiveSum(n, 0));
function RecursiveSum(val, sum) {
if (val > 1) {
sum = val + RecursiveSum(val - 1, sum);
}
else {
sum = val;
}
return sum;
}
However, these can be time consuming when dealing with large values. Using a fancy bit of maths (explained here better than I can explain it: https://math.stackexchange.com/questions/1100897/sum-of-consecutive-numbers), we can find that the sum of consecutive numbers can be calculated with an easier formula: (n(n + 1))/2
Meaning we can just write a function to do that and save execution time:
const n = 100;
console.log(QuickSum(n));
function QuickSum(n) {
var sum = n + 1;
sum = sum * n;
sum = sum / 2; //You could shrink the calculation to sum = (n * (n + 1)) / 2 I just did it over a few lines for readability
return sum;
};
None of these options result in an infinite loop.

Round to the next whole number javascript

I want to achieve something like this in JavaScript:
input = 2455.55
f(input) = 2456
f(input) = 2460
f(input) = 2500
f(input) = 3000
f(input) = 2455.55
I am using the Math.round() method for now but only get to 2,546 with it. Wondering if there is a best way to achieve the rest.
You can divide your number by ten until you get a non-integer, round it up and then multiply by ten again the same amount of time. Something like this:
function roundUp(n) {
var n2 = n;
var i=0;
while (Number.isInteger(n2)) {
n2 /= 10;
i++;
}
return Math.round(n2) * Math.pow(10, i);
}
console.log(roundUp(2455.55)); // 2456
console.log(roundUp(2456)); // 2460
console.log(roundUp(2460)); // 2500
console.log(roundUp(2500)); // 3000
Based on your desired output it looks like you need to track the number of function calls. This doesn't seem to be an argument to your function.
Given the constraint that you have only a single argument, the implementation looks probably like
var lastNum = 0
var digitsToRound = 0
function roundUp(input) {
// Verify whether the function is called with the same argument as last call.
// Note that we cannot compare floating point numbers.
// See https://dev.to/alldanielscott/how-to-compare-numbers-correctly-in-javascript-1l4i
if (Math.abs(input - lastNum) < Number.EPSILON) {
// If the number of digitsToRound exceeds the number of digits in the input we want
// to reset the number of digitsToRound. Otherwise we increase the digitsToRound.
if (digitsToRound > (Math.log10(input) - 1)) {
digitsToRound = 0;
} else {
digitsToRound = digitsToRound + 1;
}
} else {
// The function was called with a new input, we reset the digitsToRound
digitsToRound = 0;
lastNum = input;
}
// Compute the factor by which we need to divide and multiply to round the input
// as desired.
var factor = Math.max(1, Math.pow(10, digitsToRound));
return Math.ceil(input / factor) * factor;
}
console.log(roundUp(2455.55)); // 2456
console.log(roundUp(2455.55)); // 2460
console.log(roundUp(2455.55)); // 2500
console.log(roundUp(2455.55)); // 3000
thanks, nice one! Inspired by your answer, I solved it like so:
function roundNumber(num, n) {
const divider = Math.pow(10, n);
return Math.round(num / divider) * divider;
};

Need help writing code to convert decimal to binary without the use of the toString

I'm trying to create my own decimal to binary converter with the method of decrementing the inputted variable (decimal value), by dividing it by 2 and storing the remainder (like 2nd grade math remainder), which is always either 0 or 1. Each of the remainder values i thin should be stored in an array and I think maybe put in backwards so that the most significant digit is first in the array (this is because when decrementing the remainer values are filled in left to right). Soooo yea i dont really know how to store the remainder values in an array using a function
Thanks in advance and if something is confusing then feel free to ask because im not even sure if this is the best method of doing this its just what i came up with
function decimalToBinary(num) {
var bin = 0;
while (num > 0) {
bin = num % 2 + bin;
num >>= 1; // basically /= 2 without remainder if any
}
alert("That decimal in binary is " + bin);
}
Your code is almost correct. The main problem is that bin starts out as 0; when you add a digit, they are added numerically, so your code ends up just counting the binary 1s: in this manner, 10 is initial 0, and +1+0+1+0, resulting in 2. You want to handle it as a string: ""+1+0+1+0 results in 1010. So, the only needed change is:
var bin = "";
If you want to solve it using arrays, with minimal changes to your code, it would be:
function decimalToBinary(num) {
var bin = [];
while (num > 0) {
bin.unshift(num % 2);
num >>= 1; // basically /= 2 without remainder if any
}
alert("That decimal in binary is " + bin.join(''));
}
Here, I use .unshift to add an element to the head of the array (and renumbering the remaining elements); .join() to collect them all into a string.
Or this:
function decimalToBinary(num) {
var bin = [];
while (num > 0) {
bin[bin.length] = num % 2;
num >>= 1; // basically /= 2 without remainder if any
}
alert("That decimal in binary is " + bin.reverse().join(''));
}
This is not as good, but illustrates some more things you can do with arrays: taking their length, setting an arbitrary element, and flipping them around.
I have written a custom Decimal to Binary method:
function toBinary (input) {
let options = [1];
let max = 0;
let i = 1;
while(i) {
max = Math.pow(2, i);
if (max > input) break;
options.push(max);
i++;
}
let j = options.length;
let result = new Array(j);
result.fill("0");
while(j >= 0) {
if (options[j] <= input) {
result[j] = "1"
input = input - options[j];
}
j--;
}
return [...result].reverse().join("");
}
//Test the toBin method with built-in toString(2)
toBinary(100) === (100).toString(2) // true
toBinary(1) === (1).toString(2) // true
toBinary(128) === (128).toString(2) // true

Round number up to the nearest multiple of 3

How would I go about rounded a number up the nearest multiple of 3?
i.e.
25 would return 27
1 would return 3
0 would return 3
6 would return 6
if(n > 0)
return Math.ceil(n/3.0) * 3;
else if( n < 0)
return Math.floor(n/3.0) * 3;
else
return 3;
Simply:
3.0*Math.ceil(n/3.0)
?
Here you are!
Number.prototype.roundTo = function(num) {
var resto = this%num;
if (resto <= (num/2)) {
return this-resto;
} else {
return this+num-resto;
}
}
Examples:
y = 236.32;
x = y.roundTo(10);
// results in x = 240
y = 236.32;
x = y.roundTo(5);
// results in x = 235
I'm answering this in psuedocode since I program mainly in SystemVerilog and Vera (ASIC HDL). % represents a modulus function.
round_number_up_to_nearest_divisor = number + ((divisor - (number % divisor)) % divisor)
This works in any case.
The modulus of the number calculates the remainder, subtracting that from the divisor results in the number required to get to the next divisor multiple, then the "magic" occurs. You would think that it's good enough to have the single modulus function, but in the case where the number is an exact multiple of the divisor, it calculates an extra multiple. ie, 24 would return 27. The additional modulus protects against this by making the addition 0.
As mentioned in a comment to the accepted answer, you can just use this:
Math.ceil(x/3)*3
(Even though it does not return 3 when x is 0, because that was likely a mistake by the OP.)
Out of the nine answers posted before this one (that have not been deleted or that do not have such a low score that they are not visible to all users), only the ones by Dean Nicholson (excepting the issue with loss of significance) and beauburrier are correct. The accepted answer gives the wrong result for negative numbers and it adds an exception for 0 to account for what was likely a mistake by the OP. Two other answers round a number to the nearest multiple instead of always rounding up, one more gives the wrong result for negative numbers, and three more even give the wrong result for positive numbers.
This function will round up to the nearest multiple of whatever factor you provide.
It will not round up 0 or numbers which are already multiples.
round_up = function(x,factor){ return x - (x%factor) + (x%factor>0 && factor);}
round_up(25,3)
27
round up(1,3)
3
round_up(0,3)
0
round_up(6,3)
6
The behavior for 0 is not what you asked for, but seems more consistent and useful this way. If you did want to round up 0 though, the following function would do that:
round_up = function(x,factor){ return x - (x%factor) + ( (x%factor>0 || x==0) && factor);}
round_up(25,3)
27
round up(1,3)
3
round_up(0,3)
3
round_up(6,3)
6
Building on #Makram's approach, and incorporating #Adam's subsequent comments, I've modified the original Math.prototype example such that it accurately rounds negative numbers in both zero-centric and unbiased systems:
Number.prototype.mround = function(_mult, _zero) {
var bias = _zero || false;
var base = Math.abs(this);
var mult = Math.abs(_mult);
if (bias == true) {
base = Math.round(base / mult) * _mult;
base = (this<0)?-base:base ;
} else {
base = Math.round(this / _mult) * _mult;
}
return parseFloat(base.toFixed(_mult.precision()));
}
Number.prototype.precision = function() {
if (!isFinite(this)) return 0;
var a = this, e = 1, p = 0;
while (Math.round(a * e) / e !== a) { a *= 10; p++; }
return p;
}
Examples:
(-2).mround(3) returns -3;
(0).mround(3) returns 0;
(2).mround(3) returns 3;
(25.4).mround(3) returns 24;
(15.12).mround(.1) returns 15.1
(n - n mod 3)+3
$(document).ready(function() {
var modulus = 3;
for (i=0; i < 21; i++) {
$("#results").append("<li>" + roundUp(i, modulus) + "</li>")
}
});
function roundUp(number, modulus) {
var remainder = number % modulus;
if (remainder == 0) {
return number;
} else {
return number + modulus - remainder;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Round up to nearest multiple of 3:
<ul id="results">
</ul>
A more general answer that might help somebody with a more general problem: if you want to round numbers to multiples of a fraction, consider using a library. This is a valid use case in GUI where decimals are typed into input and for instance you want to coerce them to multiples of 0.25, 0.2, 0.5 etc. Then the naive approach won't get you far:
function roundToStep(value, step) {
return Math.round(value / step) * step;
}
console.log(roundToStep(1.005, 0.01)); // 1, and should be 1.01
After hours of trying to write up my own function and looking up npm packages, I decided that Decimal.js gets the job done right away. It even has a toNearest method that does exactly that, and you can choose whether to round up, down, or to closer value (default).
const Decimal = require("decimal.js")
function roundToStep (value, step) {
return new Decimal(value).toNearest(step).toNumber();
}
console.log(roundToStep(1.005, 0.01)); // 1.01
RunKit example
Using remainder operator (modulus):
(n - 1 - (n - 1) % 3) + 3
By the code given below use can change any numbers and you can find any multiple of any number
let numbers = [8,11,15];
let multiple = 3
let result = numbers.map(myFunction);
function myFunction(n){
let answer = Math.round(n/multiple) * multiple ;
if (answer <= 0)
return multiple
else
return answer
}
console.log("Closest Multiple of " + multiple + " is " + result);
if(x%3==0)
return x
else
return ((x/3|0)+1)*3

Categories

Resources