static void dec128_to_mpd_conv(mpd_context_t * ctx, mpd_t *result, const uint64_t significand_low, const int64_t significand_high, const int64_t exponent_part){ uint32_t status = 0; mpd_t *ten, *sig1, *sig2, *stemp, *sig, *s64, *exp_pow, *exp_partmpd; ten = mpd_qnew(); s64 = mpd_qnew(); sig1 = mpd_qnew(); sig2 = mpd_qnew(); stemp = mpd_qnew(); sig = mpd_qnew(); exp_pow = mpd_qnew(); exp_partmpd = mpd_qnew(); mpd_qset_i64(ten,10LL,ctx,&status); /* 2^64 */ mpd_qset_string(s64,"18446744073709551616",ctx,&status); mpd_qset_u64(sig1,significand_low,ctx,&status); mpd_qset_i64(sig2,significand_high,ctx,&status); mpd_qmul(stemp,sig2,s64,ctx,&status); mpd_qadd(sig,stemp,sig1,ctx,&status); mpd_qset_i64(exp_partmpd,exponent_part,ctx,&status); mpd_qpow(exp_pow,ten,exp_partmpd,ctx,&status); mpd_qmul(result,sig,exp_pow,ctx,&status); mpd_del(ten); mpd_del(sig1); mpd_del(sig2); mpd_del(sig); mpd_del(stemp); mpd_del(s64); mpd_del(exp_pow); mpd_del(exp_partmpd); }
void test_mpd(void) { mpd_context_t ctx; mpd_t *n; char *sn = NULL; uint32_t res = 0; mpd_maxcontext(&ctx); n = mpd_qnew(); if (!n) { die("Allocating new number failed\n"); } mpd_qset_string(n, NUMBER1, &ctx, &res); sn = mpd_to_sci(n, 0); if (strcmp(sn, NUMBER1) != 0) { die("Failed converting number to string\n"); } free(sn); mpd_del(n); }
int main(int argc, char **argv) { mpd_context_t ctx; mpd_t *a, *b; mpd_t *q, *r; char *qs, *rs; char status_str[MPD_MAX_FLAG_STRING]; clock_t start_clock, end_clock; if (argc != 3) { fprintf(stderr, "divmod: usage: ./divmod x y\n"); exit(1); } mpd_init(&ctx, 38); ctx.traps = 0; q = mpd_new(&ctx); r = mpd_new(&ctx); a = mpd_new(&ctx); b = mpd_new(&ctx); mpd_set_string(a, argv[1], &ctx); mpd_set_string(b, argv[2], &ctx); start_clock = clock(); mpd_divmod(q, r, a, b, &ctx); end_clock = clock(); fprintf(stderr, "time: %f\n\n", (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); qs = mpd_to_sci(q, 1); rs = mpd_to_sci(r, 1); mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status); printf("%s %s %s\n", qs, rs, status_str); mpd_del(q); mpd_del(r); mpd_del(a); mpd_del(b); mpd_free(qs); mpd_free(rs); return 0; }
int main(){ mpd_context_t ctx; mpd_t *result1; mpd_t *result2; mpd_t *result3; mpd_setminalloc(MPD_MINALLOC_MAX); mpd_ieee_context(&ctx, 160); result1 = mpd_qnew(); result2 = mpd_qnew(); result3 = mpd_qnew(); //mpd_qset_u64(result1,2ULL,&ctx,&status); dec32_to_mpd(&ctx,result1,dec32); dec64_to_mpd(&ctx,result2,dec64); dec128_to_mpd(&ctx,result3,dec128); //mpd_qset_u64(result2,4ULL,&ctx,&status); //mpd_qpow(result3,result1,result2,&ctx,&status); mpd_print(result1); mpd_print(result2); mpd_print(result3); /*print_mpd(result1); print_mpd(result2); print_mpd(result3);*/ _Decimal32 ddd = mpd_to_dec32(result1); printf ("Compare is %d\n", memcmp(&ddd,&dec32,sizeof(_Decimal32))); printf ("0x%x\n0x%x\n", *((uint32_t *)(void *)&ddd), *((uint32_t *)(void *)&dec32)); _Decimal64 ddd64 = mpd_to_dec64(result2); printf ("Compare is %d\n", memcmp(&ddd64,&dec64,sizeof(_Decimal64))); printf ("0x%I64x\n0x%I64x\n", *((uint64_t *)(void *)&ddd64), *((uint64_t *)(void *)&dec64)); _Decimal128 ddd128 = mpd_to_dec128(result3); printf ("Compare is %d\n", memcmp(&ddd128,&dec128,sizeof(_Decimal128))); printf ("0x%I64d\n0x%I64x\n", *((uint64_t *)(void *)&ddd128), *((uint64_t *)(void *)&dec128)); mpd_del(result1); mpd_del(result2); mpd_del(result3); print_dec32(&dec32); print_dec64(&dec64); print_dec128(&dec128); return 0; }
static void dec_to_mpd_conv(mpd_context_t * ctx, mpd_t *result, const int64_t significand_low, const int64_t exponent_part){ uint32_t status = 0; mpd_t *ten, *exp_pow, *exp_partmpd, *significand_partmpd; ten = mpd_qnew(); exp_pow = mpd_qnew(); exp_partmpd = mpd_qnew(); significand_partmpd = mpd_qnew(); mpd_qset_i64(ten,10LL,ctx,&status); mpd_qset_i64(significand_partmpd,significand_low,ctx,&status); mpd_qset_i64(exp_partmpd,exponent_part,ctx,&status); mpd_qpow(exp_pow,ten,exp_partmpd,ctx,&status); mpd_qmul(result,significand_partmpd,exp_pow,ctx,&status); mpd_del(ten); mpd_del(exp_pow); mpd_del(exp_partmpd); mpd_del(significand_partmpd); }
int main(int argc, char **argv) { mpd_context_t ctx; mpd_t *a, *b; mpd_t *result; char *rstring; char status_str[MPD_MAX_FLAG_STRING]; clock_t start_clock, end_clock; if (argc != 3) { fprintf(stderr, "shift: usage: ./shift x y\n"); exit(1); } mpd_init(&ctx, 38); ctx.traps = 0; result = mpd_new(&ctx); a = mpd_new(&ctx); b = mpd_new(&ctx); mpd_set_string(a, argv[1], &ctx); mpd_set_string(b, argv[2], &ctx); start_clock = clock(); mpd_shift(result, a, b, &ctx); end_clock = clock(); fprintf(stderr, "time: %f\n\n", (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); rstring = mpd_to_sci(result, 1); mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status); printf("%s %s\n", rstring, status_str); mpd_del(a); mpd_del(b); mpd_del(result); mpd_free(rstring); return 0; }
/* * Example from: http://en.wikipedia.org/wiki/Mandelbrot_set * * Escape time algorithm for drawing the set: * * Point x0, y0 is deemed to be in the Mandelbrot set if the return * value is maxiter. Lower return values indicate how quickly points * escaped and can be used for coloring. */ int color_point(mpd_t *x0, mpd_t *y0, int maxiter, mpd_context_t *ctx) { mpd_t *x, *y, *sq_x, *sq_y; mpd_t *two, *four, *c; int i; x = mpd_new(ctx); y = mpd_new(ctx); mpd_set_u32(x, 0, ctx); mpd_set_u32(y, 0, ctx); sq_x = mpd_new(ctx); sq_y = mpd_new(ctx); mpd_set_u32(sq_x, 0, ctx); mpd_set_u32(sq_y, 0, ctx); two = mpd_new(ctx); four = mpd_new(ctx); mpd_set_u32(two, 2, ctx); mpd_set_u32(four, 4, ctx); c = mpd_new(ctx); mpd_set_u32(c, 0, ctx); for (i = 0; i < maxiter && mpd_cmp(c, four, ctx) <= 0; i++) { mpd_mul(y, x, y, ctx); mpd_mul(y, y, two, ctx); mpd_add(y, y, y0, ctx); mpd_sub(x, sq_x, sq_y, ctx); mpd_add(x, x, x0, ctx); mpd_mul(sq_x, x, x, ctx); mpd_mul(sq_y, y, y, ctx); mpd_add(c, sq_x, sq_y, ctx); } mpd_del(x); mpd_del(y); mpd_del(sq_x); mpd_del(sq_y); mpd_del(two); mpd_del(four); mpd_del(c); return i; }
int update_user_balance(bool real, uint32_t user_id, const char *asset, const char *business, uint64_t business_id, mpd_t *change, json_t *detail) { struct update_key key; key.user_id = user_id; strncpy(key.asset, asset, sizeof(key.asset)); strncpy(key.business, business, sizeof(key.business)); key.business_id = business_id; dict_entry *entry = dict_find(dict_update, &key); if (entry) { return -1; } mpd_t *result; mpd_t *abs_change = mpd_new(&mpd_ctx); mpd_abs(abs_change, change, &mpd_ctx); if (mpd_cmp(change, mpd_zero, &mpd_ctx) >= 0) { result = balance_add(user_id, BALANCE_TYPE_AVAILABLE, asset, abs_change); } else { result = balance_sub(user_id, BALANCE_TYPE_AVAILABLE, asset, abs_change); } mpd_del(abs_change); if (result == NULL) return -2; struct update_val val = { .create_time = current_timestamp() }; dict_add(dict_update, &key, &val); if (real) { double now = current_timestamp(); json_object_set_new(detail, "id", json_integer(business_id)); char *detail_str = json_dumps(detail, 0); append_user_balance_history(now, user_id, asset, business, change, detail_str); free(detail_str); push_balance_message(now, user_id, asset, business, change); } return 0; }
int main(int argc, char **argv) { mpd_context_t ctx; mpd_t *x0, *y0; mpd_t *sqrt_2, *xstep, *ystep; uint32_t prec = 19; int iter = 1000; int points[40][80]; int i, j; clock_t start_clock, end_clock; if (argc != 3) { fprintf(stderr, "usage: ./bench prec iter\n"); exit(1); } prec = strtoul(argv[1], NULL, 10); iter = strtol(argv[2], NULL, 10); mpd_init(&ctx, prec); /* no more MPD_MINALLOC changes after here */ sqrt_2 = mpd_new(&ctx); xstep = mpd_new(&ctx); ystep = mpd_new(&ctx); x0 = mpd_new(&ctx); y0 = mpd_new(&ctx); mpd_set_u32(sqrt_2, 2, &ctx); mpd_sqrt(sqrt_2, sqrt_2, &ctx); mpd_div_u32(xstep, sqrt_2, 40, &ctx); mpd_div_u32(ystep, sqrt_2, 20, &ctx); start_clock = clock(); mpd_copy(y0, sqrt_2, &ctx); for (i = 0; i < 40; i++) { mpd_copy(x0, sqrt_2, &ctx); mpd_set_negative(x0); for (j = 0; j < 80; j++) { points[i][j] = color_point(x0, y0, iter, &ctx); mpd_add(x0, x0, xstep, &ctx); } mpd_sub(y0, y0, ystep, &ctx); } end_clock = clock(); #ifdef BENCH_VERBOSE for (i = 0; i < 40; i++) { for (j = 0; j < 80; j++) { if (points[i][j] == iter) { putchar('*'); } else if (points[i][j] >= 10) { putchar('+'); } else if (points[i][j] >= 5) { putchar('.'); } else { putchar(' '); } } putchar('\n'); } putchar('\n'); #endif printf("time: %f\n\n", (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); mpd_del(x0); mpd_del(y0); mpd_del(sqrt_2); mpd_del(xstep); mpd_del(ystep); return 0; }
/* * Return the string representation of an mpd_t, formatted according to 'spec'. * The format specification is assumed to be valid. Memory errors are indicated * as usual. This function is quiet. */ char * mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status) { mpd_uint_t dt[MPD_MINALLOC_MAX]; mpd_t tmp = {MPD_STATIC|MPD_STATIC_DATA,0,0,0,MPD_MINALLOC_MAX,dt}; mpd_ssize_t dplace = MPD_DEFAULT_DOTPLACE; mpd_mbstr_t result; mpd_spec_t stackspec; char type = spec->type; int flags = 0; if (spec->min_width > MPD_MAX_PREC) { *status |= MPD_Invalid_operation; return NULL; } if (isupper((uchar)type)) { type = tolower((uchar)type); flags |= MPD_FMT_UPPER; } if (spec->sign == ' ') { flags |= MPD_FMT_SIGN_SPACE; } else if (spec->sign == '+') { flags |= MPD_FMT_SIGN_PLUS; } if (mpd_isspecial(dec)) { if (spec->align == 'z') { stackspec = *spec; stackspec.fill[0] = ' '; stackspec.fill[1] = '\0'; stackspec.align = '>'; spec = &stackspec; } } else { uint32_t workstatus = 0; mpd_ssize_t prec; switch (type) { case 'g': flags |= MPD_FMT_TOSCI; break; case 'e': flags |= MPD_FMT_EXP; break; case '%': flags |= MPD_FMT_PERCENT; if (!mpd_qcopy(&tmp, dec, status)) { return NULL; } tmp.exp += 2; dec = &tmp; type = 'f'; /* fall through */ case 'f': flags |= MPD_FMT_FIXED; break; default: abort(); /* debug: GCOV_NOT_REACHED */ } if (spec->prec >= 0) { if (spec->prec > MPD_MAX_PREC) { *status |= MPD_Invalid_operation; goto error; } switch (type) { case 'g': prec = (spec->prec == 0) ? 1 : spec->prec; if (dec->digits > prec) { _mpd_round(&tmp, dec, prec, ctx, &workstatus); dec = &tmp; } break; case 'e': if (mpd_iszero(dec)) { dplace = 1-spec->prec; } else { _mpd_round(&tmp, dec, spec->prec+1, ctx, &workstatus); dec = &tmp; } break; case 'f': mpd_qrescale(&tmp, dec, -spec->prec, ctx, &workstatus); dec = &tmp; break; } } if (type == 'f') { if (mpd_iszero(dec) && dec->exp > 0) { mpd_qrescale(&tmp, dec, 0, ctx, &workstatus); dec = &tmp; } } if (workstatus&MPD_Errors) { *status |= (workstatus&MPD_Errors); goto error; } } /* * At this point, for all scaled or non-scaled decimals: * 1) 1 <= digits <= MAX_PREC+1 * 2) adjexp(scaled) = adjexp(orig) [+1] * 3) case 'g': MIN_ETINY <= exp <= MAX_EMAX+1 * case 'e': MIN_ETINY-MAX_PREC <= exp <= MAX_EMAX+1 * case 'f': MIN_ETINY <= exp <= MAX_EMAX+1 * 4) max memory alloc in _mpd_to_string: * case 'g': MAX_PREC+36 * case 'e': MAX_PREC+36 * case 'f': 2*MPD_MAX_PREC+30 */ result.nbytes = _mpd_to_string(&result.data, dec, flags, dplace); result.nchars = result.nbytes; if (result.nbytes < 0) { *status |= MPD_Malloc_error; goto error; } if (*spec->dot != '\0' && !mpd_isspecial(dec)) { if (result.nchars > MPD_MAX_PREC+36) { /* Since a group length of one is not explicitly * disallowed, ensure that it is always possible to * insert a four byte separator after each digit. */ *status |= MPD_Invalid_operation; mpd_free(result.data); goto error; } if (!_mpd_apply_lconv(&result, spec, status)) { goto error; } } if (spec->min_width) { if (!_mpd_add_pad(&result, spec, status)) { goto error; } } mpd_del(&tmp); return result.data; error: mpd_del(&tmp); return NULL; }