I have encountered a discrepancy when translating simple JS code to C and/or Perl, specifically related to arithmetic operations (+ - * / << >>
) on integers causing overflow. My goal is to replicate the exact behavior of JS, including handling overflows. The JS variables are not explicitly BigInt, but just standard JS var.
JS (via node.js or Firefox's developer tools' console):
function calc(a, b){
return (a<<b) + (a<<b);
}
var x = calc(1, 30);
result:
2147483648
C:
#include <stdio.h>
#include <stdint.h>
int main(void){
int32_t lop = 1<<30; //1073741824;
int32_t rop = 1<<30; //1073741824;
int32_t res = lop + rop;
printf("1<<30 + 1<<30 : %d\n", res);
}
result:
1<<30 + 1<<30 : -2147483648
Perl:
sub to32bit { unpack("l", pack("L", $_[0])) } # Corion @ PerlMonks
print to32bit(to32bit(1<<30)+to32bit(1<<30));
result:
-2147483648
Is there truly a discrepancy in my approach, or am I missing something?
How can I ensure that the C/Perl code behaves exactly like JS?
My aim is to replicate JS's precise behavior in C/Perl without altering the original JS code.
For further discussion, refer to this link.
Edit: February 2024 - A new CPAN module Math::JS (available at ) has been developed by Sisyphus.