Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing GMP to calculate very large Integers from formulas
    primarykey
    data
    text
    <p>I was having a hard time to figure out how to deal with a problem I encountered. As a part of a complex formula, I need to calculate a part that quickly overflows double, i.e. results get up to ~ 1.59*10^(1331) (calculated with mathematica). Of course this is out of the range of double. Then I was thinking of using long double, which on my linux system with <code>gcc 4.6.3</code> is 16byte. </p> <p>1) double precision (8byte) has a possible range of up to 10^(308). Am I right in saying, that long double then increases the actual precision, but not the possible numeric range of values? I remember that I heard that it can be either or, depending on the system and the compiler. Is that true ? At least I still get NaN when I try to calculate my values with long double. </p> <p>2.) I was then looking for a way to actually calculate these results and I found the GNU <code>gmp</code>. I heard that you can represent very large integers and I thought this might help. However, reading the documentation, it seems that with </p> <pre><code> mpz_t x; mpz_init(x); mpz_set_*(x,#); </code></pre> <p>I can assign values to <code>gmp</code> integer data types, but in order to do that, I can "only" choose to assign values that can be represented by built-in data types like double or (u/s)int etc. All I found for how to assign really huge numbers was to use <code>mpz_set_str()</code> to assign the number from a string. How would I assign a number that is the result of a complex calculation ? Simply speaking, formulas look like this: </p> <pre><code>long double res1,res2=0.0; int a,b; a=780; b=741; float d,d1,o,s; // can be values in [0.01,100] res1=(2*(pow(b,2)*pow(E,b*(o + s))*(pow(d1,2) + pow(E,a*s)*(-1 + pow(E,a*o)) + pow(d,2)*(-1 + pow(E,a*s))) + pow(a,2)*pow(E,a*(o + s))*(pow(E,b*s)*(pow(E,b*o) + (-1 + d)*(1 + d + b*o)) + (-d + d1)*(d + d1 + b*o + b*d*s)) - a*b*(pow(d1,2)*(pow(E,a*(o + s)) + pow(E,b*(o + s))) + pow(E,a*o + (a + b)*s)*(-2 + 2*pow(E,b*o) - b*o) + d1*pow(E,a*s)*(-pow(E,b*o) + pow(E,a*o)*(1 + b*o)) + pow(d,2)*pow(E,a*s)*(-pow(E,b*o) + pow(E,b*(o + s)) + pow(E,a*o)*(-1 + pow(E,b*s) - b*s)) + d*(-(d1*pow(E,b*(o + s))) + (1 + d1)*pow(E,b*o + a*s) - pow(E,a*s + b*(o + s)) + pow(E,b*s + a*(o + s))*(1 + b*o) + pow(E,a*(o + s))*(-1 - b*o + b*d1*s)))))......; </code></pre> <p>res2 will also be of this kind, and in the end I need to calculate res1/res2, which usually becomes a very small number.</p> <p>I was thinking of splitting the formulas and adding terms to mpg_z in order to not get out of double range for each term, but as the formulas are so long and complex, that this is almost impossible. </p> <p>So in summary, the problem is, that my intermediate results can get so huge that no data type is capable of storing them, so I cannot assign it to mpz and get rid of this problem.</p> <p>I am aware that I want to calculate a double value and actually use mpz_t for integers. As far as I understand this is the only way to store such big data, since mpf_t can only handle float type. To be honest, there is still confusion on my side about the representation in <code>gmp</code>.</p> <p>Any ideas how to approach this ?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload