I'm trying to edit an existing (working, shown first) script that delivers two decimals so that it will only deliver rounded numbers - my edit shown second (example). To be clear I want simple integers i.e. 18 not 18.00.
function D(r){
if (r.stat === "ok") {
for (var k in r.items) {
document.write(r.items[k].inventory)
}
}
}
function D(r){
if (r.stat === "ok") {
for (var k in r.items) {
document.write(r.items[k].inventory)
Math.round()
}
}
}
You can try one of these methods to do that according to your requirements:
Math.floor()
intvalue = Math.floor( floatvalue );
Math.ceil()
intvalue = Math.ceil( floatvalue );
Math.round()
intvalue = Math.round( floatvalue );
Example:
value = 3.65
Math.ceil(value); // 4
Math.floor(value); // 3
Math.round(value); // 4
in your function :
you should pass argument to method math.round to work as expected :
Math.round(r.items[k].inventory);
Math.round works just fine. Put the thing you want rounded in between the parentheses ().
let foo = {
stat: "ok",
items: {
apple: {
inventory: 18.45
}
}
}
function D(r) {
if (r.stat === "ok") {
for (var k in r.items) {
console.log(Math.round(r.items[k].inventory))
}
}
}
D(foo);
Rounding numbers.
There are many ways to round a number each with slight differences.
To closest integer
Generally you round to the closest whole number
Math.round(9.4) == 9; // is true
Math.round(9.6) == 10; // is true
Math.round(-9.4) == -9; // is true
Math.round(-9.6) == -10; // is true
Midway point round up
In the case where you are halfway you round up towards Infinity
Math.round(9.5) == 10; // is true
Math.round(-9.5) == 9; // is true
You do not round to the nearest even
Math.round(8.5) == 9; // is true
Math.round(-7.5) == -7; // is true
Midway point round away from zero
If you want to round the mid point away from 0 you can use
9.5.toFixed() == 10; // is true
-9.5.toFixed() == -10; // is true
Note the result is a string so if you want a number convert it as follows
Number( 9.5.toFixed()) === 10; // is true
Number(-9.5.toFixed()) === -10; // is true
Midway point round to even
If you wish to round to the nearest even you will have to create a function
const roundEven = (val) => {
if (Math.abs(val % 1) === 0.5) {
return (val = Math.round(val), val - (val % 2) * Math.sign(val));
}
return Math.round(val);
}
roundEven(9.5) === 10; // is true
roundEven(-9.5) === -10; // is true
roundEven(8.5) === 8; // is true
roundEven(-8.5) === -8; // is true
Example
show("Math.round(9.4) === " + Math.round(9.4))
show("Math.round(9.6) === " + Math.round(9.6))
show("Math.round(-9.4) === " + Math.round(-9.4))
show("Math.round(-9.6) === " + Math.round(-9.6))
show("Math.round(9.5) === " + Math.round(9.5) )
show("Math.round(-9.5) === " + Math.round(-9.5) )
show("Math.round(8.5) === " + Math.round(8.5) )
show("Math.round(-7.5) === " + Math.round(-7.5) )
show(" 9.5.toFixed() === '" + 9.5.toFixed() + "'" )
show("-9.5.toFixed() === '" + -9.5.toFixed() + "'" )
show("Number( 9.5.toFixed()) === " + Number(9.5.toFixed()))
show("Number(-9.5.toFixed()) === " + Number(-9.5.toFixed()))
const roundEven = (val) => {
if (Math.abs(val % 1) === 0.5) {
return (val = Math.round(val), val - (val % 2) * Math.sign(val));
}
return Math.round(val);
}
show("roundEven(9.5) === " + roundEven(9.5))
show("roundEven(-9.5) === " + roundEven(-9.5))
show("roundEven(8.5) === " + roundEven(8.5))
show("roundEven(-8.5) === " + roundEven(-8.5))
show("roundEven(0.5) === " + roundEven(0.5))
show("roundEven(-0.5) === " + roundEven(-0.5))
function show(text){
const d = document.createElement("div");
d.textContent = text;
document.body.appendChild(d);
}
Related
I am trying to write a function that must convert a decimal number to binary and vice versa.
The function receives two arguments:
number, either binary/decimal
conversion to perform
Works fine when I pass binaryDecimal(5, 2); (// prints 101) for decimal to binary conversation.
When I pass the arguments to the function to convert binary to decimal, it does not print anything.
const binarioDecimal = (number = 0, base = 0) => { // 0 by default if the user does not pass any value
if (number === 0 || base === 0) {
console.log(0);
} else if (typeof number === "number" && typeof base === "number") {
if (base === 2) {
let num = number;
let binary = (num % 2).toString();
for (; num > 1; ) {
num = parseInt(num / 2);
binary = (num % 2) + binary;
}
console.log(binary);
}
} else if (typeof number === "number" && typeof base === "number") {
//this is where i think the function fails
if (base === 10) {
var decimal = 0,
i = 0,
resto;
while (number !== 0) {
resto = number % 10;
number = Number.parseInt(number / 10);
decimal = decimal + resto * Math.pow(2, i);
++i;
}
console.log(decimal);
}
}
};
binarioDecimal(); // 0
binarioDecimal(23, 2); // 10111
binarioDecimal(101, 10); //does not print anything :(
What if you split the checks into two separate conditions?
const binarioDecimal = (number = 0, base = 0) => {
if (number === 0 || base === 0) {
console.log(0);
}
if (base === 2) {
var num = number;
var binary = (num % 2).toString();
for (; num > 1; ) {
num = parseInt(num / 2);
binary = (num % 2) + binary;
}
console.log(binary);
}
if (base === 10) {
var decimal = 0,
i = 0,
resto;
while (number !== 0) {
resto = number % 10;
number = Number.parseInt(number / 10);
decimal = decimal + resto * Math.pow(2, i);
++i;
}
console.log(decimal);
}
}
binarioDecimal(); // 0
binarioDecimal(23, 2); // 10111
binarioDecimal(101, 10); // 5
The second
else if (typeof number === "number" && typeof base === "number")
is never executed.
Maybe try something like:
else if (typeof number === "number" && typeof base === "number" && base === 2)
{
...
}
else if (typeof number === "number" && typeof base === "number" && base === 10)
{
...
}
if you see what I mean!
The problem appears to be in your outermost if() statement. You have the following:
if(number === 0 || base === 0) {
/* your code */
} else if(typeof number === "number" && typeof base === "number") {
if(base === 2) { /* your code */ }
} else if(typeof number === "number" && typeof base === "number") {
if(base === 10) { /* your code */ }
}
Using this, if you call binarioDecimal(101, 10);:
if(number === 0 || base === 0)
is false
else if(typeof number === "number" && typeof base === "number")
is true
then if(base === 2)
is false
It then exits the whole statement, assuming it has fulfilled its purpose, never reaching the third else if(...) because it's the same as the previous one.
Putting the if(base === 10) with the if(base === 2) statement should resolve the issue.
if(number === 0 || base === 0) {
/* your code */
} else if(typeof number === "number" && typeof base === "number") {
if(base === 2) {
/* your code */
} else if(base === 10) {
/* your code */
}
}
That should solve why your code is never reached when the base is 10. Alternatively, outside of doing so for a coding exercise, you may want to look at Number.prototype.toString(radix); and Number.parseInt(string, radix); to convert between number bases. Hopefully this information is useful!
This is a basic calculator function. It only does addition, subtraction, multiplication, division and parentheses.
I'm having an infinite loop on recursive call in while section which is checking the string whether has a parentheses or not. If i would've send a string with 2 or more parentheses to the function, it has been stucking in loop. I couldn't figure out what I have done wrong.
const operators = ['+', '-', '*', '/', '(', ')'];
const numbers = [];
let arr;
const array = [];
function Calculate(string) {
string.split('').map(char => {
if (!operators.includes(char)) {
numbers.push(char);
} else {
arr = numbers.join('');
numbers.splice(0);
array.push(arr, char);
}
});
arr = numbers.join('');
const str = array.filter(char => char !== '').concat(arr);
while (str.includes('(')) { // Checking parentheses
let indexOpen = str.findIndex(char => char === '(');
let indexClose = indexOpen + 1;
let count = 1;
while (count !== 0) {
if (str[indexClose] === '(') {
count++;
} else if (str[indexClose] === ')') {
count--;
}
indexClose++;
}
if (
!operators.includes(str[indexOpen - 1])
// str[indexOpen - 1] !== '+' &&
// str[indexOpen - 1] !== '-' &&
// str[indexOpen - 1] !== '*' &&
// str[indexOpen - 1] !== '/'
) {
str.splice(indexOpen, 0, '*');
indexOpen++;
indexClose++;
}
const strPara = str
.filter((_, i) => i < indexClose - 1 && i > indexOpen)
.join('');
str.splice(indexOpen, indexClose - indexOpen, Calculate(strPara));
}
let indexMul; // Multiplication and division
let indexDiv;
while (str.includes('*') || str.includes('/')) {
indexMul =
str.findIndex(char => char === '*') === -1
? str.length
: str.findIndex(char => char === '*');
indexDiv =
str.findIndex(char => char === '/') === -1
? str.length
: str.findIndex(char => char === '/');
if (indexMul < indexDiv) {
str.splice(indexMul - 1, 3, +str[indexMul - 1] * +str[indexMul + 1] + '');
} else if (indexDiv < indexMul) {
str.splice(
indexDiv - 1,
3,
Math.trunc(+str[indexDiv - 1] / +str[indexDiv + 1]) + ''
);
}
}
while (str.length !== 1) { // Addition and subtraction
if (str[1] === '+') {
str.splice(0, 3, +str[0] + +str[2] + '');
}
if (str[1] === '-') {
str.splice(0, 3, +str[0] - +str[2] + '');
}
}
return str;
}
console.log(Calculate('3(16-(10-4)+2)/2(4*2)+1'));
I did this.
Be careful, this code does the calculations one after the other without managing operators precedence
The recursive way :
let strCalc = '3(16-(10-4)+2)/2(4*2)+1'
document.write(`${ strCalc } = ${ Calculate(strCalc) }`)
document.write(`<br><br>`)
strCalc = '5 ( -18.4 + 2 ) / ( -2 ( 4 * -.5 )) + 1'
document.write(`${ strCalc } = ${ Calculate(strCalc) }`)
function Calculate(str)
{
const ops = str
.match(/[\(\)\+\-\*\/]|((\d+\.?\d*)|(\.\d+))/g)
.reduce((r,v)=>
{
if (isNaN(v))
{
if (!r.opPrev || v==='(')
{
r.res.push(v)
r.opPrev = ( v!==')' )
}
else if (v==='-') // check negatives values
r.sign='-';
}
else
{
r.res.push(Number(`${r.sign}${v}`))
r.sign = ''
r.opPrev = false
}
return r
}, { res:[], opPrev:true, sign:'' }).res
;
let Pos = 0
;
return makeCalc()
;
function makeCalc()
{
let result = 0
, operand = '+'
, val
;
while ( Pos < ops.length && ops[Pos] !== ')' )
{
val = ops[Pos]
;
if ( val === '(' )
{
operand ??= '*' // nullish assignement operator
Pos++
val = makeCalc() // recurvive call
}
if ( isNaN(val) )
operand = val
;
else
{
switch (operand)
{
case '+' : result += val; break;
case '-' : result -= val; break;
case '/' : result /= val; break; // may do 0 divide!
case '*' : result *= val; break;
}
operand = null
}
Pos++
}
return result
}
}
I'm trying to make a recursive function to print the factorial of a given integer. Ask the user to enter a positive integer and then display the output on a page. For example, if the user enters 5, the output must be
5 × 4 × 3 × 2 × 1 = 120
var integer = prompt("Enter a positive integer.");
function factorialize(num) {
if(num == 0 || num == 1) {
return 1;
}
else {
return num + " x " + factorialize(num-1) + num * factorialize(num-1);
}
}
document.write(factorialize(integer));
You can pass a runningTotal of the sum so far to each recursive call. You can also keep the solution compact using template literals.
function factorialize(n, runningTotal = 1) {
if (n === 1) return `1 = ${runningTotal}`;
return `${n} x ${factorialize(n - 1, runningTotal * n)}`;
}
console.log(factorialize(5));
You could handover the parts of product and result.
function factorialize(num, product = 1, result = '') {
return num === 0 || num === 1
? result + (result && ' x ') + num + ' -> ' + product
: factorialize(num - 1, product * num, result + (result && ' x ') + num);
}
console.log(factorialize(5));
console.log(factorialize(2));
console.log(factorialize(1));
console.log(factorialize(0));
I think make that recursively is quite confused:
function factorialize(n, expression = '', result = 0) {
if (n < 0) {
return null
} else if (n === 0) {
return (expression || n) + " = " + result
}
const newExpression = result ? expression + " x " + n : n
const newResult = !result ? n : result * n
return factorialize(n - 1, newExpression, newResult)
}
console.log(factorialize(5))
Is better to segregate the responsibilities:
function factorial(n) {
let fact = 1
if (n < 0) {
console.warn("Error");
return 0
} else {
for (let i = n; i > 0; i--) {
fact = fact * i;
}
}
return fact
}
function factorialExpression(n) {
let expression = ""
if (n < 0) {
console.warn("Error");
return ""
} else {
for (let i = n; i > 0; i--) {
expression += (i < n ? " x " : "") + i
}
}
return expression
}
function factorialize(n) {
if (n === 0 || n === 1) {
return n + " = " + n
} else if (n > 1) {
return factorialExpression(n) + " = " + factorial(n)
}
return null
}
console.log(factorialize(5))
I am using javascript to format the number with commas , it was working very fine.
But now the problem is if a value is comming in negative for example : -792004
It is returning the output like : -,792,004 that is comma is in the start.
How can I modify this method ?
Here is my code :
function Comma(number) {
number = '' + number;
if (number.length > 3) {
var mod = number.length % 3;
var output = (mod > 0 ? (number.substring(0, mod)) : '');
for (i = 0; i < Math.floor(number.length / 3); i++) {
if ((mod == 0) && (i == 0))
output += number.substring(mod + 3 * i, mod + 3 * i + 3);
else
output += ',' + number.substring(mod + 3 * i, mod + 3 * i + 3);
}
return (output);
} else return number;
}
The simplest way I know which will helps you is toLocaleString() method on number:
var x = 10033001;
var y = -10033001;
console.log(x.toLocaleString(), y.toLocaleString());
But for correction of your code, you can remove number sign with Math.abs and add it after with Math.sign.
var sign = Math.sign(number);
number = Math.abs(number);
// Do the conversion
return (sign < 0) ? ("-" + output) : output;
Try this:
const comma = function(number) {
const prefix = number < 0 ? '-' : ''
number = String(Math.abs(number))
if (number.length > 3) {
const mod = number.length % 3
let output = (mod > 0 ? (number.substring(0,mod)) : '')
for (let i = 0; i < Math.floor(number.length / 3); i++) {
if (mod === 0 && i === 0)
output += number.substring(mod+ 3 * i, mod + 3 * i + 3)
else
output+= ',' + number.substring(mod + 3 * i, mod + 3 * i + 3);
}
return prefix + output
} else {
return prefix + number
}
}
If the number is negative, it assigns - to prefix. Then it changes number to its absolute value (Math.abs(number)). In the end it returns value with prefix.
I'm sending the number/string 0.001 to a the function below:
SignificantFigures = 4;
function LimitNumberOfDigits(num) {
var tempStr = "";
if (isNaN(num))
return "\xD8";
else{
if (parseFloat(num) === 0 || (num.toString().indexOf('.') === -1 && parseInt(num) < 9999) || num.toString().length <= 4) {
return num;
}
tempStr = parseFloat(num).toPrecision(SignificantFigures);
if (tempStr.indexOf("e") > -1) {
var startE = tempStr.indexOf("e");
var endE = 0;
for (var i = startE +2 ; i < tempStr.length; i++ ) { // + to ignore e and sign (+ or - )
if(parseInt(tempStr[i], 10) > 0) {
endE = i;
}else {
break;
}
}
if (startE + 2 === endE) {
var pow = tempStr[endE];
} else {
var pow = tempStr.substring(startE +2 ,endE);
}
return tempStr.substring(0,startE) + "*10<sup>"+ pow +"</sup>";
}else {
return parseFloat(num).toPrecision(SignificantFigures);
}
}
}
When im sending 0.2 or even 0.11 im getting like 0.2000 and 0.1100.
The issue here is the toPrecision acts like ToFixed.
Ideas?
EDIT
What i want? simple as that, if a numbers needs to be changed e.g 0.012312312041 it should be 0.0123 , numbers like 0.12 or 28 should stay the same.