예제 #1
0
		std::string FractalTexture::gmpNumToString(type num, int base) {
			std::string s;
#ifdef ROE_FRACTAL_USE_GMP
			long exp;
#ifdef ROE_FRACTAL_GMP_USE_C
			s = mpf_get_str(nullptr, &exp, base, 0, num);
#else
			s = num.get_str(exp, base, 0);
#endif
			std::string sign = "";
			if(s.length() == 0) {s="00"; ++exp;}
			if(s[0] == '-') {sign = "-"; s = s.substr(1);}
			while (exp <= 0) {
				s = "0"+s;
				++exp;
			}
			while (exp >= (long)s.length()) {
				s += "0";
			}
			s.insert(exp, ".");//*/
			s = sign + s;
#else
			s = util::toString((double)num);
#endif
			return s;
		}
예제 #2
0
int sg_big_float_get_mantissa_and_exponent(sg_big_float_t *src, enum sg_num_sys sys, sg_vlstr_t * mantissa, size_t* exponent)
{
    int base = SG_COMPUTE_BASE(sys);
    if (!src || !mantissa || base <= 0)
        return -1;

    mp_exp_t exp;
    char* s = mpf_get_str(NULL, &exp, base, 0, src->mpf);
    sg_vlstrcpy(mantissa, s);
    *exponent = exp;
    free(s);
    return 0;
}
int
cycle (mpf_t x) {

   char s[10000];
   char srch[SSIZE+1];
   int i;
   mp_exp_t e;
   mpf_get_str (s, &e, 10, 10000, x);
   
   // copy a search string
   for (i=0; i<SSIZE; i++)
     srch[i] = s[i+SSIZE]; 
   srch[i]='\0';

  return grep(srch, s+SSIZE+1);
}
예제 #4
0
void set(std::string & dest, mpf_t const & x)
{
    char number[256];
    mp_exp_t exponent;
    mpf_get_str(number, &exponent, 10, 78, x);
    if (number[0] == '\0')
    {
        dest = "0e0";
    }
    else
    {
        std::ostringstream s;
        s << "." << number << "e" << exponent;
        dest = s.str();
    }
}
예제 #5
0
char* mpSum(float* input, size_t n){
    int i;
    char* resStr = (char*)malloc(1024);
    char* tmp = (char*)malloc(1024);
    mpf_t sum; mpf_init(sum);
    mpf_t in; mpf_init(in);
    for(i=0; i < n; i++){
        mpf_set_d(in, (float)input[i]);
        mpf_add(sum, sum, in);
    }
    mp_exp_t exp;
    mpf_get_str(tmp, &exp, 10, 1022, sum);
    strncpy(resStr, tmp, exp); resStr[exp]='.'; strcpy(resStr+exp+1, tmp+exp);
    
    free(tmp);
    return resStr;
}
static inline void numberToString_impl_conv(sptrObject obj, int radix, std::ostringstream& os){
    switch (obj->getType()){
        case ObjectDef::ObjectType::INT:{
            mpz_class x(static_cast<ObjectDef::Int*>(obj.get())->getVal());
            char* ret = mpz_get_str(0, radix, x.get_mpz_t());
            os << ret;
            free(ret);
        }
            break;
        case ObjectDef::ObjectType::BIGINT:{
            char* ret = mpz_get_str(0, radix, static_cast<ObjectDef::BigInt*>(obj.get())->getVal().get_mpz_t());
            os << ret;
            free(ret);
        }
            break;
        case ObjectDef::ObjectType::RATIONAL:{
            char* ret = mpq_get_str(0, radix, static_cast<ObjectDef::Rational*>(obj.get())->getVal().get_mpq_t());
            os << ret;
            free(ret);
        }
            break;
        case ObjectDef::ObjectType::REAL:{
            assert(radix == 10);
            mp_exp_t expt;
            char* ret = mpf_get_str(0, &expt, 10, 0, static_cast<ObjectDef::Real*>(obj.get())->getVal().get_mpf_t());
            if (ret[0] == '\0'){
                os << "0e0";
            }
            else {
                unsigned i = 0;
                if (ret[0] == '-' || ret[0] == '+') {
                    os << ret[0];
                    ++i;
                }
                os << ret[i];
                ++i;
                os << '.' << ret + i << 'e' << expt-1;
            }
            free(ret);
        }
            break;
        default:
            assert(false);  //should never be here
    }
}
예제 #7
0
파일: util.c 프로젝트: tyru/dentaku
void
digit2token(Token *tok, Digit *digit, size_t max_size, int base)
{
    mp_exp_t exp;
    mpf_get_str(tok->str, &exp, base, max_size, *digit);
    size_t unsigned_len;

    if (tok->str[0] == '+' || tok->str[0] == '-') {
        unsigned_len = strlen(&tok->str[1]);
    }
    else {
        unsigned_len = strlen(tok->str);
    }

    if (tok->str[0] == '\0') {
        // From gmplib document:
        // When digit is zero, an empty string is produced
        // and the exponent returned is 0.
        assert(max_size >= 2);
        strcpy(tok->str, "0");
    }
    else if ((size_t)exp > unsigned_len) {
        // Add zeroes of exp to tail of string.
        for (; unsigned_len < exp; unsigned_len++) {
            tok->str[unsigned_len] = '0';
        }
        tok->str[exp] = '\0';
    }
    else if ((size_t)exp < unsigned_len) {
        // Insert '.' to head/middle of string.
        char *lower = ALLOCA(&tok->str[unsigned_len] - &tok->str[exp] + 1);
        strcpy(lower, &tok->str[exp]);
        if (exp == 0) {
            tok->str[exp] = '0';
            exp++;
        }
        tok->str[exp] = '.';
        tok->str[exp + 1] = '\0';
        strcpy(&tok->str[exp + 1], lower);
    }
}
예제 #8
0
int sg_big_float_get_str(sg_big_float_t *src, enum sg_num_sys sys, sg_vlstr_t * str)
{
    int base = SG_COMPUTE_BASE(sys);
    if (!src || !str || base <= 0)
        return -1;

    mp_exp_t exp;
    char* s = mpf_get_str(NULL, &exp, base, 0, src->mpf);
    sg_vlstrcpy(str, s);
    if (exp != 0) {
        long mantissa_length = strlen(s);
        /* rid negative symbol */
        if (mpf_sgn(src->mpf) == -1)
            --mantissa_length;
        sg_vlstr_t* float_exp = sg_vlstrfmt("e%ld", exp - mantissa_length);
        sg_vlstrcat(str, sg_vlstrraw(float_exp));
        sg_vlstrfree(&float_exp);
    }
    free(s);
    return 0;
}
예제 #9
0
vanilla::object::ptr vanilla::float_object::to_string() const
{
    mp_exp_t exp;
    char* str = mpf_get_str(nullptr, &exp, 10, 0, _v.mpf());
    std::unique_ptr<char, void (*)(char*)> tmp(str, [](char* ptr) { std::free(ptr); } );
    
    if(exp > 0)
    {
        std::string result(str, str + exp);
        result += '.';
        for(char* s = str + exp; *s; ++s)
            result += *s;
        return allocate_object<string_object>(std::move(result));
    }
    else
    {
       std::string result("0.");
       for(mp_exp_t i = 0; i < exp; ++i)
           result += '0';
       result.append(str);
       return allocate_object<string_object>(std::move(result));
    }
}
예제 #10
0
파일: Common.cpp 프로젝트: hyln9/nV
void Real::print(wostream& o) const {
    long exp;
    const size_t n_digits = static_cast<size_t>(LOG_10_2 * prec + 0.5);
    const size_t req_size = n_digits + 2;
    char* buf = new char[req_size];
    const char* const buf2 = mpf_get_str(buf, &exp, 10, n_digits, mpf);
    wstring t(buf2, buf2 + strlen(buf2));
    delete buf;
    wcs s = t.c_str();
    if (exp > 0) {
        if (s[0] == _W('-')) {
            if (exp + 1 <= static_cast<long>(t.size())) {
                o.write(s, exp + 1);
                o << _W('.') << s + exp + 1;
            } else {
                o << s;
                o << wstring(exp + 1 - t.size(), _W('0'));
                o << _W('.');
            }
        } else {
            if (exp <= static_cast<long>(t.size())) {
                o.write(s, exp);
                o << _W('.') << s + exp;
            } else {
                o << s;
                o << wstring(exp - t.size(), _W('0'));
                o << _W('.');
            }
        }
    } else {
        if (s[0] == _W('-'))
            o << _W("-0.") << wstring(-exp, _W('0')) << s + 1;
        else
            o << _W("0.") << wstring(-exp, _W('0')) << s;
    }
}
예제 #11
0
파일: pi-calc.c 프로젝트: grzpra/pi-calc
int chudnovsky(int digits, int threads)
{
	int res = 0;
	unsigned long int i, iter, precision, rest, per_cpu, k;
	mpf_t ltf, sum, result;
	pthread_t *pthreads;
	struct thread_args targs;
        mp_exp_t exponent;
        char *pi;

	/* If threads is not specified, check how many CPUs are avail */
	if (threads == 0) {
		threads = get_cpu_count();
	}

	pthreads = malloc(threads * sizeof(pthread_t));
	if (pthreads == NULL) {
		res = -ENOMEM;
		goto chudnovsky_exit;
	}

	/* Calculate and set precision */
	precision = (digits * BPD) + 1;
	mpf_set_default_prec(precision);

	/* Calculate number of iterations */
	iter = digits/DPI + 1;

	/* Init all objects */
	mpf_inits(ltf, sum, result, targs.sum, NULL);
	mpf_set_ui(sum, 0);
	mpf_set_ui(targs.sum, 0);

	/* Set pthread specific stuff */
	targs.k = 0;
	targs.iter = iter;
	pthread_mutex_init(&targs.start_mutex, NULL);
	pthread_mutex_init(&targs.sum_mutex, NULL);

	/* Prepare the constant from the left side of the equation */
	mpf_sqrt_ui(ltf, LTFCON1);
	mpf_mul_ui(ltf, ltf, LTFCON2);

	printf("Starting summing, using:\n"
		"%d digits - %lu iterations - %d threads\n",
		digits, iter, threads);

	for (i = 0; i < threads; i++) {
		pthread_create(&pthreads[i], NULL, &chudnovsky_chunk, (void *) &targs);
	}

	/* Wait for threads to finish and take their sums */
	for (i = 0; i < threads; i++) {
		pthread_join(pthreads[i], NULL);
	}

	printf("Starting final steps\n");

	/* Invert sum */
	mpf_ui_div(sum, 1, targs.sum);
	mpf_mul(result, sum, ltf);

	/* Get one more char then needed and then trunc to avoid rounding */
	pi = mpf_get_str(NULL, &exponent, 10, digits + 2, result);
	pi[digits+1] = '\0';

	if (strlen(pi) < LAST_DIGITS_PRINT + 1) {
		printf("Calculated PI:\n");
		printf("\t%.*s.%s\n", (int)exponent, pi, pi + exponent);
	} else {
		printf("Last digits of Pi are:\n");
		printf("\t%s\n", pi+(digits-(LAST_DIGITS_PRINT-1)));
	}

	free(pi);

	mpf_clears(ltf, sum, result, NULL);
	pthread_mutex_destroy(&targs.start_mutex);
	pthread_mutex_destroy(&targs.sum_mutex);

	/* TODO: add verification here! */

chudnovsky_free_pthreads:
	free(pthreads);
chudnovsky_exit:
	return res;
}
예제 #12
0
int segment_intersection_2d_test(double ax1, double ay1, double ax2,
				 double ay2, double bx1, double by1,
				 double bx2, double by2, double *x1,
				 double *y1, double *x2, double *y2)
{
    double t;

    double max_ax, min_ax, max_ay, min_ay;

    double max_bx, min_bx, max_by, min_by;

    int sgn_d, sgn_da, sgn_db;

    int vertical;

    int f11, f12, f21, f22;

    mp_exp_t exp;

    char *s;

    double d, da, db, ra, rb;

    if (!initialized)
	initialize_mpf_vars();

    /* TODO: Works for points ? */
    G_debug(3, "segment_intersection_2d_test()");
    G_debug(3, "    ax1  = %.18e, ay1  = %.18e", ax1, ay1);
    G_debug(3, "    ax2  = %.18e, ay2  = %.18e", ax2, ay2);
    G_debug(3, "    bx1  = %.18e, by1  = %.18e", bx1, by1);
    G_debug(3, "    bx2  = %.18e, by2  = %.18e", bx2, by2);

    f11 = ((ax1 == bx1) && (ay1 == by1));
    f12 = ((ax1 == bx2) && (ay1 == by2));
    f21 = ((ax2 == bx1) && (ay2 == by1));
    f22 = ((ax2 == bx2) && (ay2 == by2));

    /* Check for identical segments */
    if ((f11 && f22) || (f12 && f21)) {
	G_debug(4, "    identical segments");
	*x1 = ax1;
	*y1 = ay1;
	*x2 = ax2;
	*y2 = ay2;
	return 5;
    }
    /* Check for identical endpoints */
    if (f11 || f12) {
	G_debug(4, "    connected by endpoints");
	*x1 = ax1;
	*y1 = ay1;
	return 1;
    }
    if (f21 || f22) {
	G_debug(4, "    connected by endpoints");
	*x1 = ax2;
	*y1 = ay2;
	return 1;
    }

    if ((MAX(ax1, ax2) < MIN(bx1, bx2)) || (MAX(bx1, bx2) < MIN(ax1, ax2))) {
	G_debug(4, "    no intersection (disjoint bounding boxes)");
	return 0;
    }
    if ((MAX(ay1, ay2) < MIN(by1, by2)) || (MAX(by1, by2) < MIN(ay1, ay2))) {
	G_debug(4, "    no intersection (disjoint bounding boxes)");
	return 0;
    }

    d = (ax2 - ax1) * (by1 - by2) - (ay2 - ay1) * (bx1 - bx2);
    da = (bx1 - ax1) * (by1 - by2) - (by1 - ay1) * (bx1 - bx2);
    db = (ax2 - ax1) * (by1 - ay1) - (ay2 - ay1) * (bx1 - ax1);

    det22(dd, ax2, ax1, bx1, bx2, ay2, ay1, by1, by2);
    sgn_d = mpf_sgn(dd);
    s = mpf_get_str(NULL, &exp, 10, 40, dd);
    G_debug(3, "    dd = %sE%d", (s[0] == 0) ? "0" : s, exp);
    G_debug(3, "    d = %.18E", d);

    if (sgn_d != 0) {
	G_debug(3, "    general position");

	det22(dda, bx1, ax1, bx1, bx2, by1, ay1, by1, by2);
	det22(ddb, ax2, ax1, bx1, ax1, ay2, ay1, by1, ay1);
	sgn_da = mpf_sgn(dda);
	sgn_db = mpf_sgn(ddb);

	ra = da / d;
	rb = db / d;
	mpf_div(rra, dda, dd);
	mpf_div(rrb, ddb, dd);

	s = mpf_get_str(NULL, &exp, 10, 40, rra);
	G_debug(4, "        rra = %sE%d", (s[0] == 0) ? "0" : s, exp);
	G_debug(4, "        ra = %.18E", ra);
	s = mpf_get_str(NULL, &exp, 10, 40, rrb);
	G_debug(4, "        rrb = %sE%d", (s[0] == 0) ? "0" : s, exp);
	G_debug(4, "        rb = %.18E", rb);

	if (sgn_d > 0) {
	    if ((sgn_da < 0) || (mpf_cmp(dda, dd) > 0)) {
		G_debug(DLEVEL, "        no intersection");
		return 0;
	    }

	    if ((sgn_db < 0) || (mpf_cmp(ddb, dd) > 0)) {
		G_debug(DLEVEL, "        no intersection");
		return 0;
	    }
	}
	else {			/* if sgn_d < 0 */
	    if ((sgn_da > 0) || (mpf_cmp(dda, dd) < 0)) {
		G_debug(DLEVEL, "        no intersection");
		return 0;
	    }

	    if ((sgn_db > 0) || (mpf_cmp(ddb, dd) < 0)) {
		G_debug(DLEVEL, "        no intersection");
		return 0;
	    }
	}

	mpf_set_d(delta, ax2 - ax1);
	mpf_mul(t1, dda, delta);
	mpf_div(t2, t1, dd);
	*x1 = ax1 + mpf_get_d(t2);

	mpf_set_d(delta, ay2 - ay1);
	mpf_mul(t1, dda, delta);
	mpf_div(t2, t1, dd);
	*y1 = ay1 + mpf_get_d(t2);

	G_debug(2, "        intersection at:");
	G_debug(2, "            xx = %.18e", *x1);
	G_debug(2, "             x = %.18e", ax1 + ra * (ax2 - ax1));
	G_debug(2, "            yy = %.18e", *y1);
	G_debug(2, "             y = %.18e", ay1 + ra * (ay2 - ay1));
	return 1;
    }

    G_debug(3, "    parallel/collinear...");
    return -1;
}
예제 #13
0
size_t
mpf_out_str (FILE *stream, int base, size_t n_digits, mpf_srcptr op)
{
    char *str;
    mp_exp_t exp;
    size_t written;
    TMP_DECL;

    TMP_MARK;

    if (base == 0)
        base = 10;
    if (n_digits == 0)
        MPF_SIGNIFICANT_DIGITS (n_digits, base, op->_mp_prec);

    if (stream == 0)
        stream = stdout;

    /* Consider these changes:
       * Don't allocate memory here for huge n_digits; pass NULL to mpf_get_str.
       * Make mpf_get_str allocate extra space when passed NULL, to avoid
         allocating two huge string buffers.
       * Implement more/other allocation reductions tricks.  */

    str = (char *) TMP_ALLOC (n_digits + 2); /* extra for minus sign and \0 */

    mpf_get_str (str, &exp, base, n_digits, op);
    n_digits = strlen (str);

    written = 0;

    /* Write sign */
    if (str[0] == '-')
    {
        str++;
        fputc ('-', stream);
        written = 1;
        n_digits--;
    }

    {
        const char  *point = GMP_DECIMAL_POINT;
        size_t      pointlen = strlen (point);
        putc ('0', stream);
        fwrite (point, 1, pointlen, stream);
        written += pointlen + 1;
    }

    /* Write mantissa */
    {
        size_t fwret;
        fwret = fwrite (str, 1, n_digits, stream);
        written += fwret;
    }

    /* Write exponent */
    {
        int fpret;
        fpret = fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), exp);
        written += fpret;
    }

    TMP_FREE;
    return ferror (stream) ? 0 : written;
}
예제 #14
0
bool bbp_pi(bool const & abortTask,
            std::string const & digitIndex,
            uint32_t const digitStep,
            std::string & piSequence)
{
    unsigned long const mantissa_bits = 132;
    unsigned long const count_offset = 7;
    // settings above gives 32 hexadecimal digits
    unsigned long count = static_cast<unsigned long>(
        floor(log10(pow(2.0, static_cast<double>(mantissa_bits)))));
    count -= count_offset;

    // starting digit
    mpz_t digit;
    mpz_init(digit);
    if (mpz_set_str(digit, digitIndex.c_str(), 10) < 0)
        return false;
    mpz_sub_ui(digit, digit, 1); // subtract the 3 digit
    mpz_add_ui(digit, digit, digitStep);
    
    mpz_t tmpI[TEMPORARY_INTEGERS];
    for (size_t i = 0; i < (sizeof(tmpI) / sizeof(mpz_t)); ++i)
        mpz_init(tmpI[i]);
    mpf_t tmpF[TEMPORARY_FLOATS];
    for (size_t i = 0; i < (sizeof(tmpF) / sizeof(mpf_t)); ++i)
        mpf_init2(tmpF[i], mantissa_bits);
    
    // determine epsilon based on the number of digits required
    mpf_t epsilon;
    mpf_init2(epsilon, mantissa_bits);
    mpf_set_ui(epsilon, 10);
    mpf_pow_ui(epsilon, epsilon, count + count_offset);
    mpf_ui_div(epsilon, 1, epsilon);

    // integer constant
    mpz_t sixteen;
    mpz_init(sixteen);
    mpz_set_ui(sixteen, 16);

    // determine the series
    mpf_t s1, s2, s3, s4;
    mpf_init2(s1, mantissa_bits);
    mpf_init2(s2, mantissa_bits);
    mpf_init2(s3, mantissa_bits);
    mpf_init2(s4, mantissa_bits);
    series(abortTask, s1, 1, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;
    series(abortTask, s2, 4, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;
    series(abortTask, s3, 5, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;
    series(abortTask, s4, 6, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;

    // pid = 4. * s1 - 2. * s2 - s3 - s4;
    mpf_mul_ui(s1, s1, 4);
    mpf_mul_ui(s2, s2, 2);
    mpf_t result;
    mpf_init2(result, mantissa_bits);
    mpf_sub(result, s1, s2);
    mpf_sub(result, result, s3);
    mpf_sub(result, result, s4);

    // pid = pid - (int) pid + 1.;
    mpf_t & tmp1 = tmpF[0];
    mpf_floor(tmp1, result);
    mpf_sub(result, result, tmp1);
    mpf_add_ui(result, result, 1);
    mpf_abs(result, result);

    // output the result
    char resultStr[256];
    mp_exp_t exponent;
    mpf_get_str(resultStr, &exponent, 16, 254, result);
    resultStr[count + 1] = '\0'; // cut off any erroneous bits
    piSequence.assign(&resultStr[1]);

    // cleanup
    for (size_t i = 0; i < (sizeof(tmpI) / sizeof(mpz_t)); ++i)
        mpz_clear(tmpI[i]);
    for (size_t i = 0; i < (sizeof(tmpF) / sizeof(mpf_t)); ++i)
        mpf_clear(tmpF[i]);
    mpz_clear(digit);
    mpf_clear(epsilon);
    mpz_clear(sixteen);
    mpf_clear(s1);
    mpf_clear(s2);
    mpf_clear(s3);
    mpf_clear(s4);
    mpf_clear(result);
    return true;
}
예제 #15
0
파일: out_str.c 프로젝트: mahdiz/mpclib
size_t
mpf_out_str (FILE *stream, int base, size_t n_digits, mpf_srcptr op)
{
    char *str;
    mp_exp_t exp;
    size_t written;
    TMP_DECL (marker);

    TMP_MARK (marker);

    if (base == 0)
        base = 10;
    if (n_digits == 0)
        MPF_SIGNIFICANT_DIGITS (n_digits, base, op->_mp_prec);

    if (stream == 0)
        stream = stdout;

    str = (char *) TMP_ALLOC (n_digits + 2); /* extra for minus sign and \0 */

    mpf_get_str (str, &exp, base, n_digits, op);
    n_digits = strlen (str);

    written = 0;

    /* Write sign */
    if (str[0] == '-')
    {
        str++;
        fputc ('-', stream);
        written = 1;
        n_digits--;
    }

#if HAVE_LOCALECONV
    {
        const char  *point = localeconv()->decimal_point;
        size_t      pointlen = strlen (point);
        putc ('0', stream);
        fwrite (point, 1, pointlen, stream);
        written += pointlen + 1;
    }
#else
    fwrite ("0.", 1, 2, stream);
    written += 2;
#endif

    /* Write mantissa */
    {
        size_t fwret;
        fwret = fwrite (str, 1, n_digits, stream);
        written += fwret;
    }

    /* Write exponent */
    {
        int fpret;
        fpret = fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), exp);
        written += fpret;
    }

    TMP_FREE (marker);
    return ferror (stream) ? 0 : written;
}
예제 #16
0
int
main (int argc, char **argv)
{
    mpf_t x, y;
    int reps = 20000;
    int i;
    mp_size_t bprec = 100;
    mpf_t d, rerr, max_rerr, limit_rerr;
    char *str;
    mp_exp_t bexp;
    long size, exp;
    int base;
    char buf[SIZE * GMP_LIMB_BITS + 5];

    tests_start ();

    if (argc > 1)
    {
        reps = strtol (argv[1], 0, 0);
        if (argc > 2)
            bprec = strtol (argv[2], 0, 0);
    }

    mpf_set_default_prec (bprec);

    mpf_init_set_ui (limit_rerr, 1);
    mpf_div_2exp (limit_rerr, limit_rerr, bprec);
#if VERBOSE
    mpf_dump (limit_rerr);
#endif
    mpf_init (rerr);
    mpf_init_set_ui (max_rerr, 0);

    mpf_init (x);
    mpf_init (y);
    mpf_init (d);

    /* First test some specific values.  */

    mpf_set_str (y, "1.23456e1000", 0);

    mpf_set_str (x, "1.23456e1000", 10);
    if (mpf_cmp (x, y) != 0)
        abort ();
    mpf_set_str (x, "1.23456e+1000", 0);
    if (mpf_cmp (x, y) != 0)
        abort ();
    mpf_set_str (x, "1.23456e+1000", 10);
    if (mpf_cmp (x, y) != 0)
        abort ();

    /* Now test random values.  */

    for (i = 0; i < reps; i++)
    {
        if (i == 0)
        {
            /* exercise the special case in get_str for for x==0 */
            mpf_set_ui (x, 0L);
            base = 10;
        }
        else
        {
            size = urandom () % (2 * SIZE) - SIZE;
            exp = urandom () % EXPO;
            mpf_random2 (x, size, exp);
            base = urandom () % 61 + 2;
        }

        str = mpf_get_str (0, &bexp, base, 0, x);

        if (str[0] == '-')
            sprintf (buf, "-0.%s@%ld", str + 1, bexp);
        else
            sprintf (buf, "0.%s@%ld", str, bexp);

        mpf_set_str_or_abort (y, buf, -base);
        (*__gmp_free_func) (str, strlen (str) + 1);

        mpf_reldiff (rerr, x, y);
        if (mpf_cmp (rerr, max_rerr) > 0)
        {
            mpf_set (max_rerr, rerr);
#if VERBOSE
            mpf_dump (max_rerr);
#endif
            if (mpf_cmp (rerr, limit_rerr) > 0)
            {
                printf ("ERROR after %d tests\n", i);
                printf ("base = %d\n", base);
                printf ("   x = ");
                mpf_dump (x);
                printf ("   y = ");
                mpf_dump (y);
                abort ();
            }
        }
    }

    mpf_clear (limit_rerr);
    mpf_clear (rerr);
    mpf_clear (max_rerr);

    mpf_clear (x);
    mpf_clear (y);
    mpf_clear (d);

    tests_end ();
    exit (0);
}
예제 #17
0
/*  Command line arguments are three char[]s of digits:
 *    integer   (binary digits)
 *    exponent  (decimal value)
 *    fraction  (binary digits)
 *  Outputs are normalized decimal and binary representations
 *  of the input value, one part per line:
 *    decimal integer
 *    decimal fraction
 *    decimal exponent
 *    decimal recurrence digits
 *    decimal recurrence start position
 *    binary recurrence digits
 *    binary recurrence start
 *    binary integer
 *    binary fraction
 *    binary exponent
*/
int main(int argc, char* argv[]) {
    if (argc != 4) {
        puts("Need arguments!");
        exit(1);
    }

    //const int BINARY_PRECISION = 128;
    int       decimal_exponent;
    int       binary_exponent_v;
    char*    binary_integer_v = malloc(BUF);
    char*    binary_fraction_v = malloc(BUF);
    char*    decimal_fraction = malloc(BUF);
    char*    decimal_integer = malloc(BUF);
    int       decimal_recurrence_start = -1;
    int       binary_recurrence_start = -1;
    char*    decimal_recurrence = malloc(BUF);
    strcpy(decimal_recurrence, "0");
    char*    binary_recurrence = malloc(BUF);
    strcpy(binary_recurrence, "0");
    char*    temp = malloc(BUF);
    //int       precision_so_far = 0;

    strcpy(binary_integer_v, argv[1]);
    binary_exponent_v = atoi(argv[2]);
    strcpy(binary_fraction_v, argv[3]);
//printf("bfv %s\n", binary_fraction_v);

    mpz_t result;
    mpz_init(result);

    //char* binfractemp = binary_fraction_v;

    // The n versions of the variable are the ones that are normalized and used
    // for the binary ouput but are not used for generating the decimal values
    char* binary_integer_n = malloc(BUF);
    strcpy(binary_integer_n, binary_integer_v);
    char* binary_fraction_n = malloc(BUF);
    strcpy(binary_fraction_n, binary_fraction_v);
    int binary_exponent_n = binary_exponent_v;

    while(atoi(binary_integer_n) > 1) {
        temp[0] = binary_integer_n[strlen(binary_integer_n)-1];
        temp[1] = '\0';
//      strcpy(temp,&(binary_integer_n[strlen(binary_integer_n)-1]));
        strcpy(binary_fraction_n, strcat(temp, binary_fraction_n));
        //strcpy(binary_integer_n, substr(binary_integer_n,0, strlen(binary_integer_n) - 1));
        binary_integer_n[strlen(binary_integer_n)-1] = '\0';
        binary_exponent_n++;
    }

    while (strcmp(binary_integer_n,"0") == 0) {
        binary_integer_n[0] = binary_fraction_n[0];
        binary_integer_n[1] = '\0';
//	strcpy(binary_integer_n, binary_fraction_n);
//      strcpy(binary_fraction_n,  substr(binary_fraction_n,1,strlen(binary_fraction_n)-1));
        substr1(binary_fraction_n);
        binary_exponent_n--;
    }

    if (binary_fraction_n[0] == '\0') {
        strcpy(binary_fraction_n, "0");
    }
    //printf("bi %s\n",binary_integer_v);

    //these are copies of the originals
    char* binary_integer = malloc(BUF);
    strcpy(binary_integer, binary_integer_v);
    char* binary_fraction = malloc(BUF);
    strcpy(binary_fraction, binary_fraction_v);
    int binary_exponent     = binary_exponent_v;

    //printf("bi %s\n",binary_integer);
    while (binary_exponent > 0) {
        int a = strlen(binary_integer);

        binary_integer[a] = binary_fraction[0];
        binary_integer[a+1] = '\0';
        //strcpy(binary_fraction, substr(binary_fraction,1,strlen(binary_fraction-1)));
        substr1(binary_fraction);
        if (binary_fraction[0] == '\0') {
            strcpy(binary_fraction, "0");
        }
        binary_exponent--;
    }
    ////printf("space needed: %d\n", (int) binary_fraction - (int) binary_fraction_backing);


    //printf("bi %s\n",binary_integer);

    while (binary_exponent < 0) {
        //strcpy(temp, &(binary_integer[strlen(binary_integer) - 1]));
        temp[0] = binary_integer[strlen(binary_integer) - 1];
        temp[1] = '\0';
        strcpy(binary_fraction, strcat(temp, binary_fraction));
        //strcpy(binary_integer, substr(binary_integer,0, strlen(binary_integer) - 1));
        binary_integer[strlen(binary_integer)-1] = '\0';
        if (binary_integer[0] == '\0') {
            strcpy(binary_integer, "0");
        }
        binary_exponent++;
    }

    //  Decimal integer part
    strcpy(decimal_integer, "0");

    mpz_t power_of_two;
    mpz_init(power_of_two);
    mpz_set_ui(power_of_two, 1);

    mpz_t di;
    mpz_init(di);
    mpz_set_ui(di, 0);

    //printf("bin int len: %s\n", binary_integer);
    //int aa = 0, b = 0;
    for (int i = strlen(binary_integer) - 1; i > -1; i--) {
        //  if it's a 1 you add the decimal integer to the power of two (power of
        //  two starts at 1)
        if (binary_integer[i] == '1') {
            mpz_add(di, di, power_of_two);
            //printf("di %s\n", mpz_get_str(NULL,10,power_of_two));
            //aa++;
        }
        mpz_add(power_of_two, power_of_two, power_of_two); //double the power_of_two
        //printf("power_of_two b=%d %s\n", b, mpz_get_str(NULL,10,power_of_two));
        //b++;
    }
    //printf("aa = %d\nb = %d\n",aa,b);

    //  Decimal fraction part
    //  reset the power_of_two back to 1
    mpz_set_ui(power_of_two, 1);

    mpz_t df;
    mpz_init(df);
    mpz_set_ui(df, 0);

    strcpy(decimal_fraction, "0");

    //printf("binary_fraction pre-add: %s\n", binary_fraction);
    int j = 0, k = 0;
    for (int i = strlen(binary_fraction) - 1; i > -1; i--) {
        //  if it is 1 add the decimal fraction to the power of two
        if (binary_fraction[i] == '1') {
            j++;
            mpz_add(df, df, power_of_two);
        }
        mpz_add(power_of_two, power_of_two, power_of_two); //double the power_of_two
        k++;
    }
    //printf("j = %d\nk = %d\n",j,k);

    //printf("df %s\n", mpz_get_str(NULL, 10, df));
    //printf("powtwo %s\n", mpz_get_str(NULL, 10, power_of_two));

    mpf_set_default_prec(1000);
    mpf_t decf;
    mpf_init(decf);
    mpf_set_z(decf, df);
    //int n = 10;

    mpf_t powtwo;
    mpf_init(powtwo);
    mpf_set_z(powtwo, power_of_two);

    mpf_div(decf, decf, powtwo);


    //  Normalize
    decimal_exponent = 0;

    char* ditemp = malloc(BUF);
    char* dftemp = malloc(BUF);

    mpz_get_str(ditemp, 10, di);
    //printf("ditemp %s\n", ditemp);
    strcpy(decimal_integer, ditemp);

    mp_exp_t a;

    mpf_get_str(dftemp, &a, 10, 10000, decf);
    strcpy(decimal_fraction, dftemp);

    /*
        while( a <0)
        {
          strcpy(decimal_fraction, strcat("0", decimal_fraction));
          a++;
        }
    */
    prepend(decimal_fraction, repeat_char('0', abs(a)));


    while (strlen(decimal_integer)>1) {
        temp[0] = decimal_integer[strlen(decimal_integer)-1];
        temp[1] = '\0';
        //strcpy(temp, &(decimal_integer[strlen(decimal_integer)-1]));
        strcpy(decimal_fraction, strcat(temp, decimal_fraction));
        //strcpy(decimal_integer, substr(decimal_integer,0, strlen(decimal_integer) - 1));
        decimal_integer[strlen(decimal_integer)-1] = '\0';
        decimal_exponent++;
    }

    while (strcmp(decimal_integer, "0") == 0) {
        decimal_integer[0] = decimal_fraction[0];
        decimal_integer[1] = '\0';
        //strcpy(decimal_integer, decimal_fraction);
        //strcpy(decimal_fraction, substr(decimal_fraction,1,strlen(decimal_fraction)-1));
        substr1(decimal_fraction);
        decimal_exponent--;
    }

    if (decimal_integer[0] == '\0') {
        strcpy(decimal_integer, "0");
    }

    if (decimal_fraction[0] == '\0') {
        strcpy(decimal_fraction, "0");
    }

    char* tempDI = malloc(BUF);
    strcpy( tempDI, decimal_integer);
    while (tempDI[0] == '0') {
        //strcpy(tempDI, substr(tempDI,1,strlen(tempDI)-1));
        substr1(tempDI);
    }
    if (tempDI[0] == '\0') strcpy(tempDI, "0");

    strcpy(decimal_integer, tempDI);

    printf("%s\n", decimal_integer);
    printf("%s\n", decimal_fraction);
    printf("%d\n", decimal_exponent);
    printf("%s\n", decimal_recurrence);
    printf("%d\n", decimal_recurrence_start);
    printf("%s\n", binary_recurrence);
    printf("%d\n", binary_recurrence_start);
    // These bottom three are the normalized binary values that also have to be
    // returned to the Javascript
    printf("%s\n", binary_integer_n);
    printf("%s\n", binary_fraction_n);
    printf("%d\n", binary_exponent_n);

    mpf_clear(decf);
    mpf_clear(powtwo);
    mpz_clear(result);
    mpz_clear(di);
    mpz_clear(df);

    free(binary_integer_n);
    free(binary_fraction_n);
    free(binary_integer_v);
    free(binary_fraction_v);
    free(binary_integer);
    free(binary_fraction);
    free(binary_recurrence);
    free(decimal_recurrence);
    free(decimal_integer);
    free(decimal_fraction);
    free(tempDI);
    free(ditemp);
    free(dftemp);
    free(temp);

    return 0;
}