I’m trying to obtain the machine precision on gmp variables.
To that end, I adapted the code from wikipedia, to compute the precision of a gmp with a fixed precision:
int main( int argc, char **argv )
{
long int precision = 100;
mpf_set_default_prec(precision); // in principle redundant, but who cares
mpf_t machEps, one, temp; // "one" is the "1" in gmp. tmp is to comparison.
mpf_init2(machEps, precision);
mpf_set_ui(machEps, 1); // eps = 1
mpf_init_set(one,machEps); // ensure "one" has the same precision as machEps
mpf_init_set(temp,machEps); // ensure "temp" has the same precision as machEps
do {
mpf_div_ui(machEps,machEps,2); // eps = eps/2
mpf_div_ui(temp,machEps,2); // temp = eps/2
mpf_add(temp,temp,one); // temp += 1
}
while ( mpf_cmp(temp,one)); // temp == 1
/// print the result...
char *t = new char[400];
mp_exp_t expprt;
mpf_get_str(NULL, &expprt, 10, 10, machEps);
sprintf(t, "%se%ld", mpf_get_str(NULL, &expprt, 10, mpf_get_default_prec(), machEps), expprt);
printf( "Calculated Machine epsilon: %s\n", t);
return 0;
}
However, the result is not consistent with the wikipedia’s formula, neither changes with the precision I set. What am I missing? I’ve also tried with double and float (c standard), and the result is correct…
I get results that are consistent with wikipedia’s formula, and the values depend on the precision.
However, the value – and the effective precision – only change when crossing a limb-boundary(1). For me, that means multiples of 64, so for
the calculated machine epsilon is
Some results:
For comparison:
The output of the GMP programme is in the form
mantissa,'e',exponentwhere the value is(1) GMP represents the floating point numbers as a pair of exponent (for base 2) and mantissa (and sign). The mantissa is maintained as an array of unsigned integers, the limbs. For me, the limbs are 64 bits, on 32 bit systems usually 32 bits (iirc). So when the desired precision is between
(k-1)*LIMB_BITS(exclusive) andk*LIMB_BITS(inclusive), the array for the mantissa containsklimbs, and all of them are used, thus the effective precision isk*LIMB_BITSbits. Therefore the epsilon only changes when the number of limbs changes.