Why plus sign in front of JavaScript equation with toFixed? - javascript

I was just going through the source code of particles.js and came across the following line of code:
this.speed.x = +((-options.maxSpeedX / 2) +
(Math.random() * options.maxSpeedX)).toFixed(2);
That line of code can be found HERE too.
Now the + sign right at the beginning of the expression has no difference in the equation. E.g.
(-2 + 5) = 3
Now...
+(-2 + 5) = 3
Another example:
(-5 + 2) = -3
Now..
+(-5 + 2) = -3
Why the plus sign at the beginning of the expression when it makes no difference to the outcome of the equation?

Your code is basically
x = +someNumber.toFixed(2);
Which is
x = +(someNumber.toFixed(2));
because the function call has a higher precedence than the + operator.
This makes
x = +(someNumberFormattedAsARoundedString);
Applying the unary plus operator converts the string back to a number. The net result is the rounding of the initial someNumber.
In this specific case you linked to, this looks like bad practice due to ignorance of what is a IEEE754 floating point number. It looks like the author tried to get fixed precision numbers, thus confusing the number storage and their representation (i.e. formatting).

.toFixed() returns a String. You need to cast it to Number. The unary plus + operator is used to convert/cast the string to number.
Returns
A string representation of numObj that does not use exponential notation and has exactly digits digits after the decimal place. The number is rounded if necessary, and the fractional part is padded with zeros if necessary so that it has the specified length. If numObj is greater than 1e+21, this method simply calls Number.prototype.toString() and returns a string in exponential notation.
It is not required in the cases when the result is already a number. Example, +(-2 + 5).
However, in below operation it is required.
this.speed.x = +((-options.maxSpeedX / 2) +
(Math.random() * options.maxSpeedX)).toFixed(2);

Related

Math.sin() Different Precision between Node.js and C#

I have a problem in precision in the last digit after the comma.The javascript code generates one less Digit in compare with the C# code.
Here is the simple Node.js code
var seed = 45;
var x = Math.sin(seed) * 0.5;
console.log(x);//0.4254517622670592
Here is the simple C# code
public String pseudorandom()
{
int seed = 45;
double num = Math.Sin(seed) * (0.5);
return num.ToString("G15");//0.42545176226705922
}
How to achieve the same precision?
The JavaScript Number type is quite complex. It looks like floating point number will probably be like IEEE 754-2008 but some aspects are left to the implementation. See http://www.ecma-international.org/ecma-262/6.0/#sec-number-objects sec 12.7.
There is a note
The output of toFixed may be more precise than toString for some
values because toString only prints enough significant digits to
distinguish the number from adjacent number values. For example,
(1000000000000000128).toString() returns "1000000000000000100", while
(1000000000000000128).toFixed(0) returns "1000000000000000128".
Hence to get full digit accuracy you need something like
seed = 45;
x = Math.sin(seed) * 0.5;
x.toFixed(17);
// on my platform its "0.42545176226705922"
Also, note the specification for how the implementation of sin and cos allow for some variety in the actual algorithm. It's only guaranteed to within +/- 1 ULP.
Using java the printing algorithm is different. Even forcing 17 digits gives the result as 0.42545176226705920.
You can check you are getting the same bit patterns using x.toString(2) and Double.doubleToLongBits(x) in Java.
return num.ToString("G15");//0.42545176226705922
actually returns "0.425451762267059" (no significant digit + 15 decimal places in this example), and not the precision shown in the comment after.
So you would use:
return num.ToString("G16");
to get "0.4254517622670592"
(for your example - where the significant digit is always 0) G16 will be 16 decimal places.

Javascript : How to increase a fraction value in a textbox ? example: 0.10 to 0.11 [duplicate]

