15

how to type cast a number in javascript?

a = (unsigned int)atoi(arg1);
b = (unsigned int)atoi(arg2);

Assuming that a and b can be signed.

I want to convert a 4 byte signed integer into a 4 byte unsigned integer.

I know there is no such thing as type casting or signed/unsigned in javascript. I am looking for an easy to understand algorithm.

doppelgreener
  • 5,752
  • 8
  • 42
  • 59
Matthias
  • 1,304
  • 3
  • 22
  • 54

4 Answers4

39

You can try a = arg1>>>0, but I'm not sure it will do what you are looking for.

See this question for more details.

Community
  • 1
  • 1
Vatev
  • 7,017
  • 1
  • 28
  • 37
13

you can also use

(new Uint32Array([arg1]))[0]

e.g.

< (new Uint32Array([-1]))[0]
> 4294967295

Explanation: JavaScript does not follow traditional machine architecture integer casting conventions like C does, preferring type simplicity and portability over low level efficiency. However the typed-arrays (Uint8Array et al) in JavaScript were added specifically for the purpose of efficient and well defined multi byte and bit-level operations. Thus we can exploit this fact to access well defined and built-in bit casting operations. The syntax in the example above:

  1. Creates a natural-number array of the input
  2. Constructs a typed array (Uint32Array) from that number. This is where the cast will occur.
  3. Extracts the first (0-th) element of that typed array, which contains the cast result.
joth
  • 1,037
  • 1
  • 10
  • 6
  • 1
    This is the correct answer, no questions. About the magic part. Data in computers are represented in bits, and one byte is 8 bits. To create a negative number, you set the last bit to 1. Meaning you have 7 bits left to store your number (7 bits to store a plus value if you set the last bit to 0, or 7 bits to represent a negative number if you set the last bit to 1). Meaning there is no magic, you just say the compiler how to understand the value. You can for example, treat a positive number as negative if you say, red it as signed number. (U stands for unsigned in Uint32) – David Gatti Jun 18 '16 at 12:13
  • Belatedly added an explanation. – joth May 29 '17 at 23:12
4

convert signed byte to unsigned byte, javascript:

-5 & 0xff // = 251   , signed to unsigned byte
251 <<24 >>24 // = -5  , unsinged byte to signed

the first makes all first bits 0 except the 1st byte

the second found on

https://blog.vjeux.com/2013/javascript/conversion-from-uint8-to-int8-x-24.html

basically, in a number, there are 4 bytes. in a positive number, the 3 first bytes are 0 and all 0 bits are zero. in a negative number, the 3 first bytes are 1 and all 0 bits are one and all 1 bits are zero. In bytes the most significant bit of 4th byte is used for sign;

shifting bits to left makes the 1st bit 1 of 1st byte to be as the 1st bit of 4th byte, then shifting again to the right, drags the most significant bit across. so if the sign bit is 1. it makes many 1 bits in front 3 bytes. so it is a side effect of shifting but it works.

for example: like you start from
?1111111 the first bit is a sign bit - ?, 
but in a larger variable,  so it is:

00000000_00000000_00000000_?1111111
shift to left
?1111111_........_........_........
shift to right
????????_????????_????????_?1111111
this is the effect,
it drags the edge bit across the shift
Shimon Doodkin
  • 3,676
  • 29
  • 33
3

All (primitive) numbers in Javascript are IEEE748 doubles, giving you 52 bits of integer precision.

The problem with signed vs unsigned is that all of the Javascript bitwise operators apart from >>> convert the numbers into a 32-bit signed number - that is, they take the least significant 32 bits and throw away the rest, and then the resulting bit 31 is sign extended to give a signed result.

If you are starting with the four known byte values, you can get around the problem with the bitwise operators by using simple multiplications and additions instead, which use all 52 bits of integer precision, e.g.

var a = [ 1, 2, 3, 4];  // 0x01020304
var unsigned = a[0] * (1 << 24) + a[1] * (1 << 16) + a[2] * (1 << 8) + a[3]
Alnitak
  • 313,276
  • 69
  • 379
  • 466