Ticket #280: tt280-bignum-pmc.patch
File tt280-bignum-pmc.patch, 56.7 KB (added by rurban, 13 years ago) |
---|
-
src/pmc/bignum.pmc
old new 8 8 9 9 =head1 DESCRIPTION 10 10 11 C<BigNum> provides arbitrary precision integer mathematic functions. 11 C<BigNum> provides arbitrary precision floating point mathematic 12 functions, based on the GMP mpf library. 13 14 =head1 SYNOPSIS 15 16 Make 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 24 Make 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) 12 39 13 40 =head2 Functions 14 41 15 42 =over 4 16 43 17 =item C<static void bignum_set_ long(Interp*, PMC *, long value)>44 =item C<static void bignum_set_si(Interp*, PMC *, long value)> 18 45 19 46 =item C<static void bignum_set_double(Interp*, PMC *, double value)> 20 47 … … 28 55 # undef PARROT_HAS_GMP /* splint barfs on the gmp.h header */ 29 56 #endif /* S_SPLINT_S */ 30 57 31 /* Temporariliy disabled until someone fix it */ 58 /* Uncomment to easily disable it */ 59 /* 32 60 #ifdef PARROT_HAS_GMP 33 61 # undef PARROT_HAS_GMP 34 62 #endif 63 #undef PARROT_BIGNUM_CAN_BIGINT 64 */ 35 65 36 66 #ifdef PARROT_HAS_GMP 67 # include "pmc_bigint.h" 37 68 # include <gmp.h> 38 69 typedef struct BIGNUM { 39 70 mpf_t b; 40 71 } BIGNUM; 41 42 72 #endif 43 73 44 74 static void … … 46 76 Parrot_BigNum_attributes *attrs = 47 77 mem_allocate_zeroed_typed(Parrot_BigNum_attributes); 48 78 #ifdef PARROT_HAS_GMP 49 attrs->b i= mem_allocate_zeroed_typed(BIGNUM);50 mpf_init(attrs->b i->b);79 attrs->bn = mem_allocate_zeroed_typed(BIGNUM); 80 mpf_init(attrs->bn->b); 51 81 #else 52 attrs->b i= NULL;82 attrs->bn = NULL; 53 83 #endif 54 84 PMC_data(self) = attrs; 55 85 } … … 58 88 static void 59 89 bignum_clear(PARROT_INTERP, PMC *self) { 60 90 #ifdef PARROT_HAS_GMP 61 BIGNUM *b i;62 GETATTR_BigNum_b i(interp, self, bi);63 mpf_clear(b i->b);91 BIGNUM *bn; 92 GETATTR_BigNum_bn(interp, self, bn); 93 mpf_clear(bn->b); 64 94 #endif 65 95 } 66 96 97 67 98 #ifdef PARROT_HAS_GMP 68 99 69 100 static void 70 101 bignum_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 110 static void 111 bignum_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); 77 115 } 78 116 79 117 static 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); 118 bignum_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 124 static void 125 bignum_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); 84 129 } 85 130 86 131 static void 87 132 bignum_set_double(PARROT_INTERP, PMC *self, double value) { 88 BIGNUM *b i;89 GETATTR_BigNum_b i(interp, self, bi);90 mpf_set_d(b i->b, value);133 BIGNUM *bn; 134 GETATTR_BigNum_bn(interp, self, bn); 135 mpf_set_d(bn->b, value); 91 136 } 92 137 93 138 static void 94 139 bignum_set_str(PARROT_INTERP, PMC *self, char *value, int base) { 95 BIGNUM *b i;96 GETATTR_BigNum_b i(interp, self, bi);97 mpf_set_str(b i->b, value, base);140 BIGNUM *bn; 141 GETATTR_BigNum_bn(interp, self, bn); 142 mpf_set_str(bn->b, value, base); 98 143 } 99 144 145 #ifdef PARROT_BIGNUM_CAN_BIGINT 146 static void 147 bignum_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 100 156 static BIGNUM* 101 157 bignum_get_self(PARROT_INTERP, PMC *self) { 102 BIGNUM *b i;103 GETATTR_BigNum_b i(interp, self, bi);104 return b i;158 BIGNUM *bn; 159 GETATTR_BigNum_bn(interp, self, bn); 160 return bn; 105 161 } 106 162 107 163 static void 108 164 bignum_set_self(PARROT_INTERP, PMC *self, BIGNUM *value) { 109 BIGNUM *b i;110 GETATTR_BigNum_b i(interp, self, bi);111 mpf_set(b i->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); 112 168 } 113 169 114 170 static 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); 171 bignum_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 180 static unsigned long 181 bignum_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); 120 186 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"); 122 188 } 123 189 124 190 static int 125 191 bignum_get_bool(PARROT_INTERP, PMC *self) { 126 BIGNUM *b i;127 GETATTR_BigNum_b i(interp, self, bi);128 if (mpf_sgn(b i->b) != 0)192 BIGNUM *bn; 193 GETATTR_BigNum_bn(interp, self, bn); 194 if (mpf_sgn(bn->b) != 0) 129 195 return 1; 130 196 else 131 197 return 0; … … 133 199 134 200 static char * 135 201 bignum_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 213 static char * 214 bignum_get_string_size(PARROT_INTERP, PMC *self, int base, int digits) { 215 BIGNUM *bn; 137 216 size_t n; 138 217 char *s; 218 mp_exp_t exponent; 139 219 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); 144 223 } 145 224 146 225 static double 147 226 bignum_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 232 static FLOATVAL 233 bignum_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 240 static struct BIGINT 241 bignum_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; 151 255 } 256 #endif 152 257 153 258 static void 154 259 bignum_add_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 155 BIGNUM *b i_self, *bi_value, *bi_dest;156 GETATTR_BigNum_b i(interp, self, bi_self);157 GETATTR_BigNum_b i(interp, value, bi_value);158 GETATTR_BigNum_b i(interp, dest, bi_dest);159 mpf_add(b i_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); 160 265 } 161 266 162 267 static void 163 268 bignum_add_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 164 BIGNUM *b i_self, *bi_dest;165 GETATTR_BigNum_b i(interp, self, bi_self);166 GETATTR_BigNum_b i(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); 167 272 if (value < 0) 168 mpf_sub_ui(b i_dest->b, bi_self->b, (unsigned long int)-value);273 mpf_sub_ui(bn_dest->b, bn_self->b, (unsigned long int)-value); 169 274 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 278 static void 279 bignum_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); 171 285 } 172 286 173 287 static void 174 288 bignum_sub_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 175 BIGNUM *b i_self, *bi_value, *bi_dest;176 GETATTR_BigNum_b i(interp, self, bi_self);177 GETATTR_BigNum_b i(interp, value, bi_value);178 GETATTR_BigNum_b i(interp, dest, bi_dest);179 mpf_sub(b i_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); 180 294 } 181 295 182 296 static void 183 297 bignum_sub_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 184 BIGNUM *b i_self, *bi_dest;185 GETATTR_BigNum_b i(interp, self, bi_self);186 GETATTR_BigNum_b i(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); 187 301 if (value < 0) 188 mpf_add_ui(b i_dest->b, bi_self->b, (unsigned long int)-value);302 mpf_add_ui(bn_dest->b, bn_self->b, (unsigned long int)-value); 189 303 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 307 static void 308 bignum_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); 191 314 } 192 315 193 316 static void 194 317 bignum_mul_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 195 BIGNUM *b i_self, *bi_value, *bi_dest;196 GETATTR_BigNum_b i(interp, self, bi_self);197 GETATTR_BigNum_b i(interp, value, bi_value);198 GETATTR_BigNum_b i(interp, dest, bi_dest);199 mpf_mul(b i_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); 200 323 } 201 324 202 325 static void 203 326 bignum_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 333 static void 334 bignum_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); 208 340 } 209 341 210 342 static void 211 343 bignum_pow_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 212 BIGNUM *b i_self, *bi_dest;213 GETATTR_BigNum_b i(interp, self, bi_self);214 GETATTR_BigNum_b i(interp, dest, bi_dest);215 mpf_pow_ui(b i_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); 216 348 } 217 349 218 350 static void … … 225 357 static void 226 358 bignum_check_divide_zero(PARROT_INTERP, PMC *value) { 227 359 /* Throw an exception if we are dividing by zero. */ 228 BIGNUM *b i;229 GETATTR_BigNum_b i(interp, value, bi);230 if (mpf_cmp_si(b i->b, 0) == 0)360 BIGNUM *bn; 361 GETATTR_BigNum_bn(interp, value, bn); 362 if (mpf_cmp_si(bn->b, 0) == 0) 231 363 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_DIV_BY_ZERO, 232 364 "Divide by zero"); 233 365 } 234 366 235 367 static void 236 368 bignum_div_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 237 BIGNUM *b i_self, *bi_value, *bi_dest;369 BIGNUM *bn_self, *bn_value, *bn_dest; 238 370 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); 244 375 } 245 376 246 377 static void 247 378 bignum_div_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 248 BIGNUM *b i_self, *bi_dest;249 GETATTR_BigNum_b i(interp, self, bi_self);250 GETATTR_BigNum_b i(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); 251 382 int_check_divide_zero(interp, value); 252 383 253 /* this is mp f_fdiv_q */384 /* this is mpz_fdiv_q */ 254 385 if (value < 0) { 255 mpf_div_ui(b i_dest->b, bi_self->b, (unsigned long int)-value);256 mpf_neg(b i_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); 257 388 } 258 389 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); 270 391 } 271 392 272 393 static void 273 bignum_ fdiv_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {274 BIGNUM *b i_self, *bi_dest;275 GETATTR_BigNum_b i(interp, self, bi_self);276 GETATTR_BigNum_b i(interp, dest, bi_dest);394 bignum_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); 277 398 int_check_divide_zero(interp, value); 278 399 279 400 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); 282 404 } 283 405 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); 285 407 } 286 408 409 /* There's no such mpf_fdiv, only mpz_fdiv and mpf_div */ 287 410 static void 288 bignum_ mod_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {289 BIGNUM *b i_self, *bi_value, *bi_dest;290 GETATTR_BigNum_b i(interp, self, bi_self);291 GETATTR_BigNum_b i(interp, value, bi_value);292 GETATTR_BigNum_b i(interp, dest, bi_dest);411 bignum_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); 293 416 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); 295 418 } 296 419 297 420 static void 298 bignum_ mod_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {299 BIGNUM *b i_self, *bi_dest;300 GETATTR_BigNum_b i(interp, self, bi_self);301 GETATTR_BigNum_b i(interp, dest, bi_dest);421 bignum_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); 302 425 int_check_divide_zero(interp, value); 303 426 304 427 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); 306 430 } 307 431 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); 309 433 } 310 434 311 435 static INTVAL 312 436 bignum_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 443 static INTVAL 444 bignum_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); 317 448 } 318 449 319 450 static INTVAL 320 451 bignum_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 457 static INTVAL 458 bignum_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); 324 462 } 325 463 326 464 static void 327 465 bignum_abs(PARROT_INTERP, PMC *self, PMC *dest) { 328 BIGNUM *b i_self, *bi_dest;466 BIGNUM *bn_self, *bn_dest; 329 467 pmc_reuse(interp, dest, enum_class_BigNum, 0); 330 GETATTR_BigNum_b i(interp, self, bi_self);331 GETATTR_BigNum_b i(interp, dest, bi_dest);332 mpf_abs(b i_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); 333 471 } 334 472 335 473 static void 336 474 bignum_neg(PARROT_INTERP, PMC *self, PMC *dest) { 337 BIGNUM *b i_self, *bi_dest;475 BIGNUM *bn_self, *bn_dest; 338 476 pmc_reuse(interp, dest, enum_class_BigNum, 0); 339 GETATTR_BigNum_b i(interp, self, bi_self);340 GETATTR_BigNum_b i(interp, dest, bi_dest);341 mpf_neg(b i_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); 342 480 } 343 481 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); 482 static INTVAL 483 bignum_get_default_prec(PARROT_INTERP, PMC *self) { 484 return mpf_get_default_prec(); 357 485 } 358 486 359 487 static 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); 488 bignum_set_default_prec(PARROT_INTERP, PMC *self, INTVAL prec) { 489 mpf_set_default_prec(prec); 372 490 } 373 491 374 492 #else /* ifdef PARROT_HAS_GMP */ … … 377 495 FLOATVAL b; /* bogus definition for users without libgmp*/ 378 496 } BIGNUM; 379 497 498 #define THROW_NYI Parrot_ex_throw_from_c_args(interp, NULL, \ 499 EXCEPTION_LIBRARY_ERROR, "no bignum lib loaded") 500 380 501 # if 0 381 502 static void 382 503 bignum_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; 385 505 } 386 506 387 507 static void 388 508 bignum_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; 391 510 } 392 511 # endif 393 512 394 513 static 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"); 514 bignum_set(PARROT_INTERP, PMC *dest, PMC *src) { 515 THROW_NYI; 398 516 } 399 517 400 518 static 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"); 519 bignum_set_si(PARROT_INTERP, PMC *self, long value) { 520 THROW_NYI; 404 521 } 405 522 406 523 static void 407 524 bignum_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; 410 526 } 411 527 412 528 static void 413 529 bignum_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; 416 531 } 417 532 418 533 static void 419 534 bignum_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; 422 536 } 423 537 424 538 static BIGNUM* 425 539 bignum_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; 428 541 } 429 542 430 543 static char * 431 544 bignum_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 548 static char * 549 bignum_get_string_size(PARROT_INTERP, PMC *self, int base, int digits) { 550 THROW_NYI; 551 } 552 553 static unsigned long 554 bignum_get_ui(PARROT_INTERP, PMC *self) { 555 THROW_NYI; 434 556 } 435 557 436 558 static 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"); 559 bignum_get_si(PARROT_INTERP, PMC *self) { 560 THROW_NYI; 440 561 } 441 562 442 563 static long 443 564 bignum_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; 446 566 } 447 567 448 568 static double 449 569 bignum_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; 452 571 } 453 572 454 573 static void 455 574 bignum_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; 458 576 } 459 577 460 578 static void 461 579 bignum_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 583 static void 584 bignum_add_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 585 THROW_NYI; 464 586 } 465 587 466 588 static void 467 589 bignum_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; 470 591 } 471 592 472 593 static void 473 594 bignum_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 598 static void 599 bignum_sub_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 600 THROW_NYI; 476 601 } 477 602 478 603 static void 479 604 bignum_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; 482 606 } 483 607 484 608 static void 485 609 bignum_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 613 static void 614 bignum_mul_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 615 THROW_NYI; 488 616 } 489 617 490 618 static void 491 619 bignum_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 623 static void 624 bignum_pow_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 625 THROW_NYI; 494 626 } 495 627 496 628 static void 497 629 bignum_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; 500 631 } 501 632 502 633 static void 503 634 bignum_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; 506 636 } 507 637 508 638 static 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"); 639 bignum_div_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 640 THROW_NYI; 512 641 } 513 642 514 643 static 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"); 644 bignum_fdiv_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) { 645 THROW_NYI; 518 646 } 519 647 520 648 static 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"); 649 bignum_fdiv_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) { 650 THROW_NYI; 524 651 } 525 652 526 653 static 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"); 654 bignum_fdiv_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) { 655 THROW_NYI; 530 656 } 531 657 532 658 static INTVAL 533 659 bignum_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; 536 661 } 537 662 538 663 static INTVAL 539 664 bignum_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; 542 666 } 543 667 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"); 668 static INTVAL 669 bignum_cmp_float(PARROT_INTERP, PMC *self, FLOATVAL value) { 670 THROW_NYI; 548 671 } 549 672 550 673 static 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"); 674 bignum_abs(PARROT_INTERP, PMC *self, PMC *dest) { 675 THROW_NYI; 554 676 } 555 677 556 678 static 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"); 679 bignum_neg(PARROT_INTERP, PMC *self, PMC *dest) { 680 THROW_NYI; 560 681 } 561 682 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"); 683 static INTVAL 684 bignum_get_default_prec(PARROT_INTERP, PMC *self) { 685 THROW_NYI; 567 686 } 568 687 569 688 static 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"); 689 bignum_set_default_prec(PARROT_INTERP, PMC *self, INTVAL prec) { 690 THROW_NYI; 573 691 } 574 692 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 581 694 582 695 #endif /* ifdef PARROT_HAS_GMP */ 583 696 584 697 pmclass BigNum { 585 ATTR struct BIGNUM * b i; /*bignum val*/698 ATTR struct BIGNUM * bn; /*bignum val*/ 586 699 587 700 /* 588 701 … … 621 734 622 735 */ 623 736 VTABLE PMC *instantiate(PMC *sig) { 624 return PMCNULL; 625 626 /* TODO -- actually build this thing */ 627 #if 0 737 #ifdef PARROT_HAS_GMP 628 738 int argcP = REG_INT(interp, 3); 629 739 int base; 630 740 PMC *res; … … 640 750 num = VTABLE_get_string(INTERP, REG_PMC(interp, 5)); 641 751 VTABLE_set_string_keyed_int(INTERP, res, base, num); 642 752 return res; 753 #else 754 return PMCNULL; 643 755 #endif 644 756 } 645 757 … … 655 767 } 656 768 657 769 VTABLE void destroy() { 658 BIGNUM *b i;770 BIGNUM *bn; 659 771 Parrot_BigNum_attributes *attrs; 660 772 661 773 bignum_clear(INTERP, SELF); 662 774 663 775 attrs = (Parrot_BigNum_attributes*)PMC_data(SELF); 664 776 #ifdef PARROT_HAS_GMP 665 mem_sys_free(attrs->b i);777 mem_sys_free(attrs->bn); 666 778 #endif 667 779 mem_sys_free(attrs); 668 780 } … … 676 788 */ 677 789 678 790 VTABLE void set_integer_native(INTVAL value) { 679 bignum_set_ long(INTERP, SELF, (long)value);791 bignum_set_si(INTERP, SELF, (long)value); 680 792 } 681 793 682 794 /* 683 795 684 796 =item C<void set_number_native(FLOATVAL value)> 685 797 686 Sets the value of the bignum to C<value>.798 Sets the value of the BigNum to C<value>. 687 799 688 800 =cut 689 801 … … 697 809 698 810 =item C<void set_string_native(STRING *value)> 699 811 700 Sets the value of the integerto the result of converting C<*value> to a812 Sets the value of the BigNum to the result of converting C<*value> to a 701 813 number. 702 814 703 815 =item C<void set_string_keyed_int(INTVAL base, STRING *value)> … … 723 835 724 836 =item C<void set_pmc(PMC *value)> 725 837 726 Sets the value of the integer to the integervalue of C<*value>.838 Sets the value of the BigNum to the BigNum value of C<*value>. 727 839 728 840 =cut 729 841 … … 737 849 738 850 =item C<FLOATVAL get_number()> 739 851 740 Returns the value of the integer as a floating point number.852 Down-converts the precise BigNum to an imprecise double. 741 853 742 854 =cut 743 855 … … 751 863 752 864 =item C<INTVAL get_integer()> 753 865 754 Returns the value of the integer.866 Returns the integer conversion of the BigNum. 755 867 756 868 =cut 757 869 758 870 */ 759 871 760 872 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 880 Returns 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); 762 888 } 763 889 764 890 /* 765 891 766 892 =item C<PMC *get_bignum()> 767 893 768 Returns SELF 894 Returns SELF, keeping floating point precision. 769 895 770 896 =cut 771 897 … … 777 903 778 904 /* 779 905 906 =item C<FLOATVAL get_bigint()> 907 908 Trunc 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 780 925 =item C<INTVAL get_bool()> 781 926 782 Returns the boolean value of the integer.927 Returns the boolean value of the BigNum. 783 928 784 929 =cut 785 930 … … 793 938 794 939 =item C<STRING *get_string()> 795 940 796 Returns the string representation of the integer.941 Returns the string representation of the BigNum. 797 942 798 943 =item C<STRING *get_string_keyed_int(INTVAL base)> 799 944 800 Returns the string representation of the integer in base C<base>. 945 Returns 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 949 Returns the string representation of the BigNum in base C<base> with 950 C<digits> digits. 801 951 802 952 =item C<STRING *get_repr()> 803 953 804 Returns the string representation of the integer with the letter 'L'954 Returns the string representation of the BigNum with the letter 'N' 805 955 appended. 806 956 807 957 =cut … … 822 972 return ps; 823 973 } 824 974 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 825 982 VTABLE STRING *get_repr() { 826 983 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)); 828 985 } 829 986 /* 830 987 831 988 =item C<void increment()> 832 989 833 Increment s the integer.990 Increment the BigNum by 1.0. 834 991 835 992 =cut 836 993 … … 844 1001 845 1002 =item C<void decrement()> 846 1003 847 Decrement s the integer.1004 Decrement the BigNum by 1.0. 848 1005 849 1006 =cut 850 1007 … … 854 1011 bignum_sub_bignum_int(INTERP, SELF, 1, SELF); 855 1012 } 856 1013 1014 /* 1015 1016 =item C<void add()> 1017 1018 =cut 1019 1020 */ 1021 857 1022 MULTI PMC *add(BigNum value, PMC *dest) { 858 1023 dest = pmc_new(INTERP, SELF->vtable->base_type); 859 1024 … … 886 1051 bignum_add_bignum(INTERP, SELF, value, SELF); 887 1052 } 888 1053 889 MULTI void i_add( Integervalue) {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); 891 1056 } 892 1057 893 1058 MULTI void i_add(DEFAULT value) { … … 907 1072 "BigNum: no multiple dispatch variant 'i_add_float' for FLOATVAL"); 908 1073 } 909 1074 1075 /* 1076 1077 =item C<void substract()> 1078 1079 =cut 1080 1081 */ 910 1082 911 1083 MULTI PMC *subtract(BigNum value, PMC *dest) { 912 1084 if (dest) … … 949 1121 bignum_sub_bignum(INTERP, SELF, value, SELF); 950 1122 } 951 1123 952 MULTI void i_subtract( Integervalue) {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); 954 1126 } 955 1127 956 1128 MULTI void i_subtract(DEFAULT value) { … … 970 1142 "BigNum: no multiple dispatch variant 'i_subtract_float' for FLOATVAL"); 971 1143 } 972 1144 1145 /* 1146 1147 =item C<void multiply()> 1148 1149 =cut 1150 1151 */ 973 1152 974 1153 MULTI PMC *multiply(BigNum value, PMC *dest) { 975 1154 dest = pmc_new(INTERP, SELF->vtable->base_type); … … 1002 1181 MULTI void i_multiply(BigNum value) { 1003 1182 bignum_mul_bignum(INTERP, SELF, value, SELF); 1004 1183 } 1184 1185 MULTI void i_multiply(FLOATVAL value) { 1186 bignum_mul_bignum_float(INTERP, SELF, value, SELF); 1187 } 1188 1005 1189 MULTI void i_multiply(Integer value) { 1006 1190 bignum_mul_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), SELF); 1007 1191 } 1192 1008 1193 MULTI void i_multiply(DEFAULT value) { 1009 1194 Parrot_ex_throw_from_c_args(INTERP, NULL, 1010 1195 EXCEPTION_INTERNAL_NOT_IMPLEMENTED, … … 1022 1207 "BigNum: no multiple dispatch variant 'i_multiply_float' for FLOATVAL"); 1023 1208 } 1024 1209 1210 /* 1211 1212 =item C<void pow()> 1213 1214 =cut 1215 1216 */ 1217 1025 1218 VTABLE PMC *pow_int(INTVAL value, PMC *dest) { 1026 1219 if (dest) 1027 1220 pmc_reuse(interp, dest, SELF->vtable->base_type, 0); … … 1033 1226 } 1034 1227 1035 1228 MULTI PMC *pow(PMC *value, PMC *dest) { 1036 /* XXX only Integer RHS currently*/1229 /* only Integer RHS currently. TODO: check number and bignum types */ 1037 1230 INTVAL r = VTABLE_get_integer(INTERP, value); 1038 1231 dest = pmc_new(INTERP, SELF->vtable->base_type); 1039 1232 … … 1041 1234 return dest; 1042 1235 } 1043 1236 1237 /* 1238 1239 =item C<void divide()> 1240 1241 =cut 1242 1243 */ 1244 1044 1245 MULTI PMC *divide(BigNum value, PMC *dest) { 1045 BIGNUM *b i;1246 BIGNUM *bn; 1046 1247 if (dest) 1047 1248 pmc_reuse(interp, dest, SELF->vtable->base_type, 0); 1048 1249 else … … 1051 1252 bignum_div_bignum(INTERP, SELF, value, dest); 1052 1253 #if 0 1053 1254 /* to downgrade or not that's the question */ 1054 GETATTR_BigNum_b i(interp, dest, bi);1055 if (mpf_fits_slong_p(b i->b)) {1056 long iresult = mpf_get_si(b i->b);1255 GETATTR_BigNum_bn(interp, dest, bn); 1256 if (mpf_fits_slong_p(bn->b)) { 1257 long iresult = mpf_get_si(bn->b); 1057 1258 VTABLE_morph(interp, dest, enum_class_Integer); 1058 1259 VTABLE_set_integer_native(interp, dest, iresult); 1059 1260 } … … 1105 1306 bignum_div_bignum_int(INTERP, SELF, value, SELF); 1106 1307 } 1107 1308 1309 /* 1310 1311 =item C<void floor_divide()> 1312 1313 =cut 1314 1315 */ 1316 1108 1317 MULTI PMC *floor_divide(BigNum value, PMC *dest) { 1109 1318 dest = pmc_new(INTERP, SELF->vtable->base_type); 1110 1319 … … 1155 1364 bignum_fdiv_bignum_int(INTERP, SELF, value, SELF); 1156 1365 } 1157 1366 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 /* 1173 1368 1174 bignum_mod_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), dest); 1175 return dest; 1176 } 1369 =item C<void cmp()> 1177 1370 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 1184 1372 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 */ 1197 1374 1198 1375 MULTI INTVAL cmp(BigNum value) { 1199 1376 return bignum_cmp(INTERP, SELF, value); … … 1210 1387 VTABLE_name(interp, value)); 1211 1388 } 1212 1389 1390 /* 1391 1392 =item C<void is_equal()> 1393 1394 =cut 1395 1396 */ 1397 1213 1398 MULTI INTVAL is_equal(BigNum value) { 1214 1399 return bignum_cmp(INTERP, SELF, value) == 0; 1215 1400 } … … 1272 1457 bignum_neg(INTERP, SELF, SELF); 1273 1458 } 1274 1459 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 =cut1290 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 else1297 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 else1309 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 else1326 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 =cut1370 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 else1377 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 else1389 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 else1407 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 }1435 1460 } 1436 1461 1437 1462 /* -
parrot-svn
old new 2887 2887 t/pmc/addrregistry.t [test] 2888 2888 t/pmc/array.t [test] 2889 2889 t/pmc/bigint.t [test] 2890 t/pmc/bignum.t [test] 2890 2891 t/pmc/boolean.t [test] 2891 2892 t/pmc/bound_nci.t [test] 2892 2893 t/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 5 use strict; 6 use warnings; 7 use lib qw( . lib ../lib ../../lib ); 8 9 use Test::More; 10 use Parrot::Test; 11 use Parrot::Config; 12 13 =head1 NAME 14 15 t/pmc/bignum.t - BigNum PMC 16 17 =head1 SYNOPSIS 18 19 % prove t/pmc/bignum.t 20 21 =head1 DESCRIPTION 22 23 Tests the BigNum PMC. 24 25 =cut 26 27 if ( $PConfig{gmp} ) { 28 plan tests => 30; 29 } 30 else { 31 plan skip_all => "No BigNum PMC enabled"; 32 } 33 34 my $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 46 warn: 47 print 'GMP version ' 48 print v 49 say " is buggy with huge digit multiply - please upgrade" 50 end 51 ge_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 58 ok: 59 .end 60 EOP 61 62 if ( $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 75 pasm_output_is( <<'CODE', <<'OUT', "create" ); 76 new P0, ['BigNum'] 77 say "ok" 78 end 79 CODE 80 ok 81 OUT 82 83 pasm_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 91 CODE 92 999999 93 999999N 94 OUT 95 96 pasm_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 " 103 OK1: say "ok 1" 104 105 set P0, -999999 106 set N1, P0 107 .fp_eq_pasm(N1, -999999.0, OK2) 108 print "not " 109 OK2: say "ok 2" 110 111 set P0, 2147483646 112 set N1, P0 113 .fp_eq_pasm(N1, 2.147483646e9, OK3) 114 print "not " 115 OK3: say "ok 3" 116 117 set P0, -2147483646 118 set N1, P0 119 .fp_eq_pasm(N1, -2.147483646e9, OK4) 120 print "not " 121 OK4: say "ok 4" 122 end 123 CODE 124 ok 1 125 ok 2 126 ok 3 127 ok 4 128 OUT 129 130 my @todo_str = ( todo => "bignum strings"); 131 pasm_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 138 CODE 139 1230000000000 140 1230000000000.0000000000000000122 141 OUT 142 143 pasm_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 158 CODE 159 2000000 160 22345678987654321 161 OUT 162 163 pasm_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 175 CODE 176 1999999 177 100000000000001000000 178 OUT 179 180 pasm_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 " 190 OK1: 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 " 197 OK2: say "ok 2" 198 set P1, "223456789012345678" 199 sub P2, P0, P1 200 set P3, "-100000000000000000" 201 eq P2, P3, OK3 202 print "not " 203 OK3: say "ok 3" 204 end 205 CODE 206 ok 1 207 ok 2 208 ok 3 209 OUTPUT 210 211 pasm_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 " 219 OK1: 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 " 226 OK2: say "ok 2" 227 end 228 CODE 229 ok 1 230 ok 2 231 OUTPUT 232 233 pasm_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 " 243 OK1: 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 " 250 OK2: 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 " 258 OK3: say "ok 3" 259 set P0, "9876543219876543" 260 sub P2, P0, P4 261 set P3, "9876543219876499" 262 eq P3, P2, OK4 263 print "not " 264 OK4: say "ok 4" 265 end 266 CODE 267 ok 1 268 ok 2 269 ok 3 270 ok 4 271 OUTPUT 272 273 pasm_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 283 CODE 284 9999.994999995 285 OUT 286 287 pasm_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 293 CODE 294 9999.994999995 295 OUT 296 297 pasm_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 " 307 OK1: 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 " 315 OK2: 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 " 322 OK3: 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 " 329 OK4: say "ok 4" 330 end 331 CODE 332 ok 1 333 ok 2 334 ok 3 335 ok 4 336 OUT 337 338 pasm_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 " 347 OK1: 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 " 354 OK2: say "ok 2" 355 end 356 CODE 357 ok 1 358 ok 2 359 OUT 360 361 pasm_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 " 372 OK1: 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 " 381 OK2: say "ok 2" 382 end 383 CODE 384 ok 1 385 ok 2 386 OUT 387 388 my @todo_ov = ( todo => "bignum overflow" ); 389 for 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 403 OK: 404 get_results '0', \$P0 405 \$S0 = \$P0 406 say "ok" 407 say \$S0 408 .end 409 CODE 410 ok 411 Divide by zero 412 OUTPUT 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 444 lp: 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" 455 ex: 456 end 457 CODE 458 $c Integer 459 $d BigNum 460 $e BigNum 461 ok 462 OUT 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 472 lp: 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" 483 ex: 484 end 485 CODE 486 $c Integer 487 $d BigNum 488 $e BigNum 489 ok 490 OUT 491 } 492 493 pasm_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 503 CODE 504 1230000000000 505 -1230000000000 506 1230000000000 507 OUT 508 509 pir_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 521 CODE 522 1 523 0 524 OUTPUT 525 526 pasm_output_is( <<"CODE", <<'OUTPUT', "Truth" ); 527 new P0, ['BigNum'] 528 set P0, "123456789123456789" 529 if P0, OK1 530 print "not " 531 OK1: say "ok 1" 532 set P0, 0 533 unless P0, OK2 534 print "not " 535 OK2: say "ok 2" 536 end 537 CODE 538 ok 1 539 ok 2 540 OUTPUT 541 542 pasm_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 " 550 OK1: say "ok 1" 551 end 552 CODE 553 ok 1 554 OUTPUT 555 556 pir_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 564 ok: 565 say "ok" 566 .end 567 CODE 568 ok 569 OUT 570 571 pir_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 579 ok: 580 say "ok" 581 .end 582 CODE 583 ok 584 OUT 585 586 pir_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 594 ok: 595 say "ok" 596 .end 597 CODE 598 ok 599 OUT 600 601 pir_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 609 nok: 610 say "nok" 611 .end 612 CODE 613 ok 614 OUT 615 616 pir_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 624 nok: 625 say "nok" 626 .end 627 CODE 628 ok 629 OUT 630 631 pir_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 639 nok: 640 say "nok" 641 .end 642 CODE 643 ok 644 OUT 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 1 1 # $Id: NEWS 36758 2009-02-15 12:42:38Z rurban $ 2 2 3 New in February 2009 release (r35855 to r36 683)3 New in February 2009 release (r35855 to r36724) 4 4 5 5 - Implementation 6 + Support for portable 'Inf' and 'NaN'6 + Support for portable 'Inf', 'NaN' and -0.0 7 7 + pbc_disassemble prints constants in constants table 8 + Disabled incompleteBigNum implementation8 + New experimental BigNum implementation 9 9 + Pair is now a dynamic loadable PMC 10 10 + Various function name sanification 11 11 + New implementation of Strings component