This question already has answers here:
How to add two strings as if they were numbers? [duplicate]
(20 answers)
how to sum two numbers from input tag? [duplicate]
(2 answers)
Closed 9 years ago.
I need to increase a fraction in a text box
using javascript.
the goal is to add 1 penny until it is 0.99
and then it will be 1.00 and 1.01
how can this be done in javascript?
this is what is not working.
var a;
a = document.getElementById('a1').value;
a = a+a;
alert(a);
alert returns
0.100.10
Additional Info
var a;
a = parseFloat(document.getElementById('b13').value);
a = a+a;
alert(a);
returns
0.2
i would rather see 0.20
but most importantly, how do increase this by 0.01 at a time ?
SOLVED:
both
var a;
a = parseFloat(document.getElementById('a1').value);
a = a+0.01;
alert(a);
}
and ...
document.getElementById('a1').value = +document.getElementById('a1').value + 0.01
worked fine.
Text box returns the value as string so parse it
var a;
a = parseFloat(document.getElementById('a1').value);
a = (a+a).toFixed(2);
alert(a);
And it doesn't adds 0.01 to a .. It doubles the a so use something like this.
var a;
a = parseFloat(document.getElementById('a1').value);
a = (a + 0.01).toFixed(2);
alert(a);
a = a+a doesn't add .01. It would double a if a was a number, but since javascript is seeing it as a string, it just concatenates it.
You want a = +a+0.01.
This will add 0.01 to the value of a. The initial + is to make sure that javascript treats a as a number instead of a string.
This will work fine for your alert, but then you still need to set the value back:
document.getElementById('a1').value = a
Or, to put it all in one line (using the toFixed addition from HMR):
document.getElementById('a1').value = (+document.getElementById('a1').value + 0.01).toFixed(2)
First convert a into float like this,
a = parseFloat(document.getElementById('a1').value);
Then add and convert a to float like this,
a = (a + a).toFixed(2)
and alert the answer.
a is containing a string, instead of a number. string + string returns the concatenation of the two strings - you haven't told Javascript it's a number, so it doesn't treat it like one.
You can use parseFloat and parseInt to turn strings into floating point numbers (have decimal places) or integers (do not). http://www.javascripter.net/faq/convert2.htm
However, be aware that floating point numbers have inaccuracies due to being stored in limited amount of memory - they will round off after a certain number of places (and not decimal places - binary places, for example 0.1 cannot be represented exactly as a floating point number, despite being only one decimal place in base 10!), and if you need to do important financial calculations, you should be aware of this inaccuracy (for example, you might use a fixed point number system instead). Read What Every Computer Scientist Should Know About Floating-Point Arithmetic for more information.

JavaScript pack integers and calculate arbitrary precision float:

I need to do the following in JavaScript and so far been unable to find solutions to do it seamlessly:
Grab two integers in a specific order and pack them like Python's struct module.
This packed value, (bonus for supporting different endianness than host) will be turned into a 64 bit float (double). They must be arbitrary thus I might get an exponent representation of the integer (say, they could be 0xdeadbeef and 500):
In exp form:
1.0883076389305e-311
1.0883076389305000 * 10 ^ - 311
I need to convert it to the arbitrary precision, non-exponent form, so:
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000108830763893050000000000000000000000000000000000000000000000000000000000000000000000000000
That number converted to a string :)
I haven't found a way to do this in Javascript and I have to output some numbers like that which must support arbitrary precision, or at least, of a scale up to the 1024 exponent (or, say 400) of doubles.
Thanks!!
Note: I do need the "packing/unpacking' to be a faithful representation of those two numbers converted to a double/64bit float. But I don't care about, say, exporting to a string or raw buffer. As long as I get an arbitrary precision double representation for the double it's all fine.
1: Khronos has a specification in progress for a DataView interface as part of the WebGL TypedArray requirements, which combined with Int32Array and Float64Array would let you write your two ints into a buffer, and read them back out as a double.
Unfortunately browser support for this isn't common yet - to test your browser visit http://html5test.com/ and look at the section entitled "Native binary data".
Without the TypedArray support above I don't think there's any way to do this using bit-twiddling since Javascript's bit operators treat numbers as 32-bit unsigned values, so you'd have no access to the higher-order bits.
2: double variables don't have any specific form, IEE754 is just an internal representation.
3: that's the point at which you can attempt to show the actual precision. Unfortunately the built-in method, e.g. Number.toFixed(), doesn't support showinng more than 20 decimal places. You will need to parse the exponential form and manually construct a string with the appropriate number of leading zeros.
NB - the exponent range of a double is 2^1024, not 10^1024, hence the real limit is actually ~1.0E±308 - your example figure is smaller than that range.
EDIT actually, there might be a way, but I can't guarantee the precision of this:
take your two integers, call them hi and lo.
extract the exponent - exp = (hi >> 20) & 0x7ff
extract the sign - sign = (hi >> 31)
extract the mantissa - ((hi & 0xfffff) * Math.pow(2, 32) + lo) / Math.pow(2, 52)
result = (1 + m) * (Math.pow(2.0, exp - 1023))
if (sign) result *= -1
EDIT 2 - it works! See http://jsfiddle.net/alnitak/assXS/
var hex2double = function(input) {
var hi = parseInt(input.substring(0, 8), 16);
var lo = parseInt(input.substring(8 ), 16);
var p32 = 0x100000000;
var p52 = 0x10000000000000;
var exp = (hi >> 20) & 0x7ff;
var sign = (hi >> 31);
var m = 1 + ((hi & 0xfffff) * p32 + lo) / p52;
m = exp ? (m + 1) : (m * 2.0);
return (sign ? -1 : 1) * m * Math.pow(2, exp - 1023);
};
Enter a floating point number at http://babbage.cs.qc.edu/IEEE-754/Decimal.html, take the resulting hex string from the bottom row of output, and pass it to the function above. You should see an alert containing the original value.
EDIT 3 code fixed to account for the special case when the exponent bits are all zero.
I think you need a big number library for JavaScript such as http://jsfromhell.com/classes/bignumber.

