Unsigned Integer in Javascript

JavascriptBit ManipulationUnsigned

Javascript Problem Overview


I'm working on a page that processes IP address information, but it's choking on the fact that integers are signed. I am using bitwise operators to speed it up, but the 64th bit (signed/unsigned flag) is messing it up.

Is there any way to force a number to be unsigned in Javascript? It seems to work fine, until subnet is greater than 30, or less than 2.

Try this:

<html>
    <body>
    
    <script type='text/javascript'>
    document.write( (1 << 30) +"<br/>");
    document.write( (1 << 31) +"<br/>");
    document.write( (1 << 32) +"<br/>");
    </script>
    
    </body>
</html>

Result:

> 1073741824 > -2147483648 > 1

Javascript Solutions


Solution 1 - Javascript

document.write( (1 << 31) +"<br/>");

The << operator is defined as working on signed 32-bit integers (converted from the native Number storage of double-precision float). So 1<<31 must result in a negative number.

The only JavaScript operator that works using unsigned 32-bit integers is >>>. You can exploit this to convert a signed-integer-in-Number you've been working on with the other bitwise operators to an unsigned-integer-in-Number:

document.write(( (1<<31)>>>0 )+'<br />');

Meanwhile:

document.write( (1 << 32) +"<br/>");

won't work because all shift operations use only the lowest 5 bits of shift (in JavaScript and other C-like languages too). <<32 is equal to <<0, ie. no change.

Solution 2 - Javascript

Douglas Crockford believes that bitwise operators is one of the bad parts of javascript:

>In Java, the bitwise operators work with integers. JavaScript doesn't have integers. It only has double precision floating-point numbers. So, the bitwise operators convert their number operands into integers, do their business, and then convert them back. In most languages, these operators are very close to the hardware and very fast. In JavaScript, they are very far from the hardware and very slow. JavaScript is rarely used for doing bit manipulation. > > -- Douglas Crockford in "JavaScript: The Good Parts", Appendix B, Bitwise Operators (emphasis added)

Are you sure that bitwise operators really speed up your logic?

Solution 3 - Javascript

Use >>> instead of >> to get an unsigned right shift instead of a sign-extending one. All the other bitwise operators behave the same way regardless of whether ints are signed or not.

Your code breaking "when subnet ... is less than 2" is concerning. That sounds like you may have some bug unrelated to signedness of integers.

Solution 4 - Javascript

Javascript doesn't have integers, all numbers are actually doubles.

The Javascript 1.5 Reference by Mozilla suggests that one can only use bitwise-operations safely for 32 bit numbers.

Solution 5 - Javascript

Here are two functions that convert ipv4 addresses to/from unsigned integers in javascript:

function ip2long(ip) {
	var ipl=0;
	ip.split('.').forEach(function( octet ) {
		ipl<<=8;
		ipl+=parseInt(octet);
	});
	return(ipl >>>0);
}

function long2ip (ipl) {
	return ( (ipl>>>24) +'.' +
		(ipl>>16 & 255) +'.' +
		(ipl>>8 & 255) +'.' +
		(ipl & 255) );
}

Solution 6 - Javascript

What kind of IP addresses do you have? IPv4 uses only 32bit addresses, so JavaScript should be fine (using double which gives you an 52bit integer part). IPv6 uses 128bit addresses, so you'll have to use an array. My guess is that something else is broken.

[EDIT] Build a small library which uses an array of two ints as the internal data type.

Solution 7 - Javascript

Javascript now has a bigint type, you can use the n suffix to make such a number.

So using your example you could do:

<body>
    
    <script type='text/javascript'>
    document.write( (1n << 30n) +"<br/>");
    document.write( (1n << 31n) +"<br/>");
    document.write( (1n << 32n) +"<br/>");
    </script>
    
    </body>
</html>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionbradlis7View Question on Stackoverflow
Solution 1 - JavascriptbobinceView Answer on Stackoverflow
Solution 2 - JavascriptArtem LatyshevView Answer on Stackoverflow
Solution 3 - JavascriptmoonshadowView Answer on Stackoverflow
Solution 4 - JavascriptGeorg SchöllyView Answer on Stackoverflow
Solution 5 - JavascriptFrancis TurnerView Answer on Stackoverflow
Solution 6 - JavascriptAaron DigullaView Answer on Stackoverflow
Solution 7 - JavascriptThayneView Answer on Stackoverflow