File: precision.c

package info (click to toggle)
regina-normal 4.93-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 28,576 kB
  • sloc: cpp: 86,815; ansic: 13,030; xml: 9,089; perl: 951; sh: 380; python: 273; makefile: 103
file content (66 lines) | stat: -rw-r--r-- 1,658 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 *	precision.c
 *
 *	This file contains the functions
 *
 *		int decimal_places_of_accuracy(double x, double y);
 *		int complex_decimal_places_of_accuracy(Complex x, Complex y);
 *
 *	which are used within the kernel to determine how many decimal
 *	places of accuracy the doubles (resp. Complexes) x and y have in common.
 *	Typically x and y will be two estimates of the same computed quantity
 *	(e.g. the volume of a manifold as computed at the last and the
 *	next-to-the-last iterations of Newton's method in
 *	hyperbolic_structures.c), and decimal_places_of_accuracy()
 *	will be used to tell the user interface how many decimal places
 *	should be printed.  We compute the number of decimal places of
 *	accuracy instead of the number of significant figures, because
 *	this is what printf() requires in its formatting string.
 */

#include "kernel.h"


int decimal_places_of_accuracy(
	double	x,
	double	y)
{
	int	digits;

	if (x == y)
	{
		if (x == 0.0)
			digits = DBL_DIG;
		else
			digits = DBL_DIG - (int) ceil(log10(fabs(x)));
	}
	else
		digits = - (int) ceil(log10(fabs(x - y)));

	/*
	 *	Typically the difference between the computed values
	 *	of a quantity at the penultimate and ultimate iterations
	 *	of Newton's method is a little less than the true error.
	 *	So we fudge a bit.
	 */
	digits -= 4;

	if (digits < 0)
		digits = 0;

	return digits;
}


int complex_decimal_places_of_accuracy(
	Complex	x,
	Complex	y)
{
	int	real_precision,
		imag_precision;

	real_precision = decimal_places_of_accuracy(x.real, y.real);
	imag_precision = decimal_places_of_accuracy(x.imag, y.imag);

	return MIN(real_precision, imag_precision);
}