Always Positive in Javascript

JavaScript and client side scripting.

Moderator: General Moderators

Post Reply
User avatar
JellyFish
DevNet Resident
Posts: 1361
Joined: Tue Feb 14, 2006 7:18 pm
Location: San Diego, CA

Always Positive in Javascript

Post by JellyFish »

I'm trying to return the positive version of a number in JavaScript. The best I can do is:

Code: Select all

 
Math.sqrt(x*x); // returns the 3 if x = either -3 or 3
 
But I don't know if the Math.sqrt function is that fast so I was wondering if there was a more efficient operation for this.

Any ideas?
Last edited by JellyFish on Fri Jan 30, 2009 9:46 pm, edited 1 time in total.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Allways Positive in Javascript

Post by VladSun »

Math.abs() :)
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
JellyFish
DevNet Resident
Posts: 1361
Joined: Tue Feb 14, 2006 7:18 pm
Location: San Diego, CA

Re: Allways Positive in Javascript

Post by JellyFish »

Dur... Why didn't I think of that? lol

Thanks.

Btw, I wonder if there is any other mathematical way of always returning the positive version of a number. I looked at the Math.abs function in Google Chrome and this is what they're doing:

Code: Select all

function abs(x) {
  if (_IsSmi(x)) {
    return x >= 0 ? x : -x;
  } else {
    return Math_abs(ToNumber(x));
  }
}
Hmm, strange. I wonder if my solution (Math.sqrt(x*x)) is better?

[EDIT] I have an idea. Is there a way to easily get the binary number 01111111111111111111111111111111?
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Allways Positive in Javascript

Post by VladSun »

JellyFish wrote:Dur... Why didn't I think of that? lol

Thanks.

Btw, I wonder if there is any other mathematical way of always returning the positive version of a number. I looked at the Math.abs function in Google Chrome and this is what they're doing:

Code: Select all

function abs(x) {
  if (_IsSmi(x)) {
    return x >= 0 ? x : -x;
  } else {
    return Math_abs(ToNumber(x));
  }
}
I don't know what _IsSmi() is, but "return x >= 0 ? x : -x;" will do the work for any numeric x.

JellyFish wrote:Hmm, strange. I wonder if my solution (Math.sqrt(x*x)) is better?
Sorry, it's not good. It's too expensive - multiplication, square root ...
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Allways Positive in Javascript

Post by VladSun »

JellyFish wrote:[EDIT] I have an idea. Is there a way to easily get the binary number 0111 1111 1111 1111 1111 1111 1111 1111?
Let's hear it :)

Code: Select all

var x = 0x1FFFFFFFFFFFFFFF;
Though I'm pretty sure it won't work.

Code: Select all

var x = -1024;x = x << 1;alert(x);
:cry:
Last edited by VladSun on Tue Jul 26, 2011 6:45 am, edited 2 times in total.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
JellyFish
DevNet Resident
Posts: 1361
Joined: Tue Feb 14, 2006 7:18 pm
Location: San Diego, CA

Re: Allways Positive in Javascript

Post by JellyFish »

Well as it turns out, my original idea is flawed, due to the fact that I didn't understand the binary representation of numbers in JavaScript.

I guess the standard by which JavaScript (or ECMAScript) inherits for it's numbers is IEEE-745. In the standard negative numbers are almost opposite in binary form to there equivalent positive:

0000 0000 0000 0000 0000 0000 0000 0011 = 3 decimal
1111 1111 1111 1111 1111 1111 1111 1101 = -3 decimal

Basically the last bit (left most bit) is the signed bit, the bit which tells you whether the number is positive or negative. But when a number is negative all the bits are inverted, meaning all 1s are 0s and 0s are 1s. I thought that maybe a negative number would just be the same as a positive number only the signed bit was turned on. But in fact the whole thing is inverted.

My original idea was to get a bitmask to turn off the signed bit:

0111 1111 1111 1111 1111 1111 1111 1111

and use this to do a bitwise AND operation on another number, causing that number to always be positive. It would have been simple, but now I need to put a little more thought into it.

Smiley face to you.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Allways Positive in Javascript

Post by VladSun »

JellyFish wrote:My original idea was to get a bitmask to turn off the signed bit:

