I was wondering what the = +_ operator means in JavaScript. It looks like it does assignments.
Example:
hexbin.radius = function(_) {
if (!arguments.length)
return r;
r = +_;
dx = r * 2 * Math.sin(Math.PI / 3);
dy = r * 1.5;
return hexbin;
};
r = +_;
+ tries to cast whatever _ is to a number.
_ is only a variable name (not an operator), it could be a, foo etc.
Example:
+"1"
cast "1" to pure number 1.
var _ = "1";
var r = +_;
r is now 1, not "1".
Moreover, according to the MDN page on Arithmetic Operators:
The unary plus operator precedes its operand and evaluates to its
operand but attempts to converts it into a number, if it isn't
already. [...] It can convert string representations of integers and
floats, as well as the non-string values true, false, and null.
Integers in both decimal and hexadecimal ("0x"-prefixed) formats are
supported. Negative numbers are supported (though not for hex). If it
cannot parse a particular value, it will evaluate to NaN.
It is also noted that
unary plus is the fastest and preferred way of converting something into a number
It is not an assignment operator.
_ is just a parameter passed to the function.
hexbin.radius = function(_) {
// ^ It is passed here
// ...
};
On the next line r = +_; + infront casts that variable (_) to a number or integer value and assigns it to variable r
DO NOT CONFUSE IT WITH += operator
=+ are actually two operators = is assignment and + and _ is variable name.
like:
i = + 5;
or
j = + i;
or
i = + _;
My following codes will help you to show use of =+ to convert a string into int.
example:
y = +'5'
x = y +5
alert(x);
outputs 10
use: So here y is int 5 because of =+
otherwise:
y = '5'
x = y +5
alert(x);
outputs 55
Where as _ is a variable.
_ = + '5'
x = _ + 5
alert(x)
outputs 10
Additionally,
It would be interesting to know you could also achieve same thing with ~ (if string is int string (float will be round of to int))
y = ~~'5' // notice used two time ~
x = y + 5
alert(x);
also outputs 10
~ is bitwise NOT : Inverts the bits of its operand. I did twice for no change in magnitude.
It's not =+. In JavaScript, + means change it into number.
+'32' returns 32.
+'a' returns NaN.
So you may use isNaN() to check if it can be changed into number.
It's a sneaky one.
The important thing to understand is that the underscore character here is actually a variable name, not an operator.
The plus sign in front of that is getting the positive numerical value of underscore -- ie effectively casting the underscore variable to be an int. You could achieve the same effect with parseInt(), but the plus sign casting is likely used here because it's more concise.
And that just leaves the equals sign as just a standard variable assignment.
It's probably not deliberately written to confuse, as an experienced Javascript programmer will generally recognise underscore as a variable. But if you don't know that it is definitely very confusing. I certainly wouldn't write it like that; I'm not a fan of short meaningless variable names at the best of times -- If you want short variable names in JS code to save space, use a minifier; don't write it with short variables to start with.
= +_ will cast _ into a number.
So
var _ = "1",
r = +_;
console.log(typeof r)
would output number.
I suppose you mean r = +_;? In that case, it's conversion of the parameter to a Number. Say _ is '12.3', then +'12.3' returns 12.3. So in the quoted statement +_ is assigned to r.
_ is just a a variable name, passed as a parameter of function hexbin.radius , and + cast it into number
Let me make a exmple same like your function .
var hexbin = {},r ;
hexbin.radius = function(_) {
if (!arguments.length)
return r;
console.log( _ , typeof _ )
r = +_;
console.log( r , typeof r , isNaN(r) );
}
and run this example function .. which outputs
hexbin.radius( "1");
1 string
1 number false
hexbin.radius( 1 );
1 number
1 number false
hexbin.radius( [] );
[] object
0 number false
hexbin.radius( 'a' );
a string
NaN number true
hexbin.radius( {} );
Object {} object
NaN number true
hexbin.radius( true );
true boolean
1 number false
It Will assign new value to left side variable a number.
var a=10;
var b="asg";
var c=+a;//return 10
var d=-a;//return -10
var f="10";
var e=+b;
var g=-f;
console.log(e);//NAN
console.log(g);//-10
Simply put, +_ is equivalent to using the Number() constructor.
In fact, it even works on dates:
var d = new Date('03/27/2014');
console.log(Number(d)) // returns 1395903600000
console.log(+d) // returns 1395903600000
DEMO:
http://jsfiddle.net/dirtyd77/GCLjd/
More information can also be found on MDN - Unary plus (+) section:
The unary plus operator precedes its operand and evaluates to its operand but attempts to converts it into a number, if it isn't already. Although unary negation (-) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number. It can convert string representations of integers and floats, as well as the non-string values true, false, and null. Integers in both decimal and hexadecimal ("0x"-prefixed) formats are supported. Negative numbers are supported (though not for hex). If it cannot parse a particular value, it will evaluate to NaN.
+_ is almost equivalent of parseFloat(_) . Observe that parseInt will stop at non numeric character such as dot, whereas parshFloat will not.
EXP:
parseFloat(2.4) = 2.4
vs
parseInt(2.4) = 2
vs
+"2.4" = 2.4
Exp:
var _ = "3";
_ = +_;
console.log(_); // will show an integer 3
Very few differences:
Empty string "" evaluates to a 0, while parseInt() evaluates to NaN
For more info look here: parseInt vs unary plus - when to use which
In this expression:
r = +_;
'+' acts here as an unary operator that tries to convert the value of the right operand. It doesn't convert the operand but the evaluated value. So _ will stay "1" if it was so originally but the r will become pure number.
Consider these cases whether one wants to apply the + for numeric conversion
+"-0" // 0, not -0
+"1" //1
+"-1" // -1
+"" // 0, in JS "" is converted to 0
+null // 0, in JS null is converted to 0
+undefined // NaN
+"yack!" // NaN
+"NaN" //NaN
+"3.14" // 3.14
var _ = "1"; +_;_ // "1"
var _ = "1"; +_;!!_ //true
var _ = "0"; +_;!!_ //true
var _ = null; +_;!!_ //false
Though, it's the fastest numeric converter I'd hardly recommend one to overuse it if make use of at all. parseInt/parseFloat are good more readable alternatives.
Related
I store some parameters client-side in HTML and then need to compare them as integers. Unfortunately I have come across a serious bug that I cannot explain. The bug seems to be that my JS reads parameters as strings rather than integers, causing my integer comparisons to fail.
I have generated a small example of the error, which I also can't explain. The following returns 'true' when run:
console.log("2" > "10")
Parse the string into an integer using parseInt:
javascript:alert(parseInt("2", 10)>parseInt("10", 10))
Checking that strings are integers is separate to comparing if one is greater or lesser than another. You should always compare number with number and string with string as the algorithm for dealing with mixed types not easy to remember.
'00100' < '1' // true
as they are both strings so only the first zero of '00100' is compared to '1' and because it's charCode is lower, it evaluates as lower.
However:
'00100' < 1 // false
as the RHS is a number, the LHS is converted to number before the comparision.
A simple integer check is:
function isInt(n) {
return /^[+-]?\d+$/.test(n);
}
It doesn't matter if n is a number or integer, it will be converted to a string before the test.
If you really care about performance, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
return function(n) {
return re.test(n);
}
}());
Noting that numbers like 1.0 will return false. If you want to count such numbers as integers too, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
var re2 = /\.0+$/;
return function(n) {
return re.test((''+ n).replace(re2,''));
}
}());
Once that test is passed, converting to number for comparison can use a number of methods. I don't like parseInt() because it will truncate floats to make them look like ints, so all the following will be "equal":
parseInt(2.9) == parseInt('002',10) == parseInt('2wewe')
and so on.
Once numbers are tested as integers, you can use the unary + operator to convert them to numbers in the comparision:
if (isInt(a) && isInt(b)) {
if (+a < +b) {
// a and b are integers and a is less than b
}
}
Other methods are:
Number(a); // liked by some because it's clear what is happening
a * 1 // Not really obvious but it works, I don't like it
Comparing Numbers to String Equivalents Without Using parseInt
console.log(Number('2') > Number('10'));
console.log( ('2'/1) > ('10'/1) );
var item = { id: 998 }, id = '998';
var isEqual = (item.id.toString() === id.toString());
isEqual;
use parseInt and compare like below:
javascript:alert(parseInt("2")>parseInt("10"))
Always remember when we compare two strings.
the comparison happens on chacracter basis.
so '2' > '12' is true because the comparison will happen as
'2' > '1' and in alphabetical way '2' is always greater than '1' as unicode.
SO it will comeout true.
I hope this helps.
You can use Number() function also since it converts the object argument to a number that represents the object's value.
Eg: javascript:alert( Number("2") > Number("10"))
+ operator will coerce the string to a number.
console.log( +"2" > +"10" )
The answer is simple. Just divide string by 1.
Examples:
"2" > "10" - true
but
"2"/1 > "10"/1 - false
Also you can check if string value really is number:
!isNaN("1"/1) - true (number)
!isNaN("1a"/1) - false (string)
!isNaN("01"/1) - true (number)
!isNaN(" 1"/1) - true (number)
!isNaN(" 1abc"/1) - false (string)
But
!isNaN(""/1) - true (but string)
Solution
number !== "" && !isNaN(number/1)
The alert() wants to display a string, so it will interpret "2">"10" as a string.
Use the following:
var greater = parseInt("2") > parseInt("10");
alert("Is greater than? " + greater);
var less = parseInt("2") < parseInt("10");
alert("Is less than? " + less);
I want to convert a number start with 0 to string equivalent of the value.
If I run
var num = 12;
var int = num.toString();
console.log(int);
it logs 12 as expected but if I apply the toString() to a number start with 0 like,
var num = 012;
var int = num.toString();
console.log(int);
it logs 10, why?
Number starting with 0 is interpreted as octal (base-8).
In sloppy mode (the default) numbers starting with 0 are interpreted as being written in octal (base 8) instead of decimal (base 10). If has been like that from the first released version of Javascript, and has this syntax in common with other programming languages. It is confusing, and have lead to many hard to detect buggs.
You can enable strict mode by adding "use strict" as the first non-comment in your script or function. It removes some of the quirks. It is still possible to write octal numbers in strict mode, but you have to use the same scheme as with hexadecimal and binary: 0o20 is the octal representation of 16 decimal.
The same problem can be found with the function paseInt, that takes up to two parameters, where the second is the radix. If not specified, numbers starting with 0 will be treated as octal up to ECMAScript 5, where it was changed to decimal. So if you use parseInt, specify the radix to be sure that you get what you expected.
"use strict";
// Diffrent ways to write the same number:
const values = [
0b10000, // binary
0o20, // octal
16, // decimal,
0x10 // hexadecimal
];
console.log("As binary:", values.map( value => value.toString(2)).join());
console.log("As decimal:", values.join());
console.log("As ocal", values.map( value => value.toString(8)).join());
console.log("As hexadecimal:", values.map( value => value.toString(16)).join());
console.log("As base36:", values.map( value => value.toString(36)).join());
All you have to do is add String to the front of the number that is
var num = 12;
var int = String(num);
console.log(int);
And if you want it to look like this 0012 all you have to do is
var num = 12;
var int = String(num).padStart(4, '0');
console.log(int);
I am looking at the typeof a where var a = 2 + []. I expected the answer to be 2 of type number but I am getting '2' of type string. However, when I evaluate var b = 2 - [], I get the value to be 2 of type number. Can somebody assist me to understand this behavior.
const arr = [];
const a = 2 + arr;
console.log(a); // '2'
console.log(typeof a) // string
const b = 2 - arr;
console.log(b) // 2
console.log(typeof b); // number
//I expected the value a to be 2 of type
//number just as b
//If I toggle the boolean value of arr,
//both a and b evaluates to 2 of
//type number
+ with two operands is the "addition operator," which may do mathematical addition or string addition (concatenation) depending on its operands.
When any operand to + is an object, the JavaScript engine converts the object to a primitive. In your case, the array is an object. Converting an array to a primitive yields a string (as though you'd called their toString method, which basically does .join()). So then the + operator is dealing with a number and a string. When either operand is a string, + converts the other operand to string, and so you get "2" as the result. That is:
2 + [] becomes
2 + "" which becomes
"2" + "" which is
"2"
- with two operands is the "subtraction operator" and it's very different. It's only for math, it doesn't have any string meaning. That means it converts its arguments to numbers. Converting an array to number involves first converting it to a string, then converting the string to a number. [] becomes "" which converts to 0. So:
2 - [] becomes
2 - "" which becomes
2 - 0 which is
2
In C# the following code returns 2:
double d = 2.9;
int i = (int)d;
Debug.WriteLine(i);
In Javascript, however, the only way of converting a "double" to an "int" that I'm aware of is by using Math.round/floor/toFixed etc. Is there a way of converting to an int in Javascript without rounding? I'm aware of the performance implications of Number() so I'd rather avoid converting it to a string if at all possible.
Use parseInt().
var num = 2.9
console.log(parseInt(num, 10)); // 2
You can also use |.
var num = 2.9
console.log(num | 0); // 2
I find the "parseInt" suggestions to be pretty curious, because "parseInt" operates on strings by design. That's why its name has the word "parse" in it.
A trick that avoids a function call entirely is
var truncated = ~~number;
The double application of the "~" unary operator will leave you with a truncated version of a double-precision value. However, the value is limited to 32 bit precision, as with all the other JavaScript operations that implicitly involve considering numbers to be integers (like array indexing and the bitwise operators).
edit — In an update quite a while later, another alternative to the ~~ trick is to bitwise-OR the value with zero:
var truncated = number|0;
Similar to C# casting to (int) with just using standard lib:
Math.trunc(1.6) // 1
Math.trunc(-1.6) // -1
Just use parseInt() and be sure to include the radix so you get predictable results:
parseInt(d, 10);
There is no such thing as an int in Javascript. All Numbers are actually doubles behind the scenes* so you can't rely on the type system to issue a rounding order for you as you can in C or C#.
You don't need to worry about precision issues (since doubles correctly represent any integer up to 2^53) but you really are stuck with using Math.floor (or other equivalent tricks) if you want to round to the nearest integer.
*Most JS engines use native ints when they can but all in all JS numbers must still have double semantics.
A trick to truncate that avoids a function call entirely is
var number = 2.9
var truncated = number - number % 1;
console.log(truncated); // 2
To round a floating-point number to the nearest integer, use the addition/subtraction trick. This works for numbers with absolute value < 2 ^ 51.
var number = 2.9
var rounded = number + 6755399441055744.0 - 6755399441055744.0; // (2^52 + 2^51)
console.log(rounded); // 3
Note:
Halfway values are rounded to the nearest even using "round half to even" as the tie-breaking rule. Thus, for example, +23.5 becomes +24, as does +24.5. This variant of the round-to-nearest mode is also called bankers' rounding.
The magic number 6755399441055744.0 is explained in the stackoverflow post "A fast method to round a double to a 32-bit int explained".
// Round to whole integers using arithmetic operators
let trunc = (v) => v - v % 1;
let ceil = (v) => trunc(v % 1 > 0 ? v + 1 : v);
let floor = (v) => trunc(v % 1 < 0 ? v - 1 : v);
let round = (v) => trunc(v < 0 ? v - 0.5 : v + 0.5);
let roundHalfEven = (v) => v + 6755399441055744.0 - 6755399441055744.0; // (2^52 + 2^51)
console.log("number floor ceil round trunc");
var array = [1.5, 1.4, 1.0, -1.0, -1.4, -1.5];
array.forEach(x => {
let f = x => (x).toString().padStart(6," ");
console.log(`${f(x)} ${f(floor(x))} ${f(ceil(x))} ${f(round(x))} ${f(trunc(x))}`);
});
As #Quentin and #Pointy pointed out in their comments, it's not a good idea to use parseInt() because it is designed to convert a string to an integer. When you pass a decimal number to it, it first converts the number to a string, then casts it to an integer. I suggest you use Math.trunc(), Math.floor(), ~~num, ~~v , num | 0, num << 0, or num >> 0 depending on your needs.
This performance test demonstrates the difference in parseInt() and Math.floor() performance.
Also, this post explains the difference between the proposed methods.
What about this:
if (stringToSearch.IndexOfAny( ".,;:?!".ToCharArray() ) == -1) { ... }
I think that the easiest solution is using the bitwise not operator twice:
const myDouble = -66.7;
console.log(myDouble); //-66.7
const myInt = ~~myDouble;
console.log(myInt); //-66
const myInt = ~~-myDouble;
console.log(myInt); //66
I was checking out an online game physics library today and came across the ~~ operator. I know a single ~ is a bitwise NOT, would that make ~~ a NOT of a NOT, which would give back the same value, wouldn't it?
It removes everything after the decimal point because the bitwise operators implicitly convert their operands to signed 32-bit integers. This works whether the operands are (floating-point) numbers or strings, and the result is a number.
In other words, it yields:
function(x) {
if(x < 0) return Math.ceil(x);
else return Math.floor(x);
}
only if x is between -(231) and 231 - 1. Otherwise, overflow will occur and the number will "wrap around".
This may be considered useful to convert a function's string argument to a number, but both because of the possibility of overflow and that it is incorrect for use with non-integers, I would not use it that way except for "code golf" (i.e. pointlessly trimming bytes off the source code of your program at the expense of readability and robustness). I would use +x or Number(x) instead.
How this is the NOT of the NOT
The number -43.2, for example is:
-43.210 = 111111111111111111111111110101012
as a signed (two's complement) 32-bit binary number. (JavaScript ignores what is after the decimal point.) Inverting the bits gives:
NOT -4310 = 000000000000000000000000001010102 = 4210
Inverting again gives:
NOT 4210 = 111111111111111111111111110101012 = -4310
This differs from Math.floor(-43.2) in that negative numbers are rounded toward zero, not away from it. (The floor function, which would equal -44, always rounds down to the next lower integer, regardless of whether the number is positive or negative.)
The first ~ operator forces the operand to an integer (possibly after coercing the value to a string or a boolean), then inverts the lowest 31 bits. Officially ECMAScript numbers are all floating-point, but some numbers are implemented as 31-bit integers in the SpiderMonkey engine.
You can use it to turn a 1-element array into an integer. Floating-points are converted according to the C rule, ie. truncation of the fractional part.
The second ~ operator then inverts the bits back, so you know that you will have an integer. This is not the same as coercing a value to boolean in a condition statement, because an empty object {} evaluates to true, whereas ~~{} evaluates to false.
js>~~"yes"
0
js>~~3
3
js>~~"yes"
0
js>~~false
0
js>~~""
0
js>~~true
1
js>~~"3"
3
js>~~{}
0
js>~~{a:2}
0
js>~~[2]
2
js>~~[2,3]
0
js>~~{toString: function() {return 4}}
4
js>~~NaN
0
js>~~[4.5]
4
js>~~5.6
5
js>~~-5.6
-5
In ECMAScript 6, the equivalent of ~~ is Math.trunc:
Returns the integral part of a number by removing any fractional digits. It does not round any numbers.
Math.trunc(13.37) // 13
Math.trunc(42.84) // 42
Math.trunc(0.123) // 0
Math.trunc(-0.123) // -0
Math.trunc("-1.123")// -1
Math.trunc(NaN) // NaN
Math.trunc("foo") // NaN
Math.trunc() // NaN
The polyfill:
function trunc(x) {
return x < 0 ? Math.ceil(x) : Math.floor(x);
}
The ~ seems to do -(N+1). So ~2 == -(2 + 1) == -3 If you do it again on -3 it turns it back: ~-3 == -(-3 + 1) == 2 It probably just converts a string to a number in a round-about way.
See this thread: http://www.sitepoint.com/forums/showthread.php?t=663275
Also, more detailed info is available here: http://dreaminginjavascript.wordpress.com/2008/07/04/28/
Given ~N is -(N+1), ~~N is then -(-(N+1) + 1). Which, evidently, leads to a neat trick.
Just a bit of a warning. The other answers here got me into some trouble.
The intent is to remove anything after the decimal point of a floating point number, but it has some corner cases that make it a bug hazard. I'd recommend avoiding ~~.
First, ~~ doesn't work on very large numbers.
~~1000000000000 == -727279968
As an alternative, use Math.trunc() (as Gajus mentioned, Math.trunc() returns the integer part of a floating point number but is only available in ECMAScript 6 compliant JavaScript). You can always make your own Math.trunc() for non-ECMAScript-6 environments by doing this:
if(!Math.trunc){
Math.trunc = function(value){
return Math.sign(value) * Math.floor(Math.abs(value));
}
}
I wrote a blog post on this for reference: http://bitlords.blogspot.com/2016/08/the-double-tilde-x-technique-in.html
Converting Strings to Numbers
console.log(~~-1); // -1
console.log(~~0); // 0
console.log(~~1); // 1
console.log(~~"-1"); // -1
console.log(~~"0"); // 0
console.log(~~"1"); // 1
console.log(~~true); // 1
console.log(~~false); // 0
~-1 is 0
if (~someStr.indexOf("a")) {
// Found it
} else {
// Not Found
}
source
~~ can be used as a shorthand for Math.trunc()
~~8.29 // output 8
Math.trunc(8.29) // output 8
Here is an example of how this operator can be used efficiently, where it makes sense to use it:
leftOffset = -(~~$('html').css('padding-left').replace('px', '') + ~~$('body').css('margin-left').replace('px', '')),
Source:
See section Interacting with points
Tilde(~) has an algorihm -(N+1)
For examle:
~0 = -(0+1) = -1
~5 = -(5+1) = -6
~-7 = -(-7+1) = 6
Double tilde is -(-(N+1)+1)
For example:
~~5 = -(-(5+1)+1) = 5
~~-3 = -(-(-3+1)+1) = -3
Triple tilde is -(-(-(N+1)+1)+1)
For example:
~~~2 = -(-(-(2+1)+1)+1) = -3
~~~3 = -(-(-(3+1)+1)+1) = -4
Same as Math.abs(Math.trunc(-0.123)) if you want to make sure the - is also removed.
In addition to truncating real numbers, ~~ can also be used as an operator for updating counters in an object. The ~~ applied to an undefined object property will resolve to zero, and will resolve to the same integer if that counter property already exists, which you then increment.
let words=["abc", "a", "b", "b", "bc", "a", "b"];
let wordCounts={};
words.forEach( word => wordCounts[word] = ~~wordCounts[word] + 1 );
console.log("b count == " + wordCounts["b"]); // 3
The following two assignments are equivalent.
wordCounts[word] = (wordCounts[word] ? wordCounts[word] : 0) + 1;
wordCounts[word] = ~~wordCounts[word] + 1;