Я кодирую несколько эталонных алгоритмов как на Java, так и на C/C++. Некоторые из этих алгоритмов используют . Я хотел бы, чтобы две реализации каждого алгоритма давали идентичные результаты без округления по-разному. Один из способов сделать это, который до сих пор работал последовательно, — использовать определяемую пользователем константу pi
, которая абсолютно одинакова в обоих языках, например 3.14159. Однако мне кажется глупым определять pi, когда уже есть высокоточные константы, определенные как в библиотеках Java, так и в библиотеках GCC.
Я потратил некоторое время на написание быстрых тестовых программ, просматривая документацию по каждой библиотеке и читая о типах с плавающей запятой. Но я не смог убедить себя в том, что java.lang.Math.PI (или java.lang.StrictMath.PI) равен или не равен M_PI в math.h.
GCC 3.4.4 (cygwin) math.h содержит:
#define M_PI 3.14159265358979323846
^^^^^
но это
printf("%.20f", M_PI);
производит
3.14159265358979311600
^^^^^
что говорит о том, что последним 5 цифрам нельзя доверять.
Между тем, Javadocs говорят, что java.lang.Math.PI:
Значение
double
, которое ближе любого другого к pi, отношению длины окружности к ее диаметру.
а также
public static final double PI 3.141592653589793d
который опускает сомнительные последние пять цифр из константы.
System.out.printf("%.20f\n", Math.PI);
производит
3.14159265358979300000
^^^^^
Если у вас есть опыт работы с типами данных с плавающей запятой, можете ли вы убедить меня, что эти библиотечные константы точно равны? Или что они точно не равны?