What is the purpose of +- on a Javascript number? - javascript

I came across some code recently that was like this:
const element = document.getElementById("myId")
const rect = element.getBoundingClientRect()
const height = +-(rect.height / 1)
First of all, what is the deal with the division by 1? And second, what does +- do?
I put that logic into a Fiddle and it appears that it flips the sign of whatever is in the parentheses (from positive to negative and from negative to positive). However, if I wanted to flip a sign, why wouldn't I just do -(myvariable)?
Regarding the division by 1, it appears that the type of rect.height is already a number with floating-point precision and the divide operator is also floating-point division so we're not trying to generate an int or anything.
I just need some help trying to understand what that's trying to do.
Edit: The code was found here: Check if element is partially in viewport

Using division / will implicitly convert both operands to numbers:
const str = "10.5"
const division = str / 1;
console.log(division);
console.log(typeof division);
Using a unary minus - will implicitly convert the operand and change its sign:
const str = "10.5";
const minusStr = -str;
console.log(minusStr);
console.log(typeof minusStr);
const negativeNum = -3;
const minusNegativeNum = -negativeNum;
console.log(minusNegativeNum);
Using a unary plus + will convert anything to a number. If supplied with a number, it leaves it as it is:
const str = "10.5";
const plusStr = +str;
console.log(plusStr);
console.log(typeof plusStr);
const negativeNum = -3;
const plusNegativeNum = +negativeNum;
console.log(plusNegativeNum);
The above is also the order of how the expression +-(rect.height / 1) would be evaluated.
So, what does +-(rect.height / 1) do? The same as -rect.height but tacks on two useless operators.
It should be noted, that none of the conversions are really needed - not because a unary minus already does it, but because the height property produces a number anyway:
const element = document.getElementById("myId")
const rect = element.getBoundingClientRect()
console.log(rect.height);
console.log(typeof rect.height);
const height = +-(rect.height / 1);
console.log(height);
#myId {
width: 400px;
height: 200px;
background: red;
}
<div id="myId"></div>
So the whole expression just gets the height and inverts its sign.

Can you provide the link where you found this code?
But from what you provided, I would agree with you. The + operator and the dividing by one wouldn't do anything. So I would say that it's a typo, bit of temporary code, or the developer having one too many drinks.

I think it´s a trap. I´m not shure but if you get numbers from document you get strings instead of numbers. this + before a number in a string (example "10") would turn it in type number.
For example
"11" + 1 = "111"
because javascript concanate this as 2 strings.
but
var a = "11"
+a makes it = 11
but the restit sadly out of context i think
Edit:
ah okay.
Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-(rect.height / 1)) * 100)) < percentVisible
+-(rect.height / 1)) * 100
I think this parts makes this number to a percent value.JS don´t know percent. Everything is value / 100, but to get the right value, you should value / 1.

Related

javascript float dynamic precision?

how can I get dynamic precision for float?
exemple what I need :
0.00019400000001.dynamicPrecision() //0.000194
0.0001940001.dynamicPrecision() //0.000194
0.0001941.dynamicPrecision() //0.0001941
0.0194.dynamicPrecision() //0.0194
0.01940000.dynamicPrecision() //0.0194
(its important to not have useless zero at the end)
I can't use toFixed or toPrecision because the significative number can change and is unknow. so what way to write this dynamicPrecision method with dynamic precision?
While it's a bit questionable what you are asking for, one approach would be to take slices of the decimal and then compare it to the original. If it is some threshold percentage different, consider it an answer.
const f = (v, threshold = .9999) => {
let shift = 1;
let part;
do {
shift *= 10;
part = Math.floor(v * shift) / shift;
} while (part / v < threshold);
return part;
}
[0.194, 0.194000001, 0.19401, 0.194101]
.forEach(v => console.log(f(v)));
This uses actual math to determine the significant digit.
Basically, for each step, it takes one more digit and compares it against the value. If it is within the threshold, then it will be returned.
For 1.9410001 it would:
part = 1.9
part = 1.94
part = 1.941 // part / v > threshold, returned
The threshold is then configurable. .9999 means it is 99.99% the same as the original value.
I hope it will help,
var number1 = 0.00019400000001
console.log(parseFloat(number1.toString().replace(/0+[1-9]$/, '')));
You could replace all endings with at least one zero and one one at the end. Then take the numererical value.
function precision(v) {
return +v.toString().replace(/0+1$/, '');
}
console.log([0.00019400000001, 0.0001940001, 0.0001941, 0.0194, 0.01940000].map(precision));
Number.prototype.dynamicPrecision = function(){
return parseFloat(this.valueOf().toString().replace(/0+1$/, ''));
}
console.log(
0.00019400000001.dynamicPrecision(), //0.000194
0.0001940001.dynamicPrecision(), //0.000194
0.0001941.dynamicPrecision(), //0.0001941
0.0194.dynamicPrecision(), //0.0194
0.01940000.dynamicPrecision() //0.0194
)