0111 1111 1111 1111 1111 1111 1111 1111

and use this to do a bitwise AND operation on another number, causing that number to always be positive. It would have been simple, but now I need to put a little more thought into it.
That's why I gave you the left shift bitwise operator example "<<" it will shift all bits to the left, effectively dropping the most significant bit (MSB) (i.e. the one we expect to be the sign bit). The right shift will shift all bits to the right and will insert a 0 value for the new MSB.

So:

Code: Select all

(X << 1) >> 1
will always return the absolute value of X regardless of how long X is (so we don't need to precalculate bitmask). But ... if the MSB is indeed the sign bit.
JellyFish wrote:I guess the standard by which JavaScript (or ECMAScript) inherits for it's numbers is IEEE-745. In the standard negative numbers are almost opposite in binary form to there equivalent positive:

0000 0000 0000 0000 0000 0000 0000 0011 = 3 decimal
1111 1111 1111 1111 1111 1111 1111 1101 = -3 decimal
Are you sure about that? I couldn't find IEEE-745 standard.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
JellyFish
DevNet Resident
Posts: 1361
Joined: Tue Feb 14, 2006 7:18 pm
Location: San Diego, CA

Re: Always Positive in Javascript

Post by JellyFish »

I think this is the one: http://en.wikipedia.org/wiki/IEEE_754

I tested (X << 1) >> 1 and it doesn't seem to do as intended. I don't really see how it would. What were/are you thinking?
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Always Positive in Javascript

Post by VladSun »

JellyFish wrote:I tested (X << 1) >> 1 and it doesn't seem to do as intended. I don't really see how it would. What were/are you thinking?
Well, in JS it doesn't work (try it in C/C++ e.g.). I've already explained what it's all about:

Let's have:

Code: Select all

x = -5 (dec)
x = 1101 (bin)
Then

Code: Select all

y = x << 1
So

Code: Select all

y == 1010
Then

Code: Select all

z = y >> 1
So

Code: Select all

z == 0101 (bin)
z == 5 (dec)
Or

Code: Select all

x = -5; 
x = (x << 1) >> 1;
x == 5;
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
JellyFish
DevNet Resident
Posts: 1361
Joined: Tue Feb 14, 2006 7:18 pm
Location: San Diego, CA

Re: Always Positive in Javascript

Post by JellyFish »

I see but this only works on integers in other languages. Like I said earlier JavaScript uses a very different standard on dealing with numbers. A negative number in JavaScript is an inverted positive number plus one:

Code: Select all

-3 = ~3+1;
The reason why the above statement is true is because -1 equals all 1s in binary:

Code: Select all

-1 = 1111...1111
-2 = 1111...1110
-3 = 1111...1101
...etc.
Yes your examples might work in a language like C/C++, but after this post is called "Always Positive in Javascript". ;)

PS: Why did ECMA decide to use such awkward standard?
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Always Positive in Javascript

Post by VladSun »

You asked "What were/are you thinking?" ;)
I just want to show you an alternative (and better IMHO) approach to your AND-bitmask approach.
It was clear it won't work in JS as I said in my 3rd post ;)
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Always Positive in Javascript

Post by VladSun »

JellyFish wrote:PS: Why did ECMA decide to use such awkward standard?
Oh... :)
Now I remember that from school. I don't know how it's called in English but in Bulgarian it is "additional code".
You can calculate it in two ways - the one you already did (the "reverse code" + binary 1) and:

Code: Select all

X_negative =  M - X_positive
where M is the modulus (again, I don't know the English word) of the machine word. E.g. for 8 bit machine word M = 100000000.
As far as I remember the "additional code" is always used for binary substraction.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
JellyFish
DevNet Resident
Posts: 1361
Joined: Tue Feb 14, 2006 7:18 pm
Location: San Diego, CA

Re: Always Positive in Javascript

Post by JellyFish »

I guess what your saying is the modulus is the number that we never get to but rather just start over again? For example, in 8-bit numbers the 9th bit would be the modulus.

Anyhow, what I need is some kind of formula like so:

+n = f(-n) and +n = f(+n)

What I mean by this is positive n is what f returns regardless of whether f's argument is positive or negative. f is the formula I'm searching for.
Post Reply