Fastest way to create this number?

I'm writing a function to extend a number with sign to a wider bit length. This is a very frequently used action in the PowerPC instruction set. This is what I have so far:
function exts(value, from, to) {
return (value | something_goes_here);
}
value is the integer input, from is the number of bits that the value is using, and to is the target bit length.
What is the most efficient way to create a number that has to - from bits set to 1, followed by from bits set to 0?
Ignoring the fact that JavaScript has no 0b number syntax, for example, if I called
exts(0b1010101010, 10, 14)
I would want the function to OR the value with 0b11110000000000, returning a sign-extended result of 0b11111010101010.
A number containing p one bits followed by q zero bits can be generated via
((1<<p)-1)<<q
thus in your case
((1<<(to-from))-1)<<from
or much shorter
(1<<to)-(1<<from)
if you have the number 2^q (= 1 shifted left by q) represented as an integer of width p + q bits, it has the representation:
0...010...0
p-1 q
then 2^q - 1 has the representation
0...01...1
p q
which is exactly the opposite of you want. So just flip the bits
hence what you want is NOT((1 LEFT SHIFT by q) - 1)
= ~((1 << q) - 1) in c notation
I am not overly familiar with binary mathematics in JavaScript... But if you need to OR a number with 0b11110000000000, then I assume you would just convert that to decimal (which would get you 15360), and do value | 15360.
Relevant info that you may find useful: parseInt("11110000000000", 2) converts a binary number (specified as a string) to a decimal number, and (15360).toString(2) converts a decimal number (15360 in this case) to a binary number (the result is a string).
Revised solution
There's probably a more elegant and mathematical method, but here's a quick-and-dirty solution:
var S = "";
for(var i=0;i<p;i++)
S += "1";
for(i=0;i<q;i++)
S += "0";
S = parseInt(S, 2); // convert to decimal

Javascript parsing int64

How can I convert a long integer (as a string) to a numerical format in Javascript without javascript rounding it?
var ThisInt = '9223372036854775808'
alert(ThisInt+'\r' +parseFloat(ThisInt).toString()+'\r' +parseInt(ThisInt).toString());
I need to perform an addition on it before casting it back as a string & would prefer not to have to slice it two if at all possible.
All Numbers in Javascript are 64 bit "double" precision IEE754 floating point.
The largest positive whole number that can therefore be accurately represented is 2^53 - 1. The remaining bits are reserved for the exponent.
Your number is exactly 1024 times larger than that, so loses 3 decimal digits of precision. It simply cannot be represented any more accurately.
In ES6 one can use Number.isSafeInteger( # ) to test a number to see if its within the safe range:
var ThisInt = '9223372036854775808';
console.log( Number.isSafeInteger( parseInt( ThisInt ) ) );
There is also a BigInteger library available which should be able to help, though, and avoid you having to do all the string and bit twiddling yourself.
EDIT 2018/12 there's now a native BigInt class (and new literal syntax) landed in Chrome and NodeJS.
With a little help from recursion, you can directly increment your decimal string, be it representing a 64 bit number or more...
/**
* Increment a decimal by 1
*
* #param {String} n The decimal string
* #return The incremented value
*/
function increment(n) {
var lastChar = parseInt(n.charAt(n.length - 1)),
firstPart = n.substr(0, n.length - 1);
return lastChar < 9
? firstPart + (lastChar + 1)
: firstPart
? increment(firstPart) + "0"
: "10";
}
You cannot do this with standard Javascript. But as always, there is a nifty little library to help us out, in this case BigInt.js, which will let you use arbitrary-precision integers.
Have you tried using the Number class?
var num = new Number(parseFloat(ThisInt))
Just use Number(ThisInt) for this instead of Int or float

Categories