Issue with Math rounding in JS failing to actually provide a whole number in favor of a decimal answer

So I set this up for a bit of simple math to add a little flair to a madlibs game. Yet everytime I run this I get a decimal answer rather than a whole number, Math.round(x, n) doesn't work either. Is there some improper syntax or something I'm missing?
let height = prompt("About how tall are you like inch-wise? 48 = 4 feet, 60 = 5 feet , 72 = 6 feet."); //for height multiple in story
if (isNaN(height)) {
height = 66;
}
else {
height = height;
};
height = height / 12;
console.log(height);
Math.round(height);
console.log(height);
JavaScript doesn't pass variables by reference and Math.round returns the rounded value. So you have to assign the resulting value.
height = Math.round(height);

JS - Format number with 2 decimal not rounded

I would format a number with 2 decimal places without rounding.
So I excluded the toFixed() function.
I have tried this way
a = 1,809999
b = 27,94989
a = Math.floor(a * 100) / 100; --> 1,8
b = Math.floor(b * 100) / 100; --> 27,94
OR
a = Number(a.toString().match(/^\d+(?:\.\d{0,2})?/)); --> 1,8
b = Number(b.toString().match(/^\d+(?:\.\d{0,2})?/)); --> 27,94
Unfortunately, the second decimal of a is zero, and this was deleted, how could I do to keep it and have a = 1.80?
Thank you
(Math.floor(a * 100) / 100).toFixed(2);
With toFixed(2) !
JSFIDDLE DEMO
You can try like this:
a= a.toString().slice(0, (a.indexOf("."))+3);
JSFIDDLE DEMO
Rounding a number is about changing it's value, and should be done with math operations (Math.floor, Math.ceil, Math.round, ...).
Formatting number, is about how do numbers get displayed to a human user (like Date formatting).
Javascript does not comes with acceptable native tool to do number formatting.
You can always play with rounding to make javascript print a number the way you want, but you will end up writing a lot of (possibly buggy) code.
I would recommend using a library to format your numbers
http://numeraljs.com/
numeral(number).format('0.00');
only need to use toFixed() and pass number like 2 then it show after . two decimal like bello
a = 1,809999
b = 27,94989
a = Math.floor(a * 100) / 100;
b = Math.floor(b * 100) / 100;
$(".testa").text(a.toFixed(2)); //see here.
$(".testb").text(b.toFixed(2)); //see here.
Html :
<div class="testa"></div>
<br>
<div class="testb"></div>
i hope this will help you. and also see this jsfiddle link http://jsfiddle.net/RGerb/394/
myFunction(value: number){
let x = value + '';
var a = x.lastIndexOf('.')>=0?parseFloat(x.substr(0,x.lastIndexOf('.')+(3))):value;
var am = a.toFixed(2)
console.log("Output: " + am);
return am;
}
<button (click)="myFunction(656565.9668985)">My Function</button>
Output: 656565.96

Eval alternative

