Спецификатор формата%Lf для long double в C не работает, как ожидалось

Изучая основы C из онлайн-видео, автор поделился приведенным ниже кодом, чтобы найти разницу между float, double и long double. Я запустил эту программу в Eclispse на 64-битном ноутбуке с Windows 10.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
puts("Floating point type usage in C:");

// Floating point types
float           floatNumber;
double          doubleNumber;
long double     longDoubleNumber;

// Size of floating point types
//lu - Stands for "unsigned decimal integer" and "long"
printf("Storage size for unsigned float : %lu  bytes \n", sizeof(float));
printf("Storage size for double :         %lu  bytes \n", sizeof(double));
printf("Storage size for long double :   %lu  bytes \n", sizeof(long double));

floatNumber = 2.0/3.0;
doubleNumber = 2.0/3.0;
longDoubleNumber = 2.0/3.0;

puts("\nCompare precision at 4 decimal points:");
printf("floatNumber      = %1.4f\n", floatNumber);
printf("doubleNumber     = %1.4lf\n", doubleNumber);
printf("longDoubleNumber = %1.4Lf\n", longDoubleNumber);

puts("\nCompare precision at 10 decimal points:");
printf("floatNumber      = %1.10f\n", floatNumber);
printf("doubleNumber     = %1.10lf\n", doubleNumber);
printf("longDoubleNumber = %1.10Lf\n", longDoubleNumber);

puts("\nCompare precision at 30 decimal points:");
printf("floatNumber      = %1.30f\n", floatNumber);
printf("doubleNumber     = %1.30lf\n", doubleNumber);
printf("longDoubleNumber = %1.30g\n", longDoubleNumber);
return 0;
}

Почему-то я не получаю ожидаемый результат. Я добавил вывод, который я получил в своей консоли Eclispse. Может ли кто-нибудь помочь мне выяснить, что пошло не так

Floating point type usage in C:
Storage size for unsigned float : 4  bytes 
Storage size for double :         8  bytes 
Storage size for long double :   16  bytes 

Compare precision at 4 decimal points:
floatNumber      = 0.6667
doubleNumber     = 0.6667
longDoubleNumber = 0.0000              //Expected value = 0.6667

Compare precision at 10 decimal points:
floatNumber      = 0.6666666865
doubleNumber     = 0.6666666667
longDoubleNumber = 0.0000000000   //Expected value = 0.6666666667

Compare precision at 30 decimal points:
floatNumber      = 0.666666686534881590000000000000 
doubleNumber     = 0.666666666666666630000000000000
longDoubleNumber = 3.1728895775924853e-317   //This is not the expected value

1 ответ

Я предлагаю вам внести пару исправлений, а затем повторно запустить тесты. Во-первых, мы должны убедиться, что все типы верны и не продвигаются, или что-то другое. Нам нужно изменить

floatNumber = 2.0/3.0;
longDoubleNumber = 2.0/3.0;

в

floatNumber = 2.0f / 3.0f;
longDoubleNumber = 2.0L / 3.0L;

Это необходимо для того, чтобы запретить продвижение результата на удвоение (в первом случае и преобразование типа с двойного на длинное удвоение во втором), потому что первоначально оба ваших операнда имели тип "двойной" в каждом случае.

Во-вторых, вы должны избавиться от неопределенного поведения в

printf("longDoubleNumber = %1.30g\n", longDoubleNumber);

и использовать правильный длинный спецификатор двойной длины в строке формата. Это будет выглядеть так:

printf("longDoubleNumber = %1.30Lg\n", longDoubleNumber);

Сообщите нам о результатах.

Другие вопросы по тегам