... long double, как известно, точнее, чем double.
Нет, это действительно нет. Это может быть, но это ни в коем случае не гарантируется.
Различие между этими двумя типами подробно описано в стандарте (в данном случае, C++17 [basic.fundamental]/8
, хотя более ранние итерации также имеют похожую формулировку). Стандарт говорит о типах с плавающей точкой (мой акцент):
Существует три типа с плавающей точкой: float
, double
и long double
.
Тип double
обеспечивает не менее такой же точности, как float
, а тип long double
обеспечивает не менее такой же точности, как double
.
Набор значений типа float
является подмножеством набора значений типа double
; набор значений типа double
является подмножеством набора значений типа long double
.
Представление значений типов с плавающей запятой определяется реализацией.
Поскольку «подмножество» включает в себя возможность того, что два набора идентичны (аксиоматично, что A ⊂ A
), нет фактического требования, чем long double
имеет больший диапазон и / или точность, чем double
хотя иногда это так.
Если вы хотите выяснить, в чем различия в вашей реализации, вы должны искать класс numeric_limits
в заголовке <limits>
, как показано в следующей демонстрационной программе:
#include <iostream>
#include <limits>
using namespace std;
int main() {
numeric_limits<double> lim_d;
numeric_limits<long double> lim_ld;
cout << "\nmax " << lim_d.max() << " " << lim_ld.max()
<< "\nmin " << lim_d.min() << " " << lim_ld.min()
<< "\nlowest " << lim_d.lowest() << " " << lim_ld.lowest()
<< "\ndigits10 " << lim_d.digits10 << " " << lim_ld.digits10
<< '\n';
}
Вывод на моей системе отформатирован для удобства чтения:
double long double
============ =============
max 1.79769e+308 1.18973e+4932
min 2.22507e-308 3.3621 e-4932
lowest -1.79769e+308 -1.18973e+4932
digits10 15 18
Вы можете видеть, что мой диапазон значительно больше для long double
, а также есть (примерно) дополнительные три десятичных знака точности.
С точки зрения того, как это может повлиять на ваш код, трудно сказать, поскольку вы на самом деле не предоставили адекватного описания того, в чем заключается проблема (в частности, что означают wa
и ac
). Однако, поскольку long double
может иметь большую точность и / или диапазон, чем double
, вполне возможно, что это может повлиять на поведение вашего кода.
Я должен также упомянуть, что правильный спецификатор формата для long double
на самом деле %Lf
(с заглавной буквы L
), а не %lf
. Это может вызвать у вас проблемы, поскольку с данными испытаний, приведенными на странице, на которую вы ссылаетесь в комментарии, я получаю правильный результат для double
/ %f
и long double
/ %Lf
.
Но он дает разные результаты (и, в этом отношении, gcc
предупреждение) для long double
/ %lf
.