bit manipulation - JavaScript: convert a 52-bit integer to 20-bit and 32-bit integers -
in other languages can represent 64-bit integers, possible easily...
how store 64 bit integer in 2 32 bit integers , convert again
how store 64 bit integer in 2 32 bit integers in ruby
// convert 64-bit n 2 32-bit x , y x = (n & 0xffffffff00000000) >> 32 y = n & 0xffffffff
but javascript can not represent 64-bit integers. can represent 52-bit integers without problems.
now means not possible convert 64-bit integer 2 32 bit integers, because it not possible have 64-bit integer in first place.
but still, have 52 bits remaining. question is: how can split 52-bit integer in javascript in 2 32-bit integers (20 high bits , 32 low bits)
can suggest bit manipulation code above 20-bit , 32-bit split in javascript?
related: how 32 bit javascript numbers resulting bit-wise operation converted 64 bit numbers
before start
first of all, link contains minor inaccuracy in stating "any whole number less 252 [...] safely fit in javascript number. " while technically correct, not tight bound: can verified without trouble javascript numbers can store every positive integer 253 (but not 253+1).
some code
without further ado, functions requested, splitting 52-bit numbers bottom 32 bits , 20 top bits:
function to_int52(hi, lo) { /* range checking */ if ((lo !== lo|0) && (lo !== (lo|0)+4294967296)) throw new error ("lo out of range: "+lo); if (hi !== hi|0 && hi >= 1048576) throw new error ("hi out of range: "+hi); if (lo < 0) lo += 4294967296; return hi * 4294967296 + lo; } function from_int52(i) { var lo = | 0; if (lo < 0) lo += 4294967296; var hi = - lo; hi /= 4294967296; if ((hi < 0) || (hi >= 1048576) throw new error ("not int52: "+i); return { lo: lo, hi: hi }; }
where split
i not suggest using these though. javascript bitwise ops signed (@dandavis: js not have uint32s), , sign bit causes headaches when want positive value. plus v8 has optimizations (signed) integers can stored in 31 bits. combining these 2 facts, should split @ no more 30 bits, maximum positive size fit in v8 small integer ("smi").
here's code split numbers 30 low bits , 22 high bits:
function int52_30_get(i) { var lo = & 0x3fffffff; var hi = (i - lo) / 0x40000000; return { lo: lo, hi: hi }; }
you don't want creating objects though. these should inlined (if you're bothering functions @ all):
function int52_30_get_lo(i) { return & 0x3fffffff; } function int52_30_get_hi(i) { return (i - (i & 0x3fffffff)) / 0x40000000; }
and create numbers low , high parts:
function int52_30_new_safe(hi, lo) { return (hi & 0x3fffff) * 0x40000000 + (lo & 0x3fffffff); }
if you're sure hi , lo in range can skip masking:
function int52_30_new(hi, lo) { return hi * 0x40000000 + lo; }
set high , low parts individually:
/* set high part of hi */ = (hi & 0x3fffff) * 0x40000000 + (i & 0x3fffffff); /* set low part of lo */ += (lo & 0x3fffffff) - (i & 0x3fffffff);
if you're sure hi , lo in range:
/* set high part of hi */ = hi * 0x40000000 + (i & 0x3fffffff); /* set low part of lo */ += lo - (i & 0x3fffffff);
(these aren't functions because modify i
.)
for fun, function pull out arbitrary bitfields:
function int52_30_get_bits(i, lsb, nbits) { while (lsb >= 32) { /= 4294967296; lsb -= 32; } return (i / (1<<lsb)) & ((1<<nbits)-1); }
(nbits must <= 31. failure mode when nbits 32 interesting, , due 5 low bits of rhs operand of << being significant, flaw javascript spec shares x86 isa.)
more 52 bits?
it's possible use sign bit store 53-bit binary numbers integers -253 253-1. haven't done should easy enough. after starts bit hairy, , you'll run fact there aren't enough floats go round (many nans) before 264. packing 63 binary digits float should theoretically doable, left exercise reader :)
other approaches
another approach use typed arrays , create float view , int view: lets manipulate underlying binary representation of floats directly. have start worrying endianness , like.
all people suggesting string manipulation crazy.
Comments
Post a Comment