in reply to Re: Trying to translate overflowing JS code to Perl
in thread Trying to translate overflowing JS code to Perl

Pack Man Wow! thanks Corion that does it sub _leftshift32 { my ($n, $s) = @_; unpack "l", pack "L", ($n << $s) }

I probably now have to implement all other arithemtic operators used in that JS code as above.

Replies are listed 'Best First'.
Re^3: Trying to translate overflowing JS code to Perl
by syphilis (Archbishop) on Nov 28, 2023 at 23:30 UTC
    I probably now have to implement all other arithmetic operators used in that JS code as above.

    I can't come up with a better solution ... but if you were to use a perl whose ivsize was 4, then I think (not rigorously tested) you could take care of it with a simple use integer; at the top of the script.
    On perl-5.38.0, built with just that configuration:
    D:\>perl -V:ivsize ivsize='4'; D:\>perl -le "print 1169367104<<5;" 3060008960 D:\>perl -Minteger -le "print 1169367104<<5;" -1234958336
    Cheers,
    Rob
Re^3: Trying to translate overflowing JS code to Perl
by Corion (Patriarch) on Nov 29, 2023 at 07:46 UTC

    I believe you can do the complete calculation without conversion and just at the end downgrade to 32 bit and convert to signed. The following should work:

    sub calc_32bit_signed( $value ) { return unpack( "l", pack "L", ($value & 0xffffffff))) } ... say calc_32bit_signed( $n << 6 ); say calc_32bit_signed( $n + 2 );
      return unpack( "l", pack "L", ($value & 0xffffffff)))

      For which finite numeric values do any of the following 3 renditions differ:
      say unpack( "l", pack "L", ($value & 0xffffffff)); say unpack( "l", pack "L", ($value)); say unpack( "l", pack "l", ($value));
      Sorry ... I'm not trying to be critical ... not even nitpicking ... but I haven't found any such values, and I'm genuinely curious as to whether they exist.)

      Cheers,
      Rob

        Yeah - I wasn't sure either. Reconsidering, I think pack "L" and pack "l" both truncate the value to 32 bits already, so masking out higher bits does not make a difference.

      I don't think that will work, for example consider something like ($value << 6) + length($value). So if the first part overflows in JS then it is necessary to overflow (the first part) in Perl too. Simulating the overflow for the sum would not do. At the moment I am running JS code via shelling out to node.js and that works just fine.

      I was hoping that there would be a module like Math::BigInt where you specify the number of bits or something like use smallint; But now, come to think of it, perhaps a new module could consist of only overloading arithmetic operators. Let me see if I can whip up something based on your pack receipe.

      Edit: see Re: Trying to translate overflowing JS code to Perl with working code for this.

Re^3: Trying to translate overflowing JS code to Perl
by NERDVANA (Priest) on Nov 29, 2023 at 06:47 UTC
    package Math32 { use Inline 'C', <<~'END'; #include <stdint.h> long calc(long input) { return (int32_t)((int32_t)input << 5); } END } use v5.36; say Math32::calc(1169367104);
    -1234958336

    Then all you need to do is write all the JS code in C, using int32_t variables and typecasts. If you want to declare the function parameter and return type as int32_t, you'd need to add it to the typemap, which is a hassle.