How can I efficiently check in asm.js code whether a floating point value is a NaN?
A way that works in principle is to import the global isNaN JavaScript function as a foreign function into the asm.js module. As calling foreign function is expensive, though, so this won't yield optimal code.
Comparing to the value NaN (which is part of the standard library) is no option because the comparision of a NaN to another NaN always yields false by JavaScript semantics.
Examining bits on the heap is also no option because the endianess is not specified.
Why is isNaN not part of the standard library in asm.js?
This property of NaN is commonly used to identify it :
var isNaN = a!=a;
From Wikipedia :
The equality and inequality predicates are non-signaling so x = x
returning false can be used to test if x is a quiet NaN
if (value !== value) {
// Definitely NaN
}
You can make it as a function like this
function isNaN(inputValue) {
return inputValue !== inputValue;
}
Related
I have a scenario where in C#,
decimal? x; // number
decimal? y; // null
c=x*y //c returns null
where in typescript
let x:number=null;
let y:number=12;
c=x*y //c returns 0
**How to get null instead of 0 in typescript ?
I need to set generic way instead of using ternary operator and checking both properties null and returning null.
Is there any compiler options I need to set in tsconfig.json ?**
Why the result is zero in your case
Because in TypeScript/JS/ES, an arithmetic operation involving a number and null will cause null to be implicit converted to a number. And null gets converted to 0.
If you want the "C# null-swallowing" behavior, you indeed need to specify it explicitly :
let c = x === null || y === null ? null : x * y;
The 'natural' behavior in Typescript is the same as JavaScript / EcmaScript : if you have an operation with a number and null, null will be coerced to the number 0.
Is there any compiler options I need to set in tsconfig.json ?**
To my knowledge, there isn't, and there shouldn't be, because that's how arithmetic operations work in ES / JS, and TS has no reason to try changing the arithmetic rules of ES towards the one used by C#.
I need to set generic way instead of using ternary operator and checking both p> properties null and returning null.
Another solution with NaN / undefined
To avoid this code cluttering and have a similar "some special values swallows every operation" like null in C#, you could maybe use NaN (Not a Number) instead of nulls.
This
would be easy to just transform every null into NaN.
any operation like x * y will give NaN if any operand is NaN, without any change to the code that performs computations.
If you really need nulls at the end then you can convert back NaNs to null. (be careful, to test for a number to be NaN, use Math.IsNan(), never try to compare with === NaN as this will always give false, even NaN === NaN)
As a last but not least remark, if one of the operand is undefined, the result of an operation will also be NaN. So actually, you could as well turn your nulls to undefined instead of NaNs, the conversion from C# null to JS/TS undefined might be more natural. Might be easier on the serialization side as well (hint : Newtonsoft.Json.NullValueHandling.Ignore)
It is not sure this can be adapted to your situation, but it's worth checking if you want to avoid cluttering your code with conditionals like I wrote above.
Why is there an isNaN() function in JavaScript whilst isUndefined() must be written as:
typeof(...) != "undefined"
Is there a point I don't see?
In my opinion its really ugly to write this instead of just isUndefined(testValue).
There is simply no need for an isUndefined() function. The reason behind this is explained in the ECMAScript specification:
(Note that the NaN value is produced by the program expression NaN.) In some implementations, external code might be able to detect a difference between various Not-a-Number values, but such behaviour is implementation-dependent; to ECMAScript code, all NaN values are indistinguishable from each other.
The isNaN() function acts as a way to detect whether something is NaN because equality operators do not work (as you'd expect, see below) on it. One NaN value is not equal to another NaN value:
NaN === NaN; // false
undefined on the other hand is different, and undefined values are distinguishable:
undefined === undefined; // true
If you're curious as to how the isNaN() function works, the ECMAScript specification also explains this for us too:
Let num be ToNumber(number).
ReturnIfAbrupt(num).
If num is NaN, return true.
Otherwise, return false.
A reliable way for ECMAScript code to test if a value X is a NaN is an expression of the form X !== X. The result will be true if and only if X is a NaN.
NaN !== NaN; // true
100 !== 100; // false
var foo = NaN;
foo !== foo; // true
The use case var === undefined works almost everywhere, except for the cases covered by this answer, where either undefined is assigned a value, or var is undefined.
The reason such a function cannot exist, is clear from the latter case. If var is undefined, then calling the supposed function isUndefined(var) will result in a ReferenceError. However introducting a new keyword, e.g. isundefined var could address this issue.
But despite being valid, both of the above cases are poor uses of javascript. This is the reason I believe such a keyword does not exist.
isUndefined could be written as
testValue === undefined
like for every other value.
This does not work with NaN however, as NaN !== NaN. Without the ability to use a comparison, there was need for an isNaN function to detect NaN values.
This isn't a direct answer to the question as others have already answered, it's more to highlight libraries that contain an isUndefined() function for anybody looking for quick solution and they're in a position to use them.
Underscore and Lo-dash both contain an isUndefined() function, the latter, because it's built upon Underscore.
http://underscorejs.org/#isUndefined
https://lodash.com/docs#isUndefined
As the title of the question says, I want to avoid the internal number conversion on the isNaN() function.
isNaN() function try to convert the input parameter to a number calling to the Number() function.
For example, if a user puts a value false in an input text who is tested with the isNaN() function to see if the input data is "not a number", the result will be "false", because the Number() function performs a conversion of the value false to 0.
So, it's possible do this? For example, using a pragma or something?
Thanks!
The Number.isNaN() function works differently than the global isNaN(). Number.isNaN() performs no type coercion.
Now, it's important to understand what the concept NaN means. It does not simply mean, "something that is not a number". It's about the floating point system, and specifically about values that don't mean anything. If you want to check whether some unknown value is a number, there are better ways of doing it. The isNaN functions are really about numerics.
A simple test:
function isNumberReally( n ) {
return n === Number(n);
}
That uses the Number constructor to perform a conversion (if it can). It then checks to see whether the result compares as equal to the original using the no-conversions === operator. Only true primitive numbers pass that test; a string like "123" will not.
There really isn't a way to stop isNan from type conversion; Javascript does this automatically. However, you can try to create a a new Number() from the string of what you want to check, like this:
var a=false;
isNaN(Number(String(a)));//returns true;
Or you can check if something equals its number equivalent, like
return num===Number(num);
which basically does not convert types when checking equivalence.
In case you are open to other things, you could always use typeof num==="number";
The isNaN function only works reliably on something that is already a number type. If you give it any other type, it will give results that are not consistent with what you might naturally expect.
Parse the string to a number, then you can use the isNaN function on it. The parsing can either result in a number or the value NaN (which is also of the type number), and isNaN can give you a consistent result from that. Example:
if (isNaN(parseFloat(textbox.value))) {
alert('oops');
}
Note however, that the parsing will happily parse only part of the value. If someone enters a value like 123abc, the parseFloat call will return the number 123.
If you want the input to contain only a number and nothing else, you would need to verify it. For example using a regular expression that only accepts digits:
if (/^\d+$/.test(textbox.value)) {
alert("fine");
}
Try it: In Node.js, or Firefox, open a REPL, and type:
Number.isNaN('asdf');
How can this not be NaN? What is NaN if not this?
You have a misconception here. The fact that NaN means Not a Number does not mean that anything that is not a number is a NaN.
NaN is a special value on floating point arithmethic that represents an undefined result of an operation. For example, 0 / 0 generally yields NaN as a result.
More information here and here.
There is no notion of Number.isNaN() in the language specification. The only specified function is the global isNaN (15.1.2.4), which will correctly return true on anything that isn't a number or cannot get correctly transformed into a number.
Number.isNaN (which returns true on NaN) is probably an implementation detail part of the next standard draft (see remyabel' answer) which could be used internally by isNaN.
Just a note, it seems that Number.IsNaN has limited support.
This output:
console.log(Number.isNaN("blabla"));
Gives false, and false !== NaN:
console.log(false !== NaN)
console.log(false !== Number.NaN);
Here's a reference:
When the Number.isNaN is called with one argument number, the
following steps are taken:
If Type(number) is not Number, return false.
If number is NaN, return true.
Otherwise, return false.
This function differs from the global isNaN function (18.2.3) is that
it does not convert its argument to a Number before determining
whether it is NaN.
I am l33t for I have 1337 reputation.
Try this:
function checkNaN(value)
{
return value !== value;
}
It works because (I believe) NaN is the only thing in JS that does not strictly equal itself.
This is part of the EcmaScript 6 Standard.
Number.isNaN returns whether a value is NaN without coercing the parameter.
Number.isNaN("xmfds"); // false
Number.isNaN("ose"); // false
isNaN returns whether the value is NaN after coercing the parameter to Number type.
isNaN("ose") -> isNaN( Number("ose") ) -> isNaN(NaN); // true
This question already exists:
What does `!!~` mean in javascript? [duplicate]
Closed 8 years ago.
I was reading this blog post which mentioned using:
!!~
I have no idea what this does? at first I thought it would give an error, but the code below does run:
var _sessions = [
"_SID_1",
"_SID_2",
"_SID_3",
"_SID_4"
];
if(!!~_sessions.indexOf("_SID_5")) {
console.log('found');
} else {
console.log('!found');
}
output:
node test.js
!found
~ is the bitwise not operator. It inverts the bits of its operand. ! is the logical not operator. The bitwise not operator will return 0 when applied to -1, which is what indexOf returns when the value is not found in the array. Since 0 evaluates to false, doubly negating it will simply return false (a boolean value, rather than a numeric one):
var index = _sessions.indexOf("_SID_5");
console.log(~index); // 0
console.log(!~index); // true
console.log(!!~index); //false
The bitwise not operator will return a value less than 0 for any other possible value returned by indexOf. Since any other value will evaluate to true, it's just a shorthand method (kind of... they are both the same number of characters!) of checking whether an element exists in an array, rather than explicitly comparing with -1:
if (_sessions.indexOf("_SID_5") > -1) {
// This would work the same way
}
Update
With regards to the performance of this, it appears (in Chrome at least) to be marginally slower than the more common comparison with -1 (which itself is marginally slower than a comparison with 0).
Here's a test case and here's the results:
Update 2
In fact, the code in your question can be shortened, which may have been what the author was attempting to do. You can simply remove the !!, since the ~ will always result in 0 or below (and 0 is the only value that will evaluate to false):
if (~_sessions.indexOf("_SID_5")) {
// This works too
}
However, in a slightly different situation it could make sense to add in the ! operators. If you were to store the result of the bitwise operator in a variable, it would be a numeric value. By applying the logical not operator, you get a boolean value (and applying it again ensures you get the correct boolean value). If for some reason you require a boolean value over a numeric one, it makes a little bit more sense (but you can still just use the normal comparison with -1 or 0):
var inArray = !!~_sessions.indexOf("_SID_5");
console.log(typeof inArray); // boolean
Donald Knuth: "[...] premature optimization is the root of all evil"
For the sake of readability: please use
.indexOf !== -1
This explains it well:
The tilde operator in Javascript
Mixing the two NOT operators together can produce some interesting results:
!~(-2) = false
!~(-1) = true
!~(0) = false
!~(1) = false
!~(2) = false
So this just checks if the value equals -1 or not, and indexOf returns -1 if it does not find a match