Ticket #280: tt280-bignum-pmc.patch

File tt280-bignum-pmc.patch, 56.7 KB (added by rurban, 6 years ago)
  • src/pmc/bignum.pmc

    old new  
    88 
    99=head1 DESCRIPTION 
    1010 
    11 C<BigNum> provides arbitrary precision integer mathematic functions. 
     11C<BigNum> provides arbitrary precision floating point mathematic 
     12functions, based on the GMP mpf library. 
     13 
     14=head1 SYNOPSIS 
     15 
     16Make mixing of classes work, like in: 
     17 
     18        new $P0 ['BigInt'] 
     19        new $P1 ['BigNum'] 
     20        set $P0, 10 
     21        set $P1, 2 
     22        div P2, P0, P1  # $P2 = $P0 / $P1; (BigNum) 5.0 
     23 
     24Make auto-upgrading/downgrading work. 
     25 
     26        set $N1, $P0 
     27        set $N1, $P1 
     28        set $I1, $P0 
     29        set $I1, $P1 
     30        set $P0, $I1 
     31        set $P0, $N1 
     32        set $P1, $I1 
     33        set $P1, $N1 
     34 
     35  BigNum 
     36    => BigInt => Integer 
     37    => Number: float (can be long double) and double 
     38    => Integer (unsigned long) 
    1239 
    1340=head2 Functions 
    1441 
    1542=over 4 
    1643 
    17 =item C<static void bignum_set_long(Interp*, PMC *, long value)> 
     44=item C<static void bignum_set_si(Interp*, PMC *, long value)> 
    1845 
    1946=item C<static void bignum_set_double(Interp*, PMC *, double value)> 
    2047 
     
    2855#  undef PARROT_HAS_GMP /* splint barfs on the gmp.h header */ 
    2956#endif /* S_SPLINT_S */ 
    3057 
    31 /* Temporariliy disabled until someone fix it */ 
     58/* Uncomment to easily disable it */ 
     59/* 
    3260#ifdef PARROT_HAS_GMP 
    3361#  undef PARROT_HAS_GMP 
    3462#endif 
     63#undef PARROT_BIGNUM_CAN_BIGINT 
     64*/ 
    3565 
    3666#ifdef PARROT_HAS_GMP 
     67#  include "pmc_bigint.h" 
    3768#  include <gmp.h> 
    3869typedef struct BIGNUM { 
    3970    mpf_t b; 
    4071} BIGNUM; 
    41  
    4272#endif 
    4373 
    4474static void 
     
    4676    Parrot_BigNum_attributes *attrs = 
    4777        mem_allocate_zeroed_typed(Parrot_BigNum_attributes); 
    4878#ifdef PARROT_HAS_GMP 
    49     attrs->bi = mem_allocate_zeroed_typed(BIGNUM); 
    50     mpf_init(attrs->bi->b); 
     79    attrs->bn = mem_allocate_zeroed_typed(BIGNUM); 
     80    mpf_init(attrs->bn->b); 
    5181#else 
    52     attrs->bi = NULL; 
     82    attrs->bn = NULL; 
    5383#endif 
    5484    PMC_data(self) = attrs; 
    5585} 
     
    5888static void 
    5989bignum_clear(PARROT_INTERP, PMC *self) { 
    6090#ifdef PARROT_HAS_GMP 
    61     BIGNUM *bi; 
    62     GETATTR_BigNum_bi(interp, self, bi); 
    63     mpf_clear(bi->b); 
     91    BIGNUM *bn; 
     92    GETATTR_BigNum_bn(interp, self, bn); 
     93    mpf_clear(bn->b); 
    6494#endif 
    6595} 
    6696 
     97 
    6798#ifdef PARROT_HAS_GMP 
    6899 
    69100static void 
    70101bignum_set(PARROT_INTERP, PMC *dest, PMC *src) { 
    71     BIGNUM *bi_dest, *bi_src; 
    72     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    73     GETATTR_BigNum_bi(interp, src,  bi_src); 
    74     mpf_clear(bi_dest->b); 
    75     mpf_init(bi_dest->b); 
    76     mpf_set(bi_dest->b, bi_src->b); 
     102    BIGNUM *bn_dest, *bn_src; 
     103    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     104    GETATTR_BigNum_bn(interp, src,  bn_src); 
     105    mpf_clear(bn_dest->b); 
     106    mpf_init(bn_dest->b); 
     107    mpf_set(bn_dest->b, bn_src->b); 
     108} 
     109 
     110static void 
     111bignum_set_si(PARROT_INTERP, PMC *self, long value) { 
     112    BIGNUM *bn; 
     113    GETATTR_BigNum_bn(interp, self, bn); 
     114    mpf_set_si(bn->b, value); 
    77115} 
    78116 
    79117static void 
    80 bignum_set_long(PARROT_INTERP, PMC *self, long value) { 
    81     BIGNUM *bi; 
    82     GETATTR_BigNum_bi(interp, self, bi); 
    83     mpf_set_si(bi->b, value); 
     118bignum_set_ui(PARROT_INTERP, PMC *self, unsigned long value) { 
     119    BIGNUM *bn; 
     120    GETATTR_BigNum_bn(interp, self, bn); 
     121    mpf_set_ui(bn->b, value); 
     122} 
     123 
     124static void 
     125bignum_set_float(PARROT_INTERP, PMC *self, FLOATVAL value) { 
     126    BIGNUM *bn; 
     127    GETATTR_BigNum_bn(interp, self, bn); 
     128    mpf_set_d(bn->b, (double)value); 
    84129} 
    85130 
    86131static void 
    87132bignum_set_double(PARROT_INTERP, PMC *self, double value) { 
    88     BIGNUM *bi; 
    89     GETATTR_BigNum_bi(interp, self, bi); 
    90     mpf_set_d(bi->b, value); 
     133    BIGNUM *bn; 
     134    GETATTR_BigNum_bn(interp, self, bn); 
     135    mpf_set_d(bn->b, value); 
    91136} 
    92137 
    93138static void 
    94139bignum_set_str(PARROT_INTERP, PMC *self, char *value, int base) { 
    95     BIGNUM *bi; 
    96     GETATTR_BigNum_bi(interp, self, bi); 
    97     mpf_set_str(bi->b, value, base); 
     140    BIGNUM *bn; 
     141    GETATTR_BigNum_bn(interp, self, bn); 
     142    mpf_set_str(bn->b, value, base); 
    98143} 
    99144 
     145#ifdef PARROT_BIGNUM_CAN_BIGINT 
     146static void 
     147bignum_set_bigint(PARROT_INTERP, PMC *self, struct BIGINT *value) { 
     148    BIGNUM *bn; 
     149    struct BIGINT *bi; 
     150    GETATTR_BigNum_bn(interp, self, bn); 
     151    bi->b = PARROT_BIGINT(value); 
     152    mpf_set(bn->b, (mpf_srcptr)bi->b); 
     153} 
     154#endif 
     155 
    100156static BIGNUM* 
    101157bignum_get_self(PARROT_INTERP, PMC *self) { 
    102     BIGNUM *bi; 
    103     GETATTR_BigNum_bi(interp, self, bi); 
    104     return bi; 
     158    BIGNUM *bn; 
     159    GETATTR_BigNum_bn(interp, self, bn); 
     160    return bn; 
    105161} 
    106162 
    107163static void 
    108164bignum_set_self(PARROT_INTERP, PMC *self, BIGNUM *value) { 
    109     BIGNUM *bi; 
    110     GETATTR_BigNum_bi(interp, self, bi); 
    111     mpf_set(bi->b, (mpf_srcptr)((BIGNUM*)value)->b); 
     165    BIGNUM *bn; 
     166    GETATTR_BigNum_bn(interp, self, bn); 
     167    mpf_set(bn->b, (mpf_srcptr)((BIGNUM*)value)->b); 
    112168} 
    113169 
    114170static long 
    115 bignum_get_long(PARROT_INTERP, PMC *self) { 
    116     BIGNUM *bi; 
    117     GETATTR_BigNum_bi(interp, self, bi); 
    118     if (mpf_fits_slong_p(bi->b)) 
    119         return mpf_get_si(bi->b); 
     171bignum_get_si(PARROT_INTERP, PMC *self) { 
     172    BIGNUM *bn; 
     173    GETATTR_BigNum_bn(interp, self, bn); 
     174    if (mpf_fits_slong_p(bn->b)) 
     175        return mpf_get_si(bn->b); 
     176 
     177    Parrot_ex_throw_from_c_args(interp, NULL, 1, "bignum_get_si: number too big"); 
     178} 
     179 
     180static unsigned long 
     181bignum_get_ui(PARROT_INTERP, PMC *self) { 
     182    BIGNUM *bn; 
     183    GETATTR_BigNum_bn(interp, self, bn); 
     184    if (mpf_fits_slong_p(bn->b)) 
     185        return mpf_get_ui(bn->b); 
    120186 
    121     Parrot_ex_throw_from_c_args(interp, NULL, 1, "bignum_get_long: number too big"); 
     187    Parrot_ex_throw_from_c_args(interp, NULL, 1, "bignum_get_ui: number too big"); 
    122188} 
    123189 
    124190static int 
    125191bignum_get_bool(PARROT_INTERP, PMC *self) { 
    126     BIGNUM *bi; 
    127     GETATTR_BigNum_bi(interp, self, bi); 
    128     if (mpf_sgn(bi->b) != 0) 
     192    BIGNUM *bn; 
     193    GETATTR_BigNum_bn(interp, self, bn); 
     194    if (mpf_sgn(bn->b) != 0) 
    129195        return 1; 
    130196    else 
    131197        return 0; 
     
    133199 
    134200static char * 
    135201bignum_get_string(PARROT_INTERP, PMC *self, int base) { 
    136     BIGNUM *bi; 
     202    BIGNUM *bn; 
     203    size_t  n; 
     204    char   *s; 
     205    mp_exp_t exponent; 
     206 
     207    GETATTR_BigNum_bn(interp, self, bn); 
     208    n = (mpf_get_prec(bn->b)) / log(base) * log(2); 
     209    s = (char *)mem_sys_allocate(n + 5); 
     210    return mpf_get_str(s, &exponent, base, 0, bn->b); 
     211} 
     212 
     213static char * 
     214bignum_get_string_size(PARROT_INTERP, PMC *self, int base, int digits) { 
     215    BIGNUM *bn; 
    137216    size_t  n; 
    138217    char   *s; 
     218    mp_exp_t exponent; 
    139219 
    140     GETATTR_BigNum_bi(interp, self, bi); 
    141     n = mpf_sizeinbase(bi->b, base) + 2; 
    142     s = (char *)mem_sys_allocate(n); 
    143     return mpf_get_str(s, base, bi->b); 
     220    GETATTR_BigNum_bn(interp, self, bn); 
     221    s = (char *)mem_sys_allocate(digits + 5); 
     222    return mpf_get_str(s, &exponent, base, digits, bn->b); 
    144223} 
    145224 
    146225static double 
    147226bignum_get_double(PARROT_INTERP, PMC *self) { 
    148     BIGNUM *bi; 
    149     GETATTR_BigNum_bi(interp, self, bi); 
    150     return mpf_get_d(bi->b); 
     227    BIGNUM *bn; 
     228    GETATTR_BigNum_bn(interp, self, bn); 
     229    return mpf_get_d(bn->b); 
     230} 
     231 
     232static FLOATVAL 
     233bignum_get_float(PARROT_INTERP, PMC *self) { 
     234    BIGNUM *bn; 
     235    GETATTR_BigNum_bn(interp, self, bn); 
     236    return mpf_get_d(bn->b); 
     237} 
     238 
     239#ifdef PARROT_BIGNUM_CAN_BIGINT 
     240static struct BIGINT 
     241bignum_get_bigint(PARROT_INTERP, PMC *self) { 
     242    BIGNUM *bn; 
     243    struct BIGINT *bi_dest; 
     244    GETATTR_BigNum_bn(interp, self, bn); 
     245    mpz_clear(bi_dest->b); 
     246    mpz_init(bi_dest->b); 
     247    if (mpf_fits_slong_p(bn->b)) { 
     248        bi_dest->b = mpf_get_ui(bn->b); 
     249    } 
     250    else { 
     251        Parrot_ex_throw_from_c_args(interp, NULL, 1, 
     252            "bignum_get_bigint: Precision loss"); 
     253    } 
     254    return bi_dest; 
    151255} 
     256#endif 
    152257 
    153258static void 
    154259bignum_add_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    155     BIGNUM *bi_self, *bi_value, *bi_dest; 
    156     GETATTR_BigNum_bi(interp, self, bi_self); 
    157     GETATTR_BigNum_bi(interp, value, bi_value); 
    158     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    159     mpf_add(bi_dest->b, bi_self->b, bi_value->b); 
     260    BIGNUM *bn_self, *bn_value, *bn_dest; 
     261    GETATTR_BigNum_bn(interp, self, bn_self); 
     262    GETATTR_BigNum_bn(interp, value, bn_value); 
     263    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     264    mpf_add(bn_dest->b, bn_self->b, bn_value->b); 
    160265} 
    161266 
    162267static void 
    163268bignum_add_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    164     BIGNUM *bi_self, *bi_dest; 
    165     GETATTR_BigNum_bi(interp, self, bi_self); 
    166     GETATTR_BigNum_bi(interp, dest, bi_dest); 
     269    BIGNUM *bn_self, *bn_dest; 
     270    GETATTR_BigNum_bn(interp, self, bn_self); 
     271    GETATTR_BigNum_bn(interp, dest, bn_dest); 
    167272    if (value < 0) 
    168         mpf_sub_ui(bi_dest->b, bi_self->b, (unsigned long int)-value); 
     273        mpf_sub_ui(bn_dest->b, bn_self->b, (unsigned long int)-value); 
    169274    else 
    170         mpf_add_ui(bi_dest->b, bi_self->b, (unsigned long int)value); 
     275        mpf_add_ui(bn_dest->b, bn_self->b, (unsigned long int)value); 
     276} 
     277 
     278static void 
     279bignum_add_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 
     280    BIGNUM *bn, *bn_self, *bn_dest; 
     281    GETATTR_BigNum_bn(interp, self, bn_self); 
     282    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     283    mpf_set_d(bn->b, value); 
     284    mpf_add(bn_dest->b, bn_self->b, bn->b); 
    171285} 
    172286 
    173287static void 
    174288bignum_sub_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    175     BIGNUM *bi_self, *bi_value, *bi_dest; 
    176     GETATTR_BigNum_bi(interp, self, bi_self); 
    177     GETATTR_BigNum_bi(interp, value, bi_value); 
    178     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    179     mpf_sub(bi_dest->b, bi_self->b, bi_value->b); 
     289    BIGNUM *bn_self, *bn_value, *bn_dest; 
     290    GETATTR_BigNum_bn(interp, self, bn_self); 
     291    GETATTR_BigNum_bn(interp, value, bn_value); 
     292    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     293    mpf_sub(bn_dest->b, bn_self->b, bn_value->b); 
    180294} 
    181295 
    182296static void 
    183297bignum_sub_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    184     BIGNUM *bi_self, *bi_dest; 
    185     GETATTR_BigNum_bi(interp, self, bi_self); 
    186     GETATTR_BigNum_bi(interp, dest, bi_dest); 
     298    BIGNUM *bn_self, *bn_dest; 
     299    GETATTR_BigNum_bn(interp, self, bn_self); 
     300    GETATTR_BigNum_bn(interp, dest, bn_dest); 
    187301    if (value < 0) 
    188         mpf_add_ui(bi_dest->b, bi_self->b, (unsigned long int)-value); 
     302        mpf_add_ui(bn_dest->b, bn_self->b, (unsigned long int)-value); 
    189303    else 
    190         mpf_sub_ui(bi_dest->b, bi_self->b, (unsigned long int)value); 
     304        mpf_sub_ui(bn_dest->b, bn_self->b, (unsigned long int)value); 
     305} 
     306 
     307static void 
     308bignum_sub_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 
     309    BIGNUM *bn, *bn_self, *bn_dest; 
     310    GETATTR_BigNum_bn(interp, self, bn_self); 
     311    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     312    mpf_set_d(bn->b, value); 
     313    mpf_sub(bn_dest->b, bn_self->b, bn->b); 
    191314} 
    192315 
    193316static void 
    194317bignum_mul_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    195     BIGNUM *bi_self, *bi_value, *bi_dest; 
    196     GETATTR_BigNum_bi(interp, self, bi_self); 
    197     GETATTR_BigNum_bi(interp, value, bi_value); 
    198     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    199     mpf_mul(bi_dest->b, bi_self->b, bi_value->b); 
     318    BIGNUM *bn_self, *bn_value, *bn_dest; 
     319    GETATTR_BigNum_bn(interp, self, bn_self); 
     320    GETATTR_BigNum_bn(interp, value, bn_value); 
     321    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     322    mpf_mul(bn_dest->b, bn_self->b, bn_value->b); 
    200323} 
    201324 
    202325static void 
    203326bignum_mul_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    204     BIGNUM *bi_self, *bi_dest; 
    205     GETATTR_BigNum_bi(interp, self, bi_self); 
    206     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    207     mpf_mul_si(bi_dest->b, bi_self->b, value); 
     327    BIGNUM *bn_self, *bn_dest; 
     328    GETATTR_BigNum_bn(interp, self, bn_self); 
     329    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     330    mpf_mul_ui(bn_dest->b, bn_self->b, (unsigned long)value); 
     331} 
     332 
     333static void 
     334bignum_mul_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 
     335    BIGNUM *bn, *bn_self, *bn_dest; 
     336    GETATTR_BigNum_bn(interp, self, bn_self); 
     337    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     338    mpf_set_d(bn->b, value); 
     339    mpf_mul(bn_dest->b, bn_self->b, bn->b); 
    208340} 
    209341 
    210342static void 
    211343bignum_pow_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    212     BIGNUM *bi_self, *bi_dest; 
    213     GETATTR_BigNum_bi(interp, self, bi_self); 
    214     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    215     mpf_pow_ui(bi_dest->b, bi_self->b, (unsigned long int)value); 
     344    BIGNUM *bn_self, *bn_dest; 
     345    GETATTR_BigNum_bn(interp, self, bn_self); 
     346    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     347    mpf_pow_ui(bn_dest->b, bn_self->b, (unsigned long int)value); 
    216348} 
    217349 
    218350static void 
     
    225357static void 
    226358bignum_check_divide_zero(PARROT_INTERP, PMC *value) { 
    227359    /* Throw an exception if we are dividing by zero. */ 
    228     BIGNUM *bi; 
    229     GETATTR_BigNum_bi(interp, value, bi); 
    230     if (mpf_cmp_si(bi->b, 0) == 0) 
     360    BIGNUM *bn; 
     361    GETATTR_BigNum_bn(interp, value, bn); 
     362    if (mpf_cmp_si(bn->b, 0) == 0) 
    231363        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_DIV_BY_ZERO, 
    232364            "Divide by zero"); 
    233365} 
    234366 
    235367static void 
    236368bignum_div_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    237     BIGNUM *bi_self, *bi_value, *bi_dest; 
     369    BIGNUM *bn_self, *bn_value, *bn_dest; 
    238370    bignum_check_divide_zero(interp, value); 
    239     GETATTR_BigNum_bi(interp, self, bi_self); 
    240     GETATTR_BigNum_bi(interp, value, bi_value); 
    241     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    242     /* this is mpf_fdiv_q */ 
    243     mpf_div(bi_dest->b, bi_self->b, bi_value->b); 
     371    GETATTR_BigNum_bn(interp, self, bn_self); 
     372    GETATTR_BigNum_bn(interp, value, bn_value); 
     373    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     374    mpf_div(bn_dest->b, bn_self->b, bn_value->b); 
    244375} 
    245376 
    246377static void 
    247378bignum_div_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    248     BIGNUM *bi_self, *bi_dest; 
    249     GETATTR_BigNum_bi(interp, self, bi_self); 
    250     GETATTR_BigNum_bi(interp, dest, bi_dest); 
     379    BIGNUM *bn_self, *bn_dest; 
     380    GETATTR_BigNum_bn(interp, self, bn_self); 
     381    GETATTR_BigNum_bn(interp, dest, bn_dest); 
    251382    int_check_divide_zero(interp, value); 
    252383 
    253     /* this is mpf_fdiv_q */ 
     384    /* this is mpz_fdiv_q */ 
    254385    if (value < 0) { 
    255         mpf_div_ui(bi_dest->b, bi_self->b, (unsigned long int)-value); 
    256         mpf_neg(bi_dest->b, bi_dest->b); 
     386        mpf_div_ui(bn_dest->b, bn_self->b, (unsigned long int)-value); 
     387        mpf_neg(bn_dest->b, bn_dest->b); 
    257388    } 
    258389    else 
    259         mpf_div_ui(bi_dest->b, bi_self->b, (unsigned long int)value); 
    260 } 
    261  
    262 static void 
    263 bignum_fdiv_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    264     BIGNUM *bi_self, *bi_value, *bi_dest; 
    265     GETATTR_BigNum_bi(interp, self, bi_self); 
    266     GETATTR_BigNum_bi(interp, value, bi_value); 
    267     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    268     bignum_check_divide_zero(interp, value); 
    269     mpf_fdiv_q(bi_dest->b, bi_self->b, bi_value->b); 
     390        mpf_div_ui(bn_dest->b, bn_self->b, (unsigned long int)value); 
    270391} 
    271392 
    272393static void 
    273 bignum_fdiv_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    274     BIGNUM *bi_self, *bi_dest; 
    275     GETATTR_BigNum_bi(interp, self, bi_self); 
    276     GETATTR_BigNum_bi(interp, dest, bi_dest); 
     394bignum_div_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 
     395    BIGNUM *bn, *bn_self, *bn_dest; 
     396    GETATTR_BigNum_bn(interp, self, bn_self); 
     397    GETATTR_BigNum_bn(interp, dest, bn_dest); 
    277398    int_check_divide_zero(interp, value); 
    278399 
    279400    if (value < 0) { 
    280         mpf_fdiv_q_ui(bi_dest->b, bi_self->b, (unsigned long int)-value); 
    281         mpf_neg(bi_dest->b, bi_dest->b); 
     401        mpf_set_d(bn->b, -value); 
     402        mpf_div(bn_dest->b, bn_self->b, bn->b); 
     403        mpf_neg(bn_dest->b, bn_dest->b); 
    282404    } 
    283405    else 
    284         mpf_fdiv_q_ui(bi_dest->b, bi_self->b, (unsigned long int)value); 
     406        mpf_div(bn_dest->b, bn_self->b, bn->b); 
    285407} 
    286408 
     409/* There's no such mpf_fdiv, only mpz_fdiv and mpf_div */ 
    287410static void 
    288 bignum_mod_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    289     BIGNUM *bi_self, *bi_value, *bi_dest; 
    290     GETATTR_BigNum_bi(interp, self, bi_self); 
    291     GETATTR_BigNum_bi(interp, value, bi_value); 
    292     GETATTR_BigNum_bi(interp, dest, bi_dest); 
     411bignum_fdiv_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
     412    BIGNUM *bn_self, *bn_value, *bn_dest; 
     413    GETATTR_BigNum_bn(interp, self, bn_self); 
     414    GETATTR_BigNum_bn(interp, value, bn_value); 
     415    GETATTR_BigNum_bn(interp, dest, bn_dest); 
    293416    bignum_check_divide_zero(interp, value); 
    294     mpf_mod(bi_dest->b, bi_self->b, bi_value->b); 
     417    mpf_div(bn_dest->b, bn_self->b, bn_value->b); 
    295418} 
    296419 
    297420static void 
    298 bignum_mod_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    299     BIGNUM *bi_self, *bi_dest; 
    300     GETATTR_BigNum_bi(interp, self, bi_self); 
    301     GETATTR_BigNum_bi(interp, dest, bi_dest); 
     421bignum_fdiv_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
     422    BIGNUM *bn_self, *bn_dest; 
     423    GETATTR_BigNum_bn(interp, self, bn_self); 
     424    GETATTR_BigNum_bn(interp, dest, bn_dest); 
    302425    int_check_divide_zero(interp, value); 
    303426 
    304427    if (value < 0) { 
    305         mpf_mod_ui(bi_dest->b, bi_self->b, (unsigned long int)-value); 
     428        mpf_div_ui(bn_dest->b, bn_self->b, (unsigned long int)-value); 
     429        mpf_neg(bn_dest->b, bn_dest->b); 
    306430    } 
    307431    else 
    308         mpf_mod_ui(bi_dest->b, bi_self->b, (unsigned long int)value); 
     432        mpf_div_ui(bn_dest->b, bn_self->b, (unsigned long int)value); 
    309433} 
    310434 
    311435static INTVAL 
    312436bignum_cmp(PARROT_INTERP, PMC *self, PMC *value) { 
    313     BIGNUM *bi_self, *bi_value; 
    314     GETATTR_BigNum_bi(interp, self,  bi_self); 
    315     GETATTR_BigNum_bi(interp, value, bi_value); 
    316     return mpf_cmp(bi_self->b, bi_value->b); 
     437    BIGNUM *bn_self, *bn_value; 
     438    GETATTR_BigNum_bn(interp, self,  bn_self); 
     439    GETATTR_BigNum_bn(interp, value, bn_value); 
     440    return mpf_cmp(bn_self->b, bn_value->b); 
     441} 
     442 
     443static INTVAL 
     444bignum_cmp_double(PARROT_INTERP, PMC *self, double value) { 
     445    BIGNUM *bn; 
     446    GETATTR_BigNum_bn(interp, self, bn); 
     447    return mpf_cmp_d(bn->b, value); 
    317448} 
    318449 
    319450static INTVAL 
    320451bignum_cmp_int(PARROT_INTERP, PMC *self, INTVAL value) { 
    321     BIGNUM *bi; 
    322     GETATTR_BigNum_bi(interp, self, bi); 
    323     return mpf_cmp_si(bi->b, value); 
     452    BIGNUM *bn; 
     453    GETATTR_BigNum_bn(interp, self, bn); 
     454    return mpf_cmp_si(bn->b, value); 
     455} 
     456 
     457static INTVAL 
     458bignum_cmp_ulong(PARROT_INTERP, PMC *self, unsigned long value) { 
     459    BIGNUM *bn; 
     460    GETATTR_BigNum_bn(interp, self, bn); 
     461    return mpf_cmp_ui(bn->b, value); 
    324462} 
    325463 
    326464static void 
    327465bignum_abs(PARROT_INTERP, PMC *self, PMC *dest) { 
    328     BIGNUM *bi_self, *bi_dest; 
     466    BIGNUM *bn_self, *bn_dest; 
    329467    pmc_reuse(interp, dest, enum_class_BigNum, 0); 
    330     GETATTR_BigNum_bi(interp, self, bi_self); 
    331     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    332     mpf_abs(bi_dest->b, bi_self->b); 
     468    GETATTR_BigNum_bn(interp, self, bn_self); 
     469    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     470    mpf_abs(bn_dest->b, bn_self->b); 
    333471} 
    334472 
    335473static void 
    336474bignum_neg(PARROT_INTERP, PMC *self, PMC *dest) { 
    337     BIGNUM *bi_self, *bi_dest; 
     475    BIGNUM *bn_self, *bn_dest; 
    338476    pmc_reuse(interp, dest, enum_class_BigNum, 0); 
    339     GETATTR_BigNum_bi(interp, self, bi_self); 
    340     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    341     mpf_neg(bi_dest->b, bi_self->b); 
     477    GETATTR_BigNum_bn(interp, self, bn_self); 
     478    GETATTR_BigNum_bn(interp, dest, bn_dest); 
     479    mpf_neg(bn_dest->b, bn_self->b); 
    342480} 
    343481 
    344 static void 
    345 bignum_bitwise_shl_bignum_int(PARROT_INTERP, PMC *self, 
    346                               INTVAL value, PMC *dest) 
    347 { 
    348     BIGNUM *bi_self, *bi_dest; 
    349     GETATTR_BigNum_bi(interp, self, bi_self); 
    350     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    351     /* The third args to mpf_mul_2exp and mpf_tdiv_q_2exp are unsigned, so we 
    352        need to do something sensible with negative values. */ 
    353     if (value >= 0) 
    354         mpf_mul_2exp(bi_dest->b, bi_self->b, (unsigned long int)value); 
    355     else 
    356         mpf_tdiv_q_2exp(bi_dest->b, bi_self->b, (unsigned long int)-value); 
     482static INTVAL 
     483bignum_get_default_prec(PARROT_INTERP, PMC *self) { 
     484    return mpf_get_default_prec(); 
    357485} 
    358486 
    359487static void 
    360 bignum_bitwise_shr_bignum_int(PARROT_INTERP, PMC *self, 
    361                               INTVAL value, PMC *dest) 
    362 { 
    363     BIGNUM *bi_self, *bi_dest; 
    364     GETATTR_BigNum_bi(interp, self, bi_self); 
    365     GETATTR_BigNum_bi(interp, dest, bi_dest); 
    366     /* The third args to mpf_mul_2exp and mpf_tdiv_q_2exp are unsigned, so we 
    367        need to do something sensible with negative values. */ 
    368     if (value >= 0) 
    369         mpf_tdiv_q_2exp(bi_dest->b, bi_self->b, (unsigned long int)value); 
    370     else 
    371         mpf_mul_2exp(bi_dest->b, bi_self->b, (unsigned long int)-value); 
     488bignum_set_default_prec(PARROT_INTERP, PMC *self, INTVAL prec) { 
     489     mpf_set_default_prec(prec); 
    372490} 
    373491 
    374492#else /* ifdef PARROT_HAS_GMP */ 
     
    377495    FLOATVAL b; /* bogus definition for users without libgmp*/ 
    378496} BIGNUM; 
    379497 
     498#define THROW_NYI Parrot_ex_throw_from_c_args(interp, NULL, \ 
     499        EXCEPTION_LIBRARY_ERROR, "no bignum lib loaded") 
     500 
    380501#  if 0 
    381502static void 
    382503bignum_init(PARROT_INTERP, PMC *self) { 
    383     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    384         "no bignum lib loaded"); 
     504    THROW_NYI; 
    385505} 
    386506 
    387507static void 
    388508bignum_clear(PARROT_INTERP, PMC *self) { 
    389     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    390         "no bignum lib loaded"); 
     509    THROW_NYI; 
    391510} 
    392511#  endif 
    393512 
    394513static void 
    395 bignum_set_long(PARROT_INTERP, PMC *self, long value) { 
    396     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    397         "no bignum lib loaded"); 
     514bignum_set(PARROT_INTERP, PMC *dest, PMC *src) { 
     515    THROW_NYI; 
    398516} 
    399517 
    400518static void 
    401 bignum_set(PARROT_INTERP, PMC *dest, PMC *src) { 
    402     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    403         "no bignum lib loaded"); 
     519bignum_set_si(PARROT_INTERP, PMC *self, long value) { 
     520    THROW_NYI; 
    404521} 
    405522 
    406523static void 
    407524bignum_set_double(PARROT_INTERP, PMC *self, double value) { 
    408     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    409         "no bignum lib loaded"); 
     525    THROW_NYI; 
    410526} 
    411527 
    412528static void 
    413529bignum_set_str(PARROT_INTERP, PMC *self, char *value, int base) { 
    414     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    415         "no bignum lib loaded"); 
     530    THROW_NYI; 
    416531} 
    417532 
    418533static void 
    419534bignum_set_self(PARROT_INTERP, PMC *self, BIGNUM *value) { 
    420     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    421         "no bignum lib loaded"); 
     535    THROW_NYI; 
    422536} 
    423537 
    424538static BIGNUM* 
    425539bignum_get_self(PARROT_INTERP, PMC *self) { 
    426     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    427         "no bignum lib loaded"); 
     540    THROW_NYI; 
    428541} 
    429542 
    430543static char * 
    431544bignum_get_string(PARROT_INTERP, PMC *self, int base) { 
    432     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    433         "no bignum lib loaded"); 
     545    THROW_NYI; 
     546} 
     547 
     548static char * 
     549bignum_get_string_size(PARROT_INTERP, PMC *self, int base, int digits) { 
     550    THROW_NYI; 
     551} 
     552 
     553static unsigned long 
     554bignum_get_ui(PARROT_INTERP, PMC *self) { 
     555    THROW_NYI; 
    434556} 
    435557 
    436558static long 
    437 bignum_get_long(PARROT_INTERP, PMC *self) { 
    438     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    439         "no bignum lib loaded"); 
     559bignum_get_si(PARROT_INTERP, PMC *self) { 
     560    THROW_NYI; 
    440561} 
    441562 
    442563static long 
    443564bignum_get_bool(PARROT_INTERP, PMC *self) { 
    444     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    445         "no bignum lib loaded"); 
     565    THROW_NYI; 
    446566} 
    447567 
    448568static double 
    449569bignum_get_double(PARROT_INTERP, PMC *self) { 
    450     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    451         "no bignum lib loaded"); 
     570    THROW_NYI; 
    452571} 
    453572 
    454573static void 
    455574bignum_add_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    456     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    457         "no bignum lib loaded"); 
     575    THROW_NYI; 
    458576} 
    459577 
    460578static void 
    461579bignum_add_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    462     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    463         "no bignum lib loaded"); 
     580    THROW_NYI; 
     581} 
     582 
     583static void 
     584bignum_add_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 
     585    THROW_NYI; 
    464586} 
    465587 
    466588static void 
    467589bignum_sub_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    468     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    469         "no bignum lib loaded"); 
     590    THROW_NYI; 
    470591} 
    471592 
    472593static void 
    473594bignum_sub_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    474     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    475         "no bignum lib loaded"); 
     595    THROW_NYI; 
     596} 
     597 
     598static void 
     599bignum_sub_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 
     600    THROW_NYI; 
    476601} 
    477602 
    478603static void 
    479604bignum_mul_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    480     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    481         "no bignum lib loaded"); 
     605    THROW_NYI; 
    482606} 
    483607 
    484608static void 
    485609bignum_mul_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    486     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    487         "no bignum lib loaded"); 
     610    THROW_NYI; 
     611} 
     612 
     613static void 
     614bignum_mul_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 
     615    THROW_NYI; 
    488616} 
    489617 
    490618static void 
    491619bignum_pow_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    492     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    493         "no bignum lib loaded"); 
     620    THROW_NYI; 
     621} 
     622 
     623static void 
     624bignum_pow_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 
     625    THROW_NYI; 
    494626} 
    495627 
    496628static void 
    497629bignum_div_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    498     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    499         "no bignum lib loaded"); 
     630    THROW_NYI; 
    500631} 
    501632 
    502633static void 
    503634bignum_div_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    504     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    505         "no bignum lib loaded"); 
     635    THROW_NYI; 
    506636} 
    507637 
    508638static void 
    509 bignum_fdiv_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    510     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    511         "no bignum lib loaded"); 
     639bignum_div_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 
     640    THROW_NYI; 
    512641} 
    513642 
    514643static void 
    515 bignum_fdiv_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    516     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    517         "no bignum lib loaded"); 
     644bignum_fdiv_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
     645    THROW_NYI; 
    518646} 
    519647 
    520648static void 
    521 bignum_mod_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    522     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    523         "no bignum lib loaded"); 
     649bignum_fdiv_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
     650    THROW_NYI; 
    524651} 
    525652 
    526653static void 
    527 bignum_mod_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 
    528     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    529         "no bignum lib loaded"); 
     654bignum_fdiv_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 
     655    THROW_NYI; 
    530656} 
    531657 
    532658static INTVAL 
    533659bignum_cmp(PARROT_INTERP, PMC *self, PMC *value) { 
    534     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    535         "no bignum lib loaded"); 
     660    THROW_NYI; 
    536661} 
    537662 
    538663static INTVAL 
    539664bignum_cmp_int(PARROT_INTERP, PMC *self, INTVAL value) { 
    540     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    541         "no bignum lib loaded"); 
     665    THROW_NYI; 
    542666} 
    543667 
    544 static void 
    545 bignum_abs(PARROT_INTERP, PMC *self, PMC *dest) { 
    546     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    547         "no bignum lib loaded"); 
     668static INTVAL 
     669bignum_cmp_float(PARROT_INTERP, PMC *self, FLOATVAL value) { 
     670    THROW_NYI; 
    548671} 
    549672 
    550673static void 
    551 bignum_neg(PARROT_INTERP, PMC *self, PMC *dest) { 
    552     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    553         "no bignum lib loaded"); 
     674bignum_abs(PARROT_INTERP, PMC *self, PMC *dest) { 
     675    THROW_NYI; 
    554676} 
    555677 
    556678static void 
    557 bignum_bitwise_shl_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    558     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    559         "no bignum lib loaded"); 
     679bignum_neg(PARROT_INTERP, PMC *self, PMC *dest) { 
     680    THROW_NYI; 
    560681} 
    561682 
    562 static void 
    563 bignum_bitwise_shl_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) 
    564 { 
    565     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    566         "no bignum lib loaded"); 
     683static INTVAL 
     684bignum_get_default_prec(PARROT_INTERP, PMC *self) { 
     685    THROW_NYI; 
    567686} 
    568687 
    569688static void 
    570 bignum_bitwise_shr_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 
    571     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    572         "no bignum lib loaded"); 
     689bignum_set_default_prec(PARROT_INTERP, PMC *self, INTVAL prec) { 
     690    THROW_NYI; 
    573691} 
    574692 
    575 static void 
    576 bignum_bitwise_shr_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) 
    577 { 
    578     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
    579         "no bignum lib loaded"); 
    580 } 
     693#undef THROW_NYI 
    581694 
    582695#endif /* ifdef PARROT_HAS_GMP */ 
    583696 
    584697pmclass BigNum { 
    585     ATTR struct BIGNUM * bi; /*bignum val*/ 
     698    ATTR struct BIGNUM * bn; /*bignum val*/ 
    586699 
    587700/* 
    588701 
     
    621734 
    622735*/ 
    623736    VTABLE PMC *instantiate(PMC *sig) { 
    624         return PMCNULL; 
    625  
    626         /* TODO -- actually build this thing */ 
    627 #if 0 
     737#ifdef PARROT_HAS_GMP 
    628738        int argcP = REG_INT(interp, 3); 
    629739        int base; 
    630740        PMC *res; 
     
    640750        num = VTABLE_get_string(INTERP, REG_PMC(interp, 5)); 
    641751        VTABLE_set_string_keyed_int(INTERP, res, base, num); 
    642752        return res; 
     753#else 
     754        return PMCNULL; 
    643755#endif 
    644756    } 
    645757 
     
    655767    } 
    656768 
    657769    VTABLE void destroy() { 
    658         BIGNUM                   *bi; 
     770        BIGNUM                   *bn; 
    659771        Parrot_BigNum_attributes *attrs; 
    660772 
    661773        bignum_clear(INTERP, SELF); 
    662774 
    663775        attrs = (Parrot_BigNum_attributes*)PMC_data(SELF); 
    664776#ifdef PARROT_HAS_GMP 
    665         mem_sys_free(attrs->bi); 
     777        mem_sys_free(attrs->bn); 
    666778#endif 
    667779        mem_sys_free(attrs); 
    668780    } 
     
    676788*/ 
    677789 
    678790    VTABLE void set_integer_native(INTVAL value) { 
    679         bignum_set_long(INTERP, SELF, (long)value); 
     791        bignum_set_si(INTERP, SELF, (long)value); 
    680792    } 
    681793 
    682794/* 
    683795 
    684796=item C<void set_number_native(FLOATVAL value)> 
    685797 
    686 Sets the value of the bignum to C<value>. 
     798Sets the value of the BigNum to C<value>. 
    687799 
    688800=cut 
    689801 
     
    697809 
    698810=item C<void set_string_native(STRING *value)> 
    699811 
    700 Sets the value of the integer to the result of converting C<*value> to a 
     812Sets the value of the BigNum to the result of converting C<*value> to a 
    701813number. 
    702814 
    703815=item C<void set_string_keyed_int(INTVAL base, STRING *value)> 
     
    723835 
    724836=item C<void set_pmc(PMC *value)> 
    725837 
    726 Sets the value of the integer to the integer value of C<*value>. 
     838Sets the value of the BigNum to the BigNum value of C<*value>. 
    727839 
    728840=cut 
    729841 
     
    737849 
    738850=item C<FLOATVAL get_number()> 
    739851 
    740 Returns the value of the integer as a floating point number. 
     852Down-converts the precise BigNum to an imprecise double. 
    741853 
    742854=cut 
    743855 
     
    751863 
    752864=item C<INTVAL get_integer()> 
    753865 
    754 Returns the value of the integer. 
     866Returns the integer conversion of the BigNum. 
    755867 
    756868=cut 
    757869 
    758870*/ 
    759871 
    760872    VTABLE INTVAL get_integer() { 
    761         return bignum_get_long(INTERP, SELF); 
     873        return bignum_get_si(INTERP, SELF); 
     874    } 
     875 
     876/* 
     877 
     878=item C<INTVAL get_ulong()> 
     879 
     880Returns the unsigned long conversion of the BigNum. 
     881 
     882=cut 
     883 
     884*/ 
     885 
     886    VTABLE INTVAL get_ulong() { 
     887        return bignum_get_ui(INTERP, SELF); 
    762888    } 
    763889 
    764890/* 
    765891 
    766892=item C<PMC *get_bignum()> 
    767893 
    768 Returns SELF 
     894Returns SELF, keeping floating point precision. 
    769895 
    770896=cut 
    771897 
     
    777903 
    778904/* 
    779905 
     906=item C<FLOATVAL get_bigint()> 
     907 
     908Trunc the BigNum to an BigInt. 
     909 
     910=cut 
     911 
     912*/ 
     913 
     914    VTABLE BIGINT get_bigint() { 
     915#if PARROT_BIGNUM_CAN_BIGINT 
     916        return bignum_get_bigint(INTERP, SELF); 
     917#else 
     918        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, 
     919            "no bigint support in bigint"); 
     920#endif 
     921    } 
     922 
     923/* 
     924 
    780925=item C<INTVAL get_bool()> 
    781926 
    782 Returns the boolean value of the integer. 
     927Returns the boolean value of the BigNum. 
    783928 
    784929=cut 
    785930 
     
    793938 
    794939=item C<STRING *get_string()> 
    795940 
    796 Returns the string representation of the integer. 
     941Returns the string representation of the BigNum. 
    797942 
    798943=item C<STRING *get_string_keyed_int(INTVAL base)> 
    799944 
    800 Returns the string representation of the integer in base C<base>. 
     945Returns the string representation of the BigNum in base C<base>. 
     946 
     947=item C<STRING *get_string_keyed_int_int(INTVAL base, INTVAL digits)> 
     948 
     949Returns the string representation of the BigNum in base C<base> with 
     950C<digits> digits. 
    801951 
    802952=item C<STRING *get_repr()> 
    803953 
    804 Returns the string representation of the integer with the letter 'L' 
     954Returns the string representation of the BigNum with the letter 'N' 
    805955appended. 
    806956 
    807957=cut 
     
    822972        return ps; 
    823973    } 
    824974 
     975    VTABLE STRING *get_string_keyed_int_int(INTVAL base, INTVAL digits) { 
     976        char   *s  = bignum_get_string_size(INTERP, SELF, base, digits); 
     977        STRING *ps = Parrot_str_new(INTERP, s, 0); 
     978        mem_sys_free(s); 
     979        return ps; 
     980    } 
     981 
    825982    VTABLE STRING *get_repr() { 
    826983        STRING *s = SELF.get_string(); 
    827         return Parrot_str_append(INTERP, s, Parrot_str_new(interp, "L", 1)); 
     984        return Parrot_str_append(INTERP, s, Parrot_str_new(interp, "N", 1)); 
    828985    } 
    829986/* 
    830987 
    831988=item C<void increment()> 
    832989 
    833 Increments the integer. 
     990Increment the BigNum by 1.0. 
    834991 
    835992=cut 
    836993 
     
    8441001 
    8451002=item C<void decrement()> 
    8461003 
    847 Decrements the integer. 
     1004Decrement the BigNum by 1.0. 
    8481005 
    8491006=cut 
    8501007 
     
    8541011        bignum_sub_bignum_int(INTERP, SELF, 1, SELF); 
    8551012    } 
    8561013 
     1014/* 
     1015 
     1016=item C<void add()> 
     1017 
     1018=cut 
     1019 
     1020*/ 
     1021 
    8571022    MULTI PMC *add(BigNum value, PMC *dest) { 
    8581023        dest = pmc_new(INTERP, SELF->vtable->base_type); 
    8591024 
     
    8861051        bignum_add_bignum(INTERP, SELF, value, SELF); 
    8871052    } 
    8881053 
    889     MULTI void i_add(Integer value) { 
    890         bignum_add_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), SELF); 
     1054    MULTI void i_add(FLOATVAL value) { 
     1055        bignum_add_bignum_float(INTERP, SELF, value, SELF); 
    8911056    } 
    8921057 
    8931058    MULTI void i_add(DEFAULT value) { 
     
    9071072            "BigNum: no multiple dispatch variant 'i_add_float' for FLOATVAL"); 
    9081073    } 
    9091074 
     1075/* 
     1076 
     1077=item C<void substract()> 
     1078 
     1079=cut 
     1080 
     1081*/ 
    9101082 
    9111083    MULTI PMC *subtract(BigNum value, PMC *dest) { 
    9121084        if (dest) 
     
    9491121        bignum_sub_bignum(INTERP, SELF, value, SELF); 
    9501122    } 
    9511123 
    952     MULTI void i_subtract(Integer value) { 
    953         bignum_sub_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), SELF); 
     1124    MULTI void i_subtract(FLOATVAL value) { 
     1125        bignum_sub_bignum_float(INTERP, SELF, value, SELF); 
    9541126    } 
    9551127 
    9561128    MULTI void i_subtract(DEFAULT value) { 
     
    9701142            "BigNum: no multiple dispatch variant 'i_subtract_float' for FLOATVAL"); 
    9711143    } 
    9721144 
     1145/* 
     1146 
     1147=item C<void multiply()> 
     1148 
     1149=cut 
     1150 
     1151*/ 
    9731152 
    9741153    MULTI PMC *multiply(BigNum value, PMC *dest) { 
    9751154        dest = pmc_new(INTERP, SELF->vtable->base_type); 
     
    10021181    MULTI void i_multiply(BigNum value) { 
    10031182        bignum_mul_bignum(INTERP, SELF, value, SELF); 
    10041183    } 
     1184 
     1185    MULTI void i_multiply(FLOATVAL value) { 
     1186        bignum_mul_bignum_float(INTERP, SELF, value, SELF); 
     1187    } 
     1188 
    10051189    MULTI void i_multiply(Integer value) { 
    10061190        bignum_mul_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), SELF); 
    10071191    } 
     1192 
    10081193    MULTI void i_multiply(DEFAULT value) { 
    10091194        Parrot_ex_throw_from_c_args(INTERP, NULL, 
    10101195            EXCEPTION_INTERNAL_NOT_IMPLEMENTED, 
     
    10221207            "BigNum: no multiple dispatch variant 'i_multiply_float' for FLOATVAL"); 
    10231208    } 
    10241209 
     1210/* 
     1211 
     1212=item C<void pow()> 
     1213 
     1214=cut 
     1215 
     1216*/ 
     1217 
    10251218    VTABLE PMC *pow_int(INTVAL value, PMC *dest) { 
    10261219        if (dest) 
    10271220            pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 
     
    10331226    } 
    10341227 
    10351228    MULTI PMC *pow(PMC *value, PMC *dest) { 
    1036         /* XXX only Integer RHS currently */ 
     1229        /* only Integer RHS currently. TODO: check number and bignum types */ 
    10371230        INTVAL r = VTABLE_get_integer(INTERP, value); 
    10381231        dest = pmc_new(INTERP, SELF->vtable->base_type); 
    10391232 
     
    10411234        return dest; 
    10421235    } 
    10431236 
     1237/* 
     1238 
     1239=item C<void divide()> 
     1240 
     1241=cut 
     1242 
     1243*/ 
     1244 
    10441245    MULTI PMC *divide(BigNum value, PMC *dest) { 
    1045         BIGNUM *bi; 
     1246        BIGNUM *bn; 
    10461247        if (dest) 
    10471248            pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 
    10481249        else 
     
    10511252        bignum_div_bignum(INTERP, SELF, value, dest); 
    10521253#if 0 
    10531254        /* to downgrade or not that's the question */ 
    1054         GETATTR_BigNum_bi(interp, dest, bi); 
    1055         if (mpf_fits_slong_p(bi->b)) { 
    1056             long iresult = mpf_get_si(bi->b); 
     1255        GETATTR_BigNum_bn(interp, dest, bn); 
     1256        if (mpf_fits_slong_p(bn->b)) { 
     1257            long iresult = mpf_get_si(bn->b); 
    10571258            VTABLE_morph(interp, dest, enum_class_Integer); 
    10581259            VTABLE_set_integer_native(interp, dest, iresult); 
    10591260        } 
     
    11051306        bignum_div_bignum_int(INTERP, SELF, value, SELF); 
    11061307    } 
    11071308 
     1309/* 
     1310 
     1311=item C<void floor_divide()> 
     1312 
     1313=cut 
     1314 
     1315*/ 
     1316 
    11081317    MULTI PMC *floor_divide(BigNum value, PMC *dest) { 
    11091318        dest = pmc_new(INTERP, SELF->vtable->base_type); 
    11101319 
     
    11551364        bignum_fdiv_bignum_int(INTERP, SELF, value, SELF); 
    11561365    } 
    11571366 
    1158     MULTI PMC *modulus(BigNum value, PMC *dest) { 
    1159         if (dest) 
    1160             pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 
    1161         else 
    1162             dest = pmc_new(INTERP, SELF->vtable->base_type); 
    1163  
    1164         bignum_mod_bignum(INTERP, SELF, value, dest); 
    1165         return dest; 
    1166     } 
    1167  
    1168     MULTI PMC *modulus(Integer value, PMC *dest) { 
    1169         if (dest) 
    1170             pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 
    1171         else 
    1172             dest = pmc_new(INTERP, SELF->vtable->base_type); 
     1367/* 
    11731368 
    1174         bignum_mod_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), dest); 
    1175         return dest; 
    1176     } 
     1369=item C<void cmp()> 
    11771370 
    1178     MULTI PMC *modulus(DEFAULT value, PMC *dest) { 
    1179         Parrot_ex_throw_from_c_args(INTERP, NULL, 
    1180             EXCEPTION_INTERNAL_NOT_IMPLEMENTED, 
    1181             "BigNum: no multiple dispatch variant 'modulus' for %Ss", 
    1182             VTABLE_name(interp, value)); 
    1183     } 
     1371=cut 
    11841372 
    1185     MULTI void i_modulus(BigNum value) { 
    1186         bignum_mod_bignum(INTERP, SELF, value, SELF); 
    1187     } 
    1188     MULTI void i_modulus(Integer value) { 
    1189         bignum_mod_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), SELF); 
    1190     } 
    1191     MULTI void i_modulus(DEFAULT value) { 
    1192         Parrot_ex_throw_from_c_args(INTERP, NULL, 
    1193             EXCEPTION_INTERNAL_NOT_IMPLEMENTED, 
    1194             "BigNum: no multiple dispatch variant 'i_modulus' for %Ss", 
    1195             VTABLE_name(interp, value)); 
    1196     } 
     1373*/ 
    11971374 
    11981375    MULTI INTVAL cmp(BigNum value) { 
    11991376        return bignum_cmp(INTERP, SELF, value); 
     
    12101387            VTABLE_name(interp, value)); 
    12111388    } 
    12121389 
     1390/* 
     1391 
     1392=item C<void is_equal()> 
     1393 
     1394=cut 
     1395 
     1396*/ 
     1397 
    12131398    MULTI INTVAL is_equal(BigNum value) { 
    12141399        return bignum_cmp(INTERP, SELF, value) == 0; 
    12151400    } 
     
    12721457        bignum_neg(INTERP, SELF, SELF); 
    12731458    } 
    12741459 
    1275 /* 
    1276  
    1277 =item C<PMC *bitwise_shl(PMC *value, PMC *dest)> 
    1278  
    1279 =item C<PMC *bitwise_shl_int(INTVAL value, PMC *dest)> 
    1280  
    1281 Returns in C<*dest> the shift left of the BigNum by C<*value>. 
    1282  
    1283 =item C<void i_bitwise_shl(PMC *value)> 
    1284  
    1285 =item C<void i_bitwise_shl_int(INTVAL value)> 
    1286  
    1287 Inplace shift left. 
    1288  
    1289 =cut 
    1290  
    1291 */ 
    1292  
    1293     MULTI PMC *bitwise_shl(BigNum value, PMC *dest) { 
    1294         if (dest) 
    1295             pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 
    1296         else 
    1297             dest = pmc_new(INTERP, SELF->vtable->base_type); 
    1298  
    1299         bignum_bitwise_shl_bignum_int(INTERP, SELF, 
    1300                                       VTABLE_get_integer(INTERP, value), 
    1301                                       dest); 
    1302         return dest; 
    1303     } 
    1304  
    1305     MULTI PMC *bitwise_shl(Integer value, PMC *dest) { 
    1306         if (dest) 
    1307             pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 
    1308         else 
    1309             dest = pmc_new(INTERP, SELF->vtable->base_type); 
    1310  
    1311         bignum_bitwise_shl_bignum_int(INTERP, SELF, 
    1312                 VTABLE_get_integer(interp, value), dest); 
    1313         return dest; 
    1314     } 
    1315     MULTI PMC *bitwise_shl(DEFAULT value, PMC *dest) { 
    1316         Parrot_ex_throw_from_c_args(INTERP, NULL, 
    1317             EXCEPTION_INTERNAL_NOT_IMPLEMENTED, 
    1318             "BigNum: no multiple dispatch variant 'bitwise_shl' for %Ss", 
    1319             VTABLE_name(interp, value)); 
    1320     } 
    1321  
    1322     VTABLE PMC *bitwise_shl_int(INTVAL value, PMC *dest) { 
    1323         if (dest) 
    1324             pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 
    1325         else 
    1326             dest = pmc_new(INTERP, SELF->vtable->base_type); 
    1327  
    1328         bignum_bitwise_shl_bignum_int(INTERP, SELF, value, dest); 
    1329         return dest; 
    1330     } 
    1331  
    1332  
    1333     MULTI void i_bitwise_shl(BigNum value) { 
    1334         bignum_bitwise_shl_bignum_int(INTERP, SELF, 
    1335                                       VTABLE_get_integer(INTERP, value), 
    1336                                       SELF); 
    1337     } 
    1338  
    1339     MULTI void i_bitwise_shl(Integer value) { 
    1340         bignum_bitwise_shl_bignum_int(INTERP, SELF, 
    1341                 VTABLE_get_integer(interp, value), SELF); 
    1342     } 
    1343  
    1344     MULTI void i_bitwise_shl(DEFAULT value) { 
    1345         Parrot_ex_throw_from_c_args(INTERP, NULL, 
    1346             EXCEPTION_INTERNAL_NOT_IMPLEMENTED, 
    1347             "BigNum: no multiple dispatch variant 'i_bitwise_shl' for %Ss", 
    1348             VTABLE_name(interp, value)); 
    1349     } 
    1350  
    1351     VTABLE void i_bitwise_shl_int(INTVAL value) { 
    1352         bignum_bitwise_shl_bignum_int(INTERP, SELF, value, SELF); 
    1353     } 
    1354  
    1355 /* 
    1356  
    1357 =item C<PMC *bitwise_shr(PMC *value, PMC *dest)> 
    1358  
    1359 =item C<PMC *bitwise_shr_int(INTVAL value, PMC *dest)> 
    1360  
    1361 Returns in C<*dest> the shift right of the BigNum by C<*value>. 
    1362  
    1363 =item C<void i_bitwise_shr(PMC *value)> 
    1364  
    1365 =item C<void i_bitwise_shr_int(INTVAL value)> 
    1366  
    1367 Inplace shift left. 
    1368  
    1369 =cut 
    1370  
    1371 */ 
    1372  
    1373     MULTI PMC *bitwise_shr(BigNum value, PMC *dest) { 
    1374         if (dest) 
    1375             pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 
    1376         else 
    1377             dest = pmc_new(INTERP, SELF->vtable->base_type); 
    1378  
    1379         bignum_bitwise_shr_bignum_int(INTERP, SELF, 
    1380                                       VTABLE_get_integer(INTERP, value), 
    1381                                       dest); 
    1382         return dest; 
    1383     } 
    1384  
    1385     MULTI PMC *bitwise_shr(Integer value, PMC *dest) { 
    1386         if (dest) 
    1387             pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 
    1388         else 
    1389             dest = pmc_new(INTERP, SELF->vtable->base_type); 
    1390  
    1391         bignum_bitwise_shr_bignum_int(INTERP, SELF, 
    1392                 VTABLE_get_integer(interp, value), dest); 
    1393         return dest; 
    1394     } 
    1395  
    1396     MULTI PMC *bitwise_shr(DEFAULT value, PMC *dest) { 
    1397         Parrot_ex_throw_from_c_args(INTERP, NULL, 
    1398             EXCEPTION_INTERNAL_NOT_IMPLEMENTED, 
    1399             "BigNum: no multiple dispatch variant 'bitwise_shr' for %Ss", 
    1400             VTABLE_name(interp, value)); 
    1401     } 
    1402  
    1403     VTABLE PMC *bitwise_shr_int(INTVAL value, PMC *dest) { 
    1404         if (dest) 
    1405             pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 
    1406         else 
    1407             dest = pmc_new(INTERP, SELF->vtable->base_type); 
    1408  
    1409         bignum_bitwise_shr_bignum_int(INTERP, SELF, value, dest); 
    1410         return dest; 
    1411     } 
    1412  
    1413  
    1414     MULTI void i_bitwise_shr(BigNum value) { 
    1415         bignum_bitwise_shr_bignum_int(INTERP, SELF, 
    1416                                       VTABLE_get_integer(INTERP, value), 
    1417                                       SELF); 
    1418     } 
    1419  
    1420     MULTI void i_bitwise_shr(Integer value) { 
    1421         bignum_bitwise_shr_bignum_int(INTERP, SELF, 
    1422                 VTABLE_get_integer(interp, value), SELF); 
    1423     } 
    1424  
    1425     MULTI void i_bitwise_shr(DEFAULT value) { 
    1426         Parrot_ex_throw_from_c_args(INTERP, NULL, 
    1427             EXCEPTION_INTERNAL_NOT_IMPLEMENTED, 
    1428             "BigNum: no multiple dispatch variant 'i_bitwise_shr' for %Ss", 
    1429             VTABLE_name(interp, value)); 
    1430     } 
    1431  
    1432     VTABLE void i_bitwise_shr_int(INTVAL value) { 
    1433         bignum_bitwise_shr_bignum_int(INTERP, SELF, value, SELF); 
    1434     } 
    14351460} 
    14361461 
    14371462/* 
  • parrot-svn

    old new  
    28872887t/pmc/addrregistry.t                                        [test] 
    28882888t/pmc/array.t                                               [test] 
    28892889t/pmc/bigint.t                                              [test] 
     2890t/pmc/bignum.t                                              [test] 
    28902891t/pmc/boolean.t                                             [test] 
    28912892t/pmc/bound_nci.t                                           [test] 
    28922893t/pmc/callsignature.t                                       [test] 
  • (a) /dev/null vs. (b) parrot-svn/t/pmc/bignum.t

    a b  
     1#! perl 
     2# Copyright (C) 2009, The Perl Foundation. 
     3# $Id$ 
     4 
     5use strict; 
     6use warnings; 
     7use lib qw( . lib ../lib ../../lib ); 
     8 
     9use Test::More; 
     10use Parrot::Test; 
     11use Parrot::Config; 
     12 
     13=head1 NAME 
     14 
     15t/pmc/bignum.t - BigNum PMC 
     16 
     17=head1 SYNOPSIS 
     18 
     19    % prove t/pmc/bignum.t 
     20 
     21=head1 DESCRIPTION 
     22 
     23Tests the BigNum PMC. 
     24 
     25=cut 
     26 
     27if ( $PConfig{gmp} ) { 
     28    plan tests => 30; 
     29} 
     30else { 
     31    plan skip_all => "No BigNum PMC enabled"; 
     32} 
     33 
     34my $vers_check = <<'EOP'; 
     35.sub main :main 
     36    .local pmc b, ar 
     37    .local string v 
     38    .local int ma, mi, pa 
     39    b = new ['BigNum'] 
     40    v = b.'version'() 
     41    ar = split '.', v 
     42    ma = ar[0] 
     43    mi = ar[1] 
     44    pa = ar[2] 
     45    if ma >= 4 goto ge_4 
     46warn: 
     47    print 'GMP version ' 
     48    print v 
     49    say " is buggy with huge digit multiply - please upgrade" 
     50    end 
     51ge_4: 
     52   if mi >= 2 goto ok 
     53   if mi == 0 goto warn 
     54   # test 4.1.x 
     55   if pa >= 4 goto ok 
     56   goto warn 
     57   end 
     58ok: 
     59.end 
     60EOP 
     61 
     62if ( $PConfig{gmp} ) { 
     63 
     64    # argh 
     65    my $parrot = '.' . $PConfig{slash} . 'parrot' . $PConfig{exe}; 
     66    my $test   = 'temp_gmp_vers.pir'; 
     67    open my $O, '>', "$test" or die "can't open $test: $!"; 
     68    print $O $vers_check; 
     69    close $O; 
     70    my $warn = `$parrot $test`; 
     71    diag $warn if $warn; 
     72    unlink $test; 
     73} 
     74 
     75pasm_output_is( <<'CODE', <<'OUT', "create" ); 
     76   new P0, ['BigNum'] 
     77   say "ok" 
     78   end 
     79CODE 
     80ok 
     81OUT 
     82 
     83pasm_output_is( <<'CODE', <<'OUT', "set/get int" ); 
     84   new P0, ['BigNum'] 
     85   set P0, 999999 
     86   set I1, P0 
     87   say I1 
     88   get_repr S0, P0 
     89   say S0 
     90   end 
     91CODE 
     92999999 
     93999999N 
     94OUT 
     95 
     96pasm_output_is( <<"CODE", <<'OUT', "set int, get double" ); 
     97     .include 'include/fp_equality.pasm' 
     98     new P0, ['BigNum'] 
     99     set P0, 999999 
     100     set N1, P0 
     101     .fp_eq_pasm(N1, 999999.0, OK1) 
     102     print "not " 
     103OK1: say "ok 1" 
     104 
     105     set P0, -999999 
     106     set N1, P0 
     107     .fp_eq_pasm(N1, -999999.0, OK2) 
     108     print "not " 
     109OK2: say "ok 2" 
     110 
     111     set P0, 2147483646 
     112     set N1, P0 
     113     .fp_eq_pasm(N1, 2.147483646e9, OK3) 
     114     print "not " 
     115OK3: say "ok 3" 
     116 
     117     set P0, -2147483646 
     118     set N1, P0 
     119     .fp_eq_pasm(N1, -2.147483646e9, OK4) 
     120     print "not " 
     121OK4: say "ok 4" 
     122     end 
     123CODE 
     124ok 1 
     125ok 2 
     126ok 3 
     127ok 4 
     128OUT 
     129 
     130my @todo_str = ( todo => "bignum strings"); 
     131pasm_output_is( <<'CODE', <<'OUT', "set double, get str", @todo_str ); 
     132   new P0, ['BigNum'] 
     133   set P0, 1.23e12 
     134   say P0 
     135   set P0, "1230000000000.0000000000000000122" 
     136   say P0 
     137   end 
     138CODE 
     1391230000000000 
     1401230000000000.0000000000000000122 
     141OUT 
     142 
     143pasm_output_is( <<'CODE', <<'OUT', "add", @todo_str); 
     144   new P0, ['BigNum'] 
     145   set P0, 999999.5 
     146   new P1, ['BigNum'] 
     147   set P1, 1000000.5 
     148   new P2, ['BigNum'] 
     149   add P2, P0, P1 
     150   set S0, P2 
     151   say S0 
     152   set P0, "12345678987654321" 
     153   set P1, "10000000000000000" 
     154   add P2, P1, P0 
     155   set S0, P2 
     156   say S0 
     157   end 
     158CODE 
     1592000000 
     16022345678987654321 
     161OUT 
     162 
     163pasm_output_is( <<'CODE', <<'OUT', "add_int", @todo_str ); 
     164   new P0, ['BigNum'] 
     165   set P0, 999999 
     166   new P2, ['BigNum'] 
     167   add P2, P0, 1000000 
     168   set S0, P2 
     169   say S0 
     170   set P0, "100000000000000000000" 
     171   add P2, P0, 1000000 
     172   set S0, P2 
     173   say S0 
     174   end 
     175CODE 
     1761999999 
     177100000000000001000000 
     178OUT 
     179 
     180pasm_output_is( <<'CODE', <<'OUTPUT', "sub bignum" ); 
     181     new P0, ['BigNum'] 
     182     set P0, 12345678 
     183     new P1, ['BigNum'] 
     184     set P1, 5678 
     185     new P2, ['BigNum'] 
     186     sub P2, P0, P1 
     187     set I0, P2 
     188     eq I0, 12340000, OK1 
     189     print "not " 
     190OK1: say "ok 1" 
     191     set P0, "123456789012345678" 
     192     sub P2, P0, P1 
     193     new P3, ['BigNum'] 
     194     set P3, "123456789012340000" 
     195     eq P2, P3, OK2 
     196     print "not " 
     197OK2: say "ok 2" 
     198     set P1, "223456789012345678" 
     199     sub P2, P0, P1 
     200     set P3, "-100000000000000000" 
     201     eq P2, P3, OK3 
     202     print "not " 
     203OK3: say "ok 3" 
     204     end 
     205CODE 
     206ok 1 
     207ok 2 
     208ok 3 
     209OUTPUT 
     210 
     211pasm_output_is( <<'CODE', <<'OUTPUT', "sub native int" ); 
     212     new P0, ['BigNum'] 
     213     set P0, 12345678 
     214     new P2, ['BigNum'] 
     215     sub P2, P0, 5678 
     216     set I0, P2 
     217     eq I0, 12340000, OK1 
     218     print "not " 
     219OK1: say "ok 1" 
     220     set P0, "123456789012345678" 
     221     sub P2, P0, 5678 
     222     new P3, ['BigNum'] 
     223     set P3, "123456789012340000" 
     224     eq P2, P3, OK2 
     225     print "not " 
     226OK2: say "ok 2" 
     227     end 
     228CODE 
     229ok 1 
     230ok 2 
     231OUTPUT 
     232 
     233pasm_output_is( <<'CODE', <<'OUTPUT', "sub other int" ); 
     234     new P0, ['BigNum'] 
     235     set P0, 12345678 
     236     new P1, ['Integer'] 
     237     set P1, 5678 
     238     new P2, ['BigNum'] 
     239     sub P2, P0, P1 
     240     set I0, P2 
     241     eq I0, 12340000, OK1 
     242     print "not " 
     243OK1: say "ok 1" 
     244     set P0, "123456789012345678" 
     245     sub P2, P0, P1 
     246     new P3, ['BigNum'] 
     247     set P3, "123456789012340000" 
     248     eq P2, P3, OK2 
     249     print "not " 
     250OK2: say "ok 2" 
     251     set P0, 9876543 
     252     new P4, ['Integer'] 
     253     set P4, 44 
     254     sub P2, P0, P4 
     255     set I0, P2 
     256     eq I0, 9876499, OK3 
     257     print "not " 
     258OK3: say "ok 3" 
     259     set P0, "9876543219876543" 
     260     sub P2, P0, P4 
     261     set P3, "9876543219876499" 
     262     eq P3, P2, OK4 
     263     print "not " 
     264OK4: say "ok 4" 
     265     end 
     266CODE 
     267ok 1 
     268ok 2 
     269ok 3 
     270ok 4 
     271OUTPUT 
     272 
     273pasm_output_is( <<'CODE', <<'OUT', "mul", @todo_str ); 
     274   new P0, ['BigNum'] 
     275   set P0, 999.999 
     276   new P1, ['BigNum'] 
     277   set P1, 10.000005 
     278   new P2, ['BigNum'] 
     279   mul P2, P0, P1 
     280   set S0, P2 
     281   say S0 
     282   end 
     283CODE 
     2849999.994999995 
     285OUT 
     286 
     287pasm_output_is( <<'CODE', <<'OUT', "mul_float", @todo_str); 
     288   new P0, ['BigNum'] 
     289   set P0, 999.999 
     290   mul P2, P0, 10.000005 
     291   say P2 
     292   end 
     293CODE 
     2949999.994999995 
     295OUT 
     296 
     297pasm_output_is( <<'CODE', <<'OUT', "div bignum" ); 
     298     new P0, ['BigNum'] 
     299     set P0, "100000000000000000000" 
     300     new P1, ['BigNum'] 
     301     set P1, "100000000000000000000" 
     302     new P2, ['BigNum'] 
     303     div P2, P0, P1 
     304     set I0, P2 
     305     eq I0, 1, OK1 
     306     print "not " 
     307OK1: say "ok 1" 
     308 
     309     new P3, ['BigNum'] 
     310     set P3, "10000000000000" 
     311     set P1, 10000000 
     312     div P2, P0, P1 
     313     eq  P2, P3, OK2 
     314     print "not " 
     315OK2: say "ok 2" 
     316 
     317     set P1, 10 
     318     set P3, "10000000000000000000" 
     319     div P2, P0, P1 
     320     eq  P2, P3, OK3 
     321     print "not " 
     322OK3: say "ok 3" 
     323 
     324     set P1, -1 
     325     set P3, "-100000000000000000000" 
     326     div P2, P0, P1 
     327     eq  P2, P3, OK4 
     328     print "not " 
     329OK4: say "ok 4" 
     330     end 
     331CODE 
     332ok 1 
     333ok 2 
     334ok 3 
     335ok 4 
     336OUT 
     337 
     338pasm_output_is( <<'CODE', <<'OUT', "div native int" ); 
     339     new P0, ['BigNum'] 
     340     set P0, "100000000000000000000" 
     341     new P1, ['BigNum'] 
     342     div P1, P0, 10 
     343     new P2, ['BigNum'] 
     344     set P2, "10000000000000000000" 
     345     eq P1, P2, OK1 
     346     print "not " 
     347OK1: say "ok 1" 
     348 
     349     set P0, "100000000000000" 
     350     div P1, P0, 10000000 
     351     set P2, 10000000 
     352     eq  P1, P2, OK2 
     353     print "not " 
     354OK2: say "ok 2" 
     355     end 
     356CODE 
     357ok 1 
     358ok 2 
     359OUT 
     360 
     361pasm_output_is( <<'CODE', <<'OUT', "div other int" ); 
     362     new P0, ['BigNum'] 
     363     set P0, "100000000000000000000" 
     364     new P1, ['BigNum'] 
     365     new P3, ['Integer'] 
     366     set P3, 10 
     367     div P1, P0, P3 
     368     new P2, ['BigNum'] 
     369     set P2, "10000000000000000000" 
     370     eq P1, P2, OK1 
     371     print "not " 
     372OK1: say "ok 1" 
     373 
     374     set P0, "100000000000000" 
     375     new P4, ['Integer'] 
     376     set P4, 10000000 
     377     div P1, P0, P4 
     378     set P2, 10000000 
     379     eq  P1, P2, OK2 
     380     print "not " 
     381OK2: say "ok 2" 
     382     end 
     383CODE 
     384ok 1 
     385ok 2 
     386OUT 
     387 
     388my @todo_ov = ( todo => "bignum overflow" ); 
     389for my $op ( "/", "%" ) { 
     390    for my $type ( "BigNum", "Integer" ) { 
     391        pir_output_is( <<"CODE", <<OUTPUT, "bignum $op by zero $type", $op eq '/' ? () : @todo_str ); 
     392.sub _main :main 
     393    \$P0 = new ['BigNum'] 
     394    set \$P0, "1000000000000000000000" 
     395    \$P1 = new ['BigNum'] 
     396    ## divide by a zero $type 
     397    \$P2 = new ['$type'] 
     398    set \$P2, 0 
     399    push_eh OK 
     400    \$P1 = \$P0 $op \$P2 
     401    say "fail" 
     402    pop_eh 
     403OK: 
     404    get_results '0', \$P0 
     405    \$S0 = \$P0 
     406    say "ok" 
     407    say \$S0 
     408.end 
     409CODE 
     410ok 
     411Divide by zero 
     412OUTPUT 
     413    } 
     414} 
     415 
     416{ 
     417    my ( $a, $b, $c, $d, $e ); 
     418    if ( $PConfig{intvalsize} == 8 ) { 
     419        $a = '9223372036854775806';    # 2**63-2 
     420        $b = '1'; 
     421        $c = '9223372036854775807';    # still Integer 
     422        $d = '9223372036854775808';    # no more Integer 
     423        $e = '9223372036854775809';    # still no more Integer 
     424    } 
     425    elsif ( $PConfig{intvalsize} == 4 ) { 
     426        $a = '2147483646';             # 2**31-2 
     427        $b = '1'; 
     428        $c = '2147483647';             # still Integer 
     429        $d = '2147483648';             # no more PerlInt 
     430        $e = '2147483649';             # still no more PerlInt 
     431    } 
     432    else { 
     433        die "\$PConfig{intvalsize} == $PConfig{intvalsize}?\n"; 
     434    } 
     435 
     436    pasm_output_is( <<CODE, <<OUT, "add overflow Integer", @todo_ov ); 
     437   new P0, ['Integer'] 
     438   set P0, $a 
     439   new P1, ['Integer'] 
     440   set P1, $b 
     441   new P2, ['Integer'] 
     442   new P3, ['BigNum'] 
     443   set I3, 3 
     444lp: 
     445   add P2, P0, P1 
     446   set S0, P2 
     447   print S0 
     448   print " " 
     449   typeof S1, P2 
     450   say S1 
     451   add P1, $b 
     452   dec I3 
     453   if I3, lp 
     454   say "ok" 
     455ex: 
     456   end 
     457CODE 
     458$c Integer 
     459$d BigNum 
     460$e BigNum 
     461ok 
     462OUT 
     463 
     464    pasm_output_is( <<CODE, <<OUT, "add overflow Integer", @todo_ov ); 
     465   new P0, ['Integer'] 
     466   set P0, $a 
     467   new P1, ['Integer'] 
     468   set P1, $b 
     469   new P2, ['Integer'] 
     470   new P3, ['BigNum'] 
     471   set I3, 3 
     472lp: 
     473   add P2, P0, P1 
     474   set S0, P2 
     475   print S0 
     476   print " " 
     477   typeof S1, P2 
     478   say S1 
     479   add P1, $b 
     480   dec I3 
     481   if I3, lp 
     482   say "ok" 
     483ex: 
     484   end 
     485CODE 
     486$c Integer 
     487$d BigNum 
     488$e BigNum 
     489ok 
     490OUT 
     491} 
     492 
     493pasm_output_is( <<'CODE', <<'OUT', "abs", @todo_str ); 
     494   new P0, ['BigNum'] 
     495   set P0, "-1230000000000" 
     496   new P1, ['Undef'] 
     497   abs P1, P0 
     498   say P1 
     499   say P0 
     500   abs P0 
     501   say P0 
     502   end 
     503CODE 
     5041230000000000 
     505-1230000000000 
     5061230000000000 
     507OUT 
     508 
     509pir_output_is( << 'CODE', << 'OUTPUT', "check whether interface is done" ); 
     510 
     511.sub _main 
     512    .local pmc pmc1 
     513    pmc1 = new ['BigNum'] 
     514    .local int bool1 
     515    does bool1, pmc1, "scalar" 
     516    say bool1 
     517    does bool1, pmc1, "no_interface" 
     518    say bool1 
     519    end 
     520.end 
     521CODE 
     5221 
     5230 
     524OUTPUT 
     525 
     526pasm_output_is( <<"CODE", <<'OUTPUT', "Truth" ); 
     527     new P0, ['BigNum'] 
     528     set P0, "123456789123456789" 
     529     if P0, OK1 
     530     print "not " 
     531OK1: say "ok 1" 
     532     set P0, 0 
     533     unless P0, OK2 
     534     print "not " 
     535OK2: say "ok 2" 
     536     end 
     537CODE 
     538ok 1 
     539ok 2 
     540OUTPUT 
     541 
     542pasm_output_is( <<"CODE", <<'OUTPUT', "neg" ); 
     543     new P0, ['BigNum'] 
     544     new P1, ['BigNum'] 
     545     set P0, "123456789123456789" 
     546     neg P0 
     547     set P1, "-123456789123456789" 
     548     eq P0, P1, OK1 
     549     print "not " 
     550OK1: say "ok 1" 
     551     end 
     552CODE 
     553ok 1 
     554OUTPUT 
     555 
     556pir_output_is( <<'CODE', <<'OUT', "BUG #34949 gt" ); 
     557.sub main :main 
     558    .local pmc b 
     559    b = new ['BigNum'] 
     560    b = 1e10 
     561    if b > 4 goto ok 
     562    say "never" 
     563    end 
     564ok: 
     565    say "ok" 
     566.end 
     567CODE 
     568ok 
     569OUT 
     570 
     571pir_output_is( <<'CODE', <<'OUT', "BUG #34949 ge" ); 
     572.sub main :main 
     573    .local pmc b 
     574    b = new ['BigNum'] 
     575    b = 1e10 
     576    if b >= 4 goto ok 
     577    say "never" 
     578    end 
     579ok: 
     580    say "ok" 
     581.end 
     582CODE 
     583ok 
     584OUT 
     585 
     586pir_output_is( <<'CODE', <<'OUT', "BUG #34949 ne" ); 
     587.sub main :main 
     588    .local pmc b 
     589    b = new ['BigNum'] 
     590    b = 1e10 
     591    if b != 4 goto ok 
     592    say "never" 
     593    end 
     594ok: 
     595    say "ok" 
     596.end 
     597CODE 
     598ok 
     599OUT 
     600 
     601pir_output_is( <<'CODE', <<'OUT', "BUG #34949 eq" ); 
     602.sub main :main 
     603    .local pmc b 
     604    b = new ['BigNum'] 
     605    b = 1e10 
     606    if b == 4 goto nok 
     607    say "ok" 
     608    end 
     609nok: 
     610    say "nok" 
     611.end 
     612CODE 
     613ok 
     614OUT 
     615 
     616pir_output_is( <<'CODE', <<'OUT', "BUG #34949 le" ); 
     617.sub main :main 
     618    .local pmc b 
     619    b = new ['BigNum'] 
     620    b = 1e10 
     621    if b <= 4 goto nok 
     622    say "ok" 
     623    end 
     624nok: 
     625    say "nok" 
     626.end 
     627CODE 
     628ok 
     629OUT 
     630 
     631pir_output_is( <<'CODE', <<'OUT', "BUG #34949 lt" ); 
     632.sub main :main 
     633    .local pmc b 
     634    b = new ['BigNum'] 
     635    b = 1e10 
     636    if b < 4 goto nok 
     637    say "ok" 
     638    end 
     639nok: 
     640    say "nok" 
     641.end 
     642CODE 
     643ok 
     644OUT 
     645 
     646# Local Variables: 
     647#   mode: cperl 
     648#   cperl-indent-level: 4 
     649#   fill-column: 100 
     650# End: 
     651# vim: expandtab shiftwidth=4: 
  • parrot-svn

    old new  
    11# $Id: NEWS 36758 2009-02-15 12:42:38Z rurban $ 
    22 
    3 New in February 2009 release (r35855 to r36683) 
     3New in February 2009 release (r35855 to r36724) 
    44 
    55- Implementation 
    6   + Support for portable 'Inf' and 'NaN' 
     6  + Support for portable 'Inf', 'NaN' and -0.0 
    77  + pbc_disassemble prints constants in constants table 
    8   + Disabled incomplete BigNum implementation 
     8  + New experimental BigNum implementation 
    99  + Pair is now a dynamic loadable PMC 
    1010  + Various function name sanification 
    1111  + New implementation of Strings component