Adds tests and fixes incorrect implementation.
Kevin Tew
Index: classes/bigint.pmc =================================================================== --- classes/bigint.pmc (revision 8168) +++ classes/bigint.pmc (working copy) @@ -203,44 +203,11 @@ } static void -bigint_bitwise_shl_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest) -{ - mpz_t bn_1; - mpz_t bn_2; - mpz_init(bn_1); - mpz_init(bn_2); - mpz_set_ui(bn_1, 1); - mpz_set_ui(bn_2, 2); - - mpz_powm(BN(dest), bn_2, BN(value), bn_1); - mpz_mul(BN(dest), BN(self), BN(dest)); - - mpz_clear(bn_1); - mpz_clear(bn_2); -} -static void bigint_bitwise_shl_bigint_int(Interp *interpreter, PMC* self, INTVAL value, PMC *dest) { mpz_mul_2exp(BN(dest), BN(self), value); } - static void -bigint_bitwise_shr_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest) -{ - mpz_t bn_1; - mpz_t bn_2; - mpz_init(bn_1); - mpz_init(bn_2); - mpz_set_ui(bn_1, 1); - mpz_set_ui(bn_2, 2); - - mpz_powm(BN(dest), bn_2, BN(value), bn_1); - mpz_fdiv_q(BN(dest), BN(self), BN(dest)); - - mpz_clear(bn_1); - mpz_clear(bn_2); -} -static void bigint_bitwise_shr_bigint_int(Interp *interpreter, PMC* self, INTVAL value, PMC *dest) { mpz_tdiv_q_2exp(BN(dest), BN(self), value); @@ -1103,7 +1070,7 @@ VTABLE_morph(interpreter, dest, SELF->vtable->base_type); else dest = pmc_new(INTERP, SELF->vtable->base_type); - bigint_bitwise_shl_bigint(INTERP, SELF, value, dest); + bigint_bitwise_shl_bigint_int(INTERP, SELF, VTABLE_get_integer(INTERP, value), dest); return dest; } MMD_Integer: { @@ -1132,7 +1099,7 @@ void i_bitwise_shl (PMC* value) { MMD_BigInt: { - bigint_bitwise_shl_bigint(INTERP, SELF, value, SELF); + bigint_bitwise_shl_bigint_int(INTERP, SELF, VTABLE_get_integer(INTERP, value), SELF); } MMD_Integer: { bigint_bitwise_shl_bigint_int(INTERP, SELF, PMC_int_val(value), SELF); @@ -1146,16 +1113,83 @@ bigint_bitwise_shl_bigint_int(INTERP, SELF, value, SELF); } +/* + +=item C<PMC* bitwise_shr(PMC *value, PMC *dest)> + +=item C<PMC* bitwise_shr_int(INTVAL value, PMC *dest)> + +Returns in C<*dest> the shift right of the BigInt by C<*value>. + +=item C<void i_bitwise_shr(PMC *value)> + +=item C<void i_bitwise_shr_int(INTVAL value)> + +Inplace shift left. + +=cut + +*/ + + PMC* bitwise_shr (PMC* value, PMC* dest) { +MMD_BigInt: { + if (dest) + VTABLE_morph(interpreter, dest, SELF->vtable->base_type); + else + dest = pmc_new(INTERP, SELF->vtable->base_type); + bigint_bitwise_shr_bigint_int(INTERP, SELF, VTABLE_get_integer(INTERP, value), dest); + return dest; + } +MMD_Integer: { + if (dest) + VTABLE_morph(interpreter, dest, SELF->vtable->base_type); + else + dest = pmc_new(INTERP, SELF->vtable->base_type); + bigint_bitwise_shr_bigint_int(INTERP, SELF, PMC_int_val(value), dest); + return dest; + } +MMD_DEFAULT: { + internal_exception(1, "unimp shr"); + return dest; + } + } + + PMC* bitwise_shr_int (INTVAL value, PMC* dest) { + if (dest) + VTABLE_morph(interpreter, dest, SELF->vtable->base_type); + else + dest = pmc_new(INTERP, SELF->vtable->base_type); + bigint_bitwise_shr_bigint_int(INTERP, SELF, value, dest); + return dest; + } + + + void i_bitwise_shr (PMC* value) { +MMD_BigInt: { + bigint_bitwise_shr_bigint_int(INTERP, SELF, VTABLE_get_integer(INTERP, value), SELF); + } +MMD_Integer: { + bigint_bitwise_shr_bigint_int(INTERP, SELF, PMC_int_val(value), SELF); + } +MMD_DEFAULT: { + internal_exception(1, "unimp shr"); + } + } + + void i_bitwise_shr_int (INTVAL value) { + bigint_bitwise_shr_bigint_int(INTERP, SELF, value, SELF); + } + } /* =back - + =cut */ - + /* * Local variables: * c-indentation-style: bsd Index: t/pmc/bigint.t =================================================================== --- t/pmc/bigint.t (revision 8168) +++ t/pmc/bigint.t (working copy) @@ -21,7 +21,7 @@ use Parrot::Config; if ($PConfig{gmp}) { - plan tests => 22; + plan tests => 26; } else { plan skip_all => "No BigInt Lib configured"; @@ -657,3 +657,105 @@ 81857780532171226806613001927876611195909216420198 OUTPUT + +output_is(<<'CODE', <<'OUT', "shl_bigint"); + new P0, .BigInt + set P0, "2" + new P1, .BigInt + set P1, 2 + new P2, .BigInt + shl P2, P0, P1 + set S0, P2 + print S0 + print "\n" + set P0, "100000000000" + set P1, 10 + shl P2, P0, P1 + set S0, P2 + print S0 + print "\n" + end +CODE +8 +102400000000000 +OUT + +output_is(<<'CODE', <<'OUT', "shl_int"); + new P0, .BigInt + set P0, 2 + new P1, .Integer + set P1, 1 + new P2, .BigInt + shl P2, P0, P1 + set S0, P2 + print S0 + print "\n" + set P0, "100000000000" + set P1, 1 + shl P2, P0, P1 + set S0, P2 + print S0 + print "\n" + set P0, "100000000000" + set P1, 10 + shl P2, P0, P1 + set S0, P2 + print S0 + print "\n" + end +CODE +4 +200000000000 +102400000000000 +OUT + +output_is(<<'CODE', <<'OUT', "shr_bigint"); + new P0, .BigInt + set P0, 8 + new P1, .BigInt + set P1, 2 + new P2, .BigInt + shr P2, P0, P1 + set S0, P2 + print S0 + print "\n" + set P0, "102400000000000" + set P1, 10 + shr P2, P0, P1 + set S0, P2 + print S0 + print "\n" + end +CODE +2 +100000000000 +OUT + +output_is(<<'CODE', <<'OUT', "shr_int"); + new P0, .BigInt + set P0, 4 + new P1, .Integer + set P1, 1 + new P2, .BigInt + shr P2, P0, P1 + set S0, P2 + print S0 + print "\n" + set P0, "200000000000" + set P1, 1 + shr P2, P0, P1 + set S0, P2 + print S0 + print "\n" + set P0, "102400000000000" + set P1, 10 + shr P2, P0, P1 + set S0, P2 + print S0 + print "\n" + end +CODE +2 +100000000000 +100000000000 +OUT