X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fnumeric.cpp;h=df525d6025eaf4221cbcb3c2fda145068eede1f6;hp=9670c6b36e716eaebca1477ef53ef8f635580403;hb=5a8b8e3c4d882249db35b679ce3144a59a7012e8;hpb=c52e08efc11b598173ef0582ca836d43ecdfbe52 diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index 9670c6b3..df525d60 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -7,7 +7,7 @@ * of special functions or implement the interface to the bignum package. */ /* - * GiNaC Copyright (C) 1999-2005 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2006 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -73,7 +73,7 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(numeric, basic, ////////// /** default ctor. Numerically it initializes to an integer zero. */ -numeric::numeric() : basic(TINFO_numeric) +numeric::numeric() : basic(&numeric::tinfo_static) { value = cln::cl_I(0); setflag(status_flags::evaluated | status_flags::expanded); @@ -85,7 +85,7 @@ numeric::numeric() : basic(TINFO_numeric) // public -numeric::numeric(int i) : basic(TINFO_numeric) +numeric::numeric(int i) : basic(&numeric::tinfo_static) { // Not the whole int-range is available if we don't cast to long // first. This is due to the behaviour of the cl_I-ctor, which @@ -100,14 +100,14 @@ numeric::numeric(int i) : basic(TINFO_numeric) } -numeric::numeric(unsigned int i) : basic(TINFO_numeric) +numeric::numeric(unsigned int i) : basic(&numeric::tinfo_static) { // Not the whole uint-range is available if we don't cast to ulong // first. This is due to the behaviour of the cl_I-ctor, which // emphasizes efficiency. However, if the integer is small enough // we save space and dereferences by using an immediate type. // (C.f. ) - if (i < (1U << (cl_value_len-1))) + if (i < (1UL << (cl_value_len-1))) value = cln::cl_I(i); else value = cln::cl_I(static_cast(i)); @@ -115,14 +115,14 @@ numeric::numeric(unsigned int i) : basic(TINFO_numeric) } -numeric::numeric(long i) : basic(TINFO_numeric) +numeric::numeric(long i) : basic(&numeric::tinfo_static) { value = cln::cl_I(i); setflag(status_flags::evaluated | status_flags::expanded); } -numeric::numeric(unsigned long i) : basic(TINFO_numeric) +numeric::numeric(unsigned long i) : basic(&numeric::tinfo_static) { value = cln::cl_I(i); setflag(status_flags::evaluated | status_flags::expanded); @@ -132,7 +132,7 @@ numeric::numeric(unsigned long i) : basic(TINFO_numeric) /** Constructor for rational numerics a/b. * * @exception overflow_error (division by zero) */ -numeric::numeric(long numer, long denom) : basic(TINFO_numeric) +numeric::numeric(long numer, long denom) : basic(&numeric::tinfo_static) { if (!denom) throw std::overflow_error("division by zero"); @@ -141,7 +141,7 @@ numeric::numeric(long numer, long denom) : basic(TINFO_numeric) } -numeric::numeric(double d) : basic(TINFO_numeric) +numeric::numeric(double d) : basic(&numeric::tinfo_static) { // We really want to explicitly use the type cl_LF instead of the // more general cl_F, since that would give us a cl_DF only which @@ -153,7 +153,7 @@ numeric::numeric(double d) : basic(TINFO_numeric) /** ctor from C-style string. It also accepts complex numbers in GiNaC * notation like "2+5*I". */ -numeric::numeric(const char *s) : basic(TINFO_numeric) +numeric::numeric(const char *s) : basic(&numeric::tinfo_static) { cln::cl_N ctorval = 0; // parse complex numbers (functional but not completely safe, unfortunately @@ -232,7 +232,7 @@ numeric::numeric(const char *s) : basic(TINFO_numeric) /** Ctor from CLN types. This is for the initiated user or internal use * only. */ -numeric::numeric(const cln::cl_N &z) : basic(TINFO_numeric) +numeric::numeric(const cln::cl_N &z) : basic(&numeric::tinfo_static) { value = z; setflag(status_flags::evaluated | status_flags::expanded); @@ -624,7 +624,7 @@ ex numeric::coeff(const ex & s, int n) const * results: (2+I).has(-2) -> true. But this is consistent, since we also * would like to have (-2+I).has(2) -> true and we want to think about the * sign as a multiplicative factor. */ -bool numeric::has(const ex &other) const +bool numeric::has(const ex &other, unsigned options) const { if (!is_exactly_a(other)) return false; @@ -1708,20 +1708,20 @@ const numeric bernoulli(const numeric &nn) results.reserve(n/2); for (unsigned p=next_r; p<=n; p+=2) { cln::cl_I c = 1; // seed for binonmial coefficients - cln::cl_RA b = cln::cl_RA(1-p)/2; - const unsigned p3 = p+3; - const unsigned pm = p-2; - unsigned i, k, p_2; - // test if intermediate unsigned int can be represented by immediate - // objects by CLN (i.e. < 2^29 for 32 Bit machines, see ) + cln::cl_RA b = cln::cl_RA(p-1)/-2; + // The CLN manual says: "The conversion from `unsigned int' works only + // if the argument is < 2^29" (This is for 32 Bit machines. More + // generally, cl_value_len is the limiting exponent of 2. We must make + // sure that no intermediates are created which exceed this value. The + // largest intermediate is (p+3-2*k)*(p/2-k+1) <= (p^2+p)/2. if (p < (1UL<::const_iterator it = callbacklist.begin(), end = callbacklist.end(); + for (; it != end; ++it) { + (*it)(digitsdiff); + } + return *this; } @@ -2026,6 +2037,13 @@ void _numeric_digits::print(std::ostream &os) const } +/** Add a new callback function. */ +void _numeric_digits::add_callback(digits_changed_callback callback) +{ + callbacklist.push_back(callback); +} + + std::ostream& operator<<(std::ostream &os, const _numeric_digits &e) { e.print(os);