Анализ числа с плавающей запятой / двойной точности в 32 десятичных разрядах
Из файла .c другого парня я увидел это:
const float c = 0.70710678118654752440084436210485f;
где он хочет избежать вычисленияsqrt(1/2)
.
Может ли это действительно храниться как-то с простымC/C++
? Я имею в виду, не теряя точности. Это кажется мне невозможным.
Я использую C ++, но я не верю, что разница в точности между этими двумя языками слишком велика (если есть), поэтому я ее не тестировал.
Итак, я написал эти несколько строк, чтобы взглянуть на поведение кода:
std::cout << "Number: 0.70710678118654752440084436210485\n";
const float f = 0.70710678118654752440084436210485f;
std::cout << "float: " << std::setprecision(32) << f << std::endl;
const double d = 0.70710678118654752440084436210485; // no f extension
std::cout << "double: " << std::setprecision(32) << d << std::endl;
const double df = 0.70710678118654752440084436210485f;
std::cout << "doublef: " << std::setprecision(32) << df << std::endl;
const long double ld = 0.70710678118654752440084436210485;
std::cout << "l double: " << std::setprecision(32) << ld << std::endl;
const long double ldl = 0.70710678118654752440084436210485l; // l suffix!
std::cout << "l doublel: " << std::setprecision(32) << ldl << std::endl;
Вывод такой:
* ** ***
v v v
Number: 0.70710678118654752440084436210485 // 32 decimal digits
float: 0.707106769084930419921875 // 24 >> >>
double: 0.70710678118654757273731092936941
doublef: 0.707106769084930419921875 // same as float
l double: 0.70710678118654757273731092936941 // same as double
l doublel: 0.70710678118654752438189403651592 // suffix l
где*
последняя точная цифраfloat
, **
последняя точная цифраdouble
а также***
последняя точная цифраlong double
.
Выход изdouble
имеет 32 десятичных знака, так как я установил точностьstd::cout
на это значение.
float
выход имеет 24, как и ожидалось, как сказаноВот:
float has 24 binary bits of precision, and double has 53.
Я ожидаю, что последний результат будет таким же, как и перед последним, т.е.f
суффикс не помешает номеру статьdouble
, ясчитать что когда я пишу это:
const double df = 0.70710678118654752440084436210485f;
происходит то, что сначала число становитсяfloat
один, а затем хранится какdouble
, так что после 24-х десятичных цифр, он имеет нули, и поэтомуdouble
точность останавливается там.
Я прав?
Отэтот Ответ я нашел некоторую соответствующую информацию:
float x = 0 has an implicit typecast from int to float.
float x = 0.0f does not have such a typecast.
float x = 0.0 has an implicit typecast from double to float.
[РЕДАКТИРОВАТЬ]
Около__float128
, это не стандартно, поэтому это вне конкуренции. Узнать большеВот.