This code works as a calculator, but the scratch pad at codeacademy tells me that eval is evil. Is there another way to do the same thing without using eval?
var calculate = prompt("Enter problem");
alert(eval(calculate));
eval evaluates the string input as JavaScript and coincidentally JavaScript supports calculations and understands 1+1, which makes it suitable as a calculator.
If you don't want to use eval, which is good, you have to parse that string yourself and, finally, do the computation yourself (not exactly yourself though). Have a look at this math processor, which does what you want.
Basically what you do is:
Read the input string char by char (with this kind of problem it's still possible)
Building a tree of actions you want to do
At the end of the string, you evaluate the tree and do some calculations
For example you have "1+2/3", this could evaluate to the following data structure:
"+"
/ \
"1" "/"
/ \
"2" "3"
You could then traverse that structure from top to bottom and do the computations.
At first you've got the "+", which has a 1 on the left side and some expression on the right side,
so you have to evaluate that expression first. So you go to the "/" node, which has two numeric children. Knowing that, you can now compute 2/3 and replace the whole "/" node with the result of that. Now you can go up again and compute the result of the "+" node: 1 + 0.66. Now you replace that node with the result and all you've got left is the result of the expression.
Some pseudo code on how this might look in your code:
calculation(operator, leftValue, rightValue):
switch operator {
case '+': return leftValue + rightValue
case '-': return 42
}
action(node):
node.value = calculation(node.operator, action(node.left) action(node.right))
As you might have noticed, the tree is designed in such a way that it honors operator precedence. The / has a lower level than the +, which means it get's evaluated first.
However you do this in detail, that's basically the way to go.
You can use the expression parser that is included in the math.js library:
http://mathjs.org
Example usage:
mathjs.evaluate('1.2 / (2.3 + 0.7)'); // 0.4
mathjs.evaluate('5.08 cm in inch'); // 2 inch
mathjs.evaluate('sin(45 deg) ^ 2'); // 0.5
mathjs.evaluate('9 / 3 + 2i'); // 3 + 2i
mathjs.evaluate('det([-1, 2; 3, 1])'); // -7
You can use eval safely for a simple arithmetic calculator by filtering the input- if you only accept digits, decimal points and operators (+,-,*,/) you won't get in much trouble. If you want advanced Math functions, you are better off with the parser suggestions.
function calculate(){
"use strict";
var s= prompt('Enter problem');
if(/[^0-9()*+\/ .-]+/.test(s)) throw Error('bad input...');
try{
var ans= eval(s);
}
catch(er){
alert(er.message);
}
alert(ans);
}
calculate()
I write some functions when I had a problem like this. Maybe this can help:
data = [
{id:1,val1:"test",val2:"test2",val2:"test3"},
{id:2,val1:"test",val2:"test2",val2:"test3"},
{id:3,val1:"test",val2:"test2",val2:"test3"}
];
datakey = Object.keys(data[0]);
// here's a fix for e['datakey[f]'] >> e[x]
vix = function(e,f){
a = "string";
e[a] = datakey[f];
x = e.string;
end = e[x];
delete e.string;
return end;
};
// here's a fix to define that variable
vox = function(e,f,string){
a = "string";
e[a] = datakey[f];
x = e.string;
end = e[x] = string;
delete e.string;
};
row = 2 // 3th row ==> {id:3,val1:"test",val2:"test2",val2:"test3"}
column = 1 //datakey 2 ==> val1
vox(data[row],column,"new value");
alert(data[2].val1); //the value that we have changed

How can I round a number in JavaScript? .toFixed() returns a string?

Am I missing something here?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Why does .toFixed() return a string?
I want to round the number to 2 decimal digits.
Number.prototype.toFixed is a function designed to format a number before printing it out. It's from the family of toString, toExponential and toPrecision.
To round a number, you would do this:
someNumber = 42.008;
someNumber = Math.round( someNumber * 1e2 ) / 1e2;
someNumber === 42.01;
// if you need 3 digits, replace 1e2 with 1e3 etc.
// or just copypaste this function to your code:
function toFixedNumber(num, digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(num*pow) / pow;
}
.
Or if you want a “native-like” function, you can extend the prototype:
Number.prototype.toFixedNumber = function(digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(this*pow) / pow;
}
someNumber = 42.008;
someNumber = someNumber.toFixedNumber(2);
someNumber === 42.01;
//or even hexadecimal
someNumber = 0xAF309/256; //which is af3.09
someNumber = someNumber.toFixedNumber(1, 16);
someNumber.toString(16) === "af3.1";
However, bear in mind that polluting the prototype is considered bad when you're writing a module, as modules shouldn't have any side effects. So, for a module, use the first function.
I've solved this problem by changing this:
someNumber = someNumber.toFixed(2)
...to this:
someNumber = +someNumber.toFixed(2);
However this will convert the number to a string and parse it again, which will have a significant impact on performance. If you care about performance or type safety, check the the other answers as well.
It returns a string because 0.1, and powers thereof (which are used to display decimal fractions), are not representable (at least not with full accuracy) in binary floating-point systems.
For example, 0.1 is really 0.1000000000000000055511151231257827021181583404541015625, and 0.01 is really 0.01000000000000000020816681711721685132943093776702880859375. (Thanks to BigDecimal for proving my point. :-P)
Therefore (absent a decimal floating point or rational number type), outputting it as a string is the only way to get it trimmed to exactly the precision required for display.
Why not use parseFloat?
var someNumber = 123.456;
someNumber = parseFloat(someNumber.toFixed(2));
alert(typeof(someNumber));
//alerts number
I solved it with converting it back to number using JavaScript's Number() function
var x = 2.2873424;
x = Number(x.toFixed(2));
Of course it returns a string. If you wanted to round the numeric variable you'd use Math.round() instead. The point of toFixed is to format the number with a fixed number of decimal places for display to the user.
You can simply use a '+' to convert the result to a number.
var x = 22.032423;
x = +x.toFixed(2); // x = 22.03
May be too late to answer but you can multiple the output with 1 to convert to number again, here is an example.
const x1 = 1211.1212121;
const x2 = x1.toFixed(2)*1;
console.log(typeof(x2));
What would you expect it to return when it's supposed to format a number ? If you have a number you can't pretty much do anything with it because e.g.2 == 2.0 == 2.00 etc. so it has to be a string.
Because its primary use is displaying numbers? If you want to round numbers, use Math.round() with apropriate factors.
To supply an example of why it has to be a string:
If you format 1.toFixed(2) you would get '1.00'.
This is not the same as 1, as 1 does not have 2 decimals.
I know JavaScript isn't exactly a performance language, but chances are you'd get better performance for a rounding if you use something like:
roundedValue = Math.round(value * 100) * 0.01
You should use it like below.
var someNumber: number = 0.000000;
someNumber = Number(someNumber.toFixed(2))
Why not * the result by 1 i.e
someNumber.toFixed(2) * 1
Here's a slightly more functional version of the answer m93a provided.
const toFixedNumber = (toFixTo = 2, base = 10) => num => {
const pow = Math.pow(base, toFixTo)
return +(Math.round(num * pow) / pow)
}
const oneNumber = 10.12323223
const result1 = toFixedNumber(2)(oneNumber) // 10.12
const result2 = toFixedNumber(3)(oneNumber) // 10.123
// or using pipeline-operator
const result3 = oneNumber |> toFixedNumber(2) // 10.12
For others like me that happen upon this very old question, a modern solution:
const roundValue = (num, decimals = 2) => {
let scaling = 10 ** decimals;
return Math.round((num + Number.EPSILON) * scaling) / scaling;
}
ref: https://stackoverflow.com/a/11832950
Be careful using toFixed() and Math.round(), they can produce unexpected results due to the floating point number system:
function toFixedNumber(num, digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(num*pow) / pow;
}
console.log(toFixedNumber(130.795, 2, 10));
// 130.79 (incorrect)
console.log(toFixedNumber(100.795, 2, 10));
// 100.8
console.log(+130.795.toFixed(2));
// 130.79 (incorrect)
console.log(+100.795.toFixed(2));
// 100.8
I recommend using Lodash's _.round() function: https://lodash.com/docs/4.17.15#round
_.round(130.795, 2);
// 130.8

Categories

Resources