export class int32 { private limbs : Uint16Array ; constructor ( low , high ) { this . limbs = new Uint16Array ( [ low , high ] ) ; } returns { int32 } static zero ( ) { return new int32 ( 0 , 0 ) ; } returns { int32 } static one ( ) { return new int32 ( 1 , 0 ) ; } returns { int32 } static fromInt ( int ) { return new int32 ( int & 0xffff , int >>> 16 ) ; } param { number } flag returns { int32 } static fromFlag ( flag ) { const tmp = new Int32Array ( 1 ) ; tmp [ 0 ] = flag ; tmp [ 0 ] *= - 1 ; return new int32 ( tmp [ 0 ] & 0xffff , tmp [ 0 ] >>> 16 ) ; } returns { number } low ( ) { return this . limbs [ 0 ] ; } returns { number } high ( ) { return this . limbs [ 1 ] ; } returns { number } lsb ( ) { return this . limbs [ 0 ] & 1 ; } returns { number } msb ( ) { return ( this . limbs [ 1 ] >>> 15 ) & 1 ; } param { number | int32 } arg returns { number } add ( arg ) { if ( arg instanceof int32 ) { return int32_add_int32 ( this , arg ) ; } return int32_add_number ( this , arg ) ; } param { number | int32 } arg returns { number } and ( arg ) { if ( arg instanceof int32 ) { return int32_and_int32 ( this , arg ) ; } return int32_and_number ( this , arg ) ; } param { number | int32 } arg returns { number } compare ( arg ) { if ( typeof arg === 'number' ) { arg = int32 . fromInt ( arg ) ; } return int32_compare ( this , arg ) ; } returns { number } isZero ( ) { return int32_is_zero ( this ) ; } param { number } amount returns { number } lshift ( amount ) { if ( amount > 31 ) { return int32 . zero ( ) ; } return int32_lshift ( this , amount ) ; } returns { number } not ( ) { return int32_not ( this ) ; } param { number | int32 } arg returns { number } or ( arg ) { if ( arg instanceof int32 ) { return int32_or_int32 ( this , arg ) ; } return int32_or_number ( this , arg ) ; } param { number } amount returns { int32 } rshift ( amount ) { if ( amount > 31 ) { return int32 . zero ( ) ; } return int32_rshift ( this , amount ) ; } param { number | int32 } arg returns { number } sub ( arg ) { if ( arg instanceof int32 ) { return int32_sub_int32 ( this , arg ) ; } return int32_sub_number ( this , arg ) ; } param { number | int32 } arg returns { number } xor ( arg ) { if ( arg instanceof int32 ) { return int32_xor_int32 ( this , arg ) ; } return int32_xor_number ( this , arg ) ; } returns { string } toHex ( ) { const l = ( this . low ( ) & 0xffff ) . toString ( 16 ) . padStart ( 4 , '0' ) ; const h = ( this . high ( ) & 0xffff ) . toString ( 16 ) . padStart ( 4 , '0' ) ; return h . concat ( l ) ; } returns { int32 } decrement ( ) { const out = new int32 ( this . low ( ) , this . high ( ) ) ; const carry = new Uint32Array ( 1 ) ; carry [ 0 ] = out . limbs [ 0 ] - 1 ; out . limbs [ 0 ] = carry [ 0 ] & 0xffff ; out . limbs [ 1 ] = out . limbs [ 1 ] + ( carry [ 0 ] >>> 16 ) ; return out ; } returns { number } toNumber ( ) { return ( this . low ( ) | ( this . high ( ) << 16 ) ) ; } /**
     * MUTATES the obejct!
     *
     * Set both limbs to 0 in-place.
     */ wipe ( ) { this . limbs [ 0 ] ^= this . limbs [ 0 ] ; this . limbs [ 1 ] ^= this . limbs [ 1 ] ; } } function int32_add_int32 ( a , b ) { let l = a . low ( ) + b . low ( ) ; let h = a . high ( ) + b . high ( ) + ( l >>> 16 ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_add_number ( a , b ) { let l = a . low ( ) + ( b & 0xffff ) ; let h = a . high ( ) + ( b >>> 16 ) + ( l >>> 16 ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_and_int32 ( a , b ) { let l = a . low ( ) & b . low ( ) ; let h = a . high ( ) & b . high ( ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_and_number ( a , b ) { let l = a . low ( ) & ( b & 0xffff ) ; let h = a . high ( ) & ( b >>> 16 ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_compare ( left , right ) { const diff = right . sub ( left ) ; let gt = diff . xor ( left . xor ( right ) . and ( left . xor ( diff ) ) ) . msb ( ) ; let eq = right . xor ( left ) . isZero ( ) ; return int32 . fromInt ( ( gt + gt + eq ) ) . decrement ( ) ; } function int32_is_zero ( a ) { const tmp = new Uint32Array ( 1 ) ; tmp [ 0 ] = ( a . low ( ) | a . high ( ) ) ; tmp [ 0 ] -- ; return tmp [ 0 ] >>> 31 ; } function int32_lshift ( a , x ) { let l = ( a . low ( ) << x ) ; let h = ( l >>> 16 ) | ( a . high ( ) << x ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_not ( a ) { let l = a . low ( ) ^ 0xffff ; let h = a . high ( ) ^ 0xffff ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_or_int32 ( a , b ) { let l = a . low ( ) | b . low ( ) ; let h = a . high ( ) | b . high ( ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_or_number ( a , b ) { let l = a . low ( ) | ( b & 0xffff ) ; let h = a . high ( ) | ( b >>> 16 ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_rshift ( a , amount ) { let m = ( 1 << ( amount + 1 ) ) - 1 ; let h = ( a . high ( ) >>> amount ) ; let l = ( a . low ( ) >>> amount ) | ( ( ( a . high ( ) & m ) << 16 ) >>> amount ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_sub_int32 ( a , b ) { let l = a . low ( ) - b . low ( ) ; let h = a . high ( ) - b . high ( ) + ( l >>> 16 ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_sub_number ( a , b ) { let l = a . low ( ) - ( b & 0xffff ) ; let h = a . high ( ) - ( b >>> 16 ) + ( l >>> 16 ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_xor_int32 ( a , b ) { let l = a . low ( ) ^ b . low ( ) ; let h = a . high ( ) ^ b . high ( ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; } function int32_xor_number ( a , b ) { let l = a . low ( ) ^ ( b & 0xffff ) ; let h = a . high ( ) ^ ( b >>> 16 ) ; return new int32 ( l & 0xffff , h & 0xffff ) ; }