математика с очень маленькими числами, используя float и double - PullRequest
0 голосов
/ 12 февраля 2020

Я пишу этот код только для того, чтобы увидеть разницу в значении точности при использовании чисел с плавающей точкой и двойных чисел. в основном я пытаюсь вычислить значение приведенной постоянной Планка. Сокращенные Планки const = Планки const / 2π.

#include<stdio.h>
#include<math.h>

const float H = 6.62607015e-34;
const float Pi = 3.1415926;
int main()
{
    float a = H / (2 * Pi);
    double b = H / (2 * Pi);
    printf("float is %ld \ndouble is %ld", a, b);
    return 0;
}

Но вывод вообще не имеет смысла. Я не знаю, что я делаю здесь неправильно.

float is 536870912
double is 954303911

Я даже пытался изменить типы данных констант на удвоенные, что было не лучше.

float is 0
double is 954303911

I уменьшил значащие цифры в константе, но это не имело значения. Может кто-нибудь сказать мне, что я здесь делаю не так?

Ответы [ 2 ]

3 голосов
/ 12 февраля 2020

%ld должен получить long int в качестве аргумента, а не double. Попробуйте %f, %e, %g, с дополнительными модификаторами на ваш выбор или другие форматы, поддерживаемые printf.

Кроме того, вы должны рассмотреть возможность включения предупреждений компилятора, например -W -Wall с g cc:

: In function 'main':
:10:5: warning: format '%ld' expects argument of type 'long int', but argument 2 has type 'double' [-Wformat=]
     printf("float is %ld \ndouble is %ld", a, b);
     ^
:10:5: warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'double' [-Wformat=]

Аргументы имеют тип double, поскольку float повышается при использовании с функцией varargs, такой как printf.

В вашем примере вычисления в основном одинаковы: оба вычисления H / (2 * Pi) выполняются как float, и после этого результат преобразуется в double: в одном случае, поскольку b равен double, а в другом случае из-за правил продвижения на printf.

1 голос
/ 12 февраля 2020
printf("float is %ld \ndouble is %ld", a, b);

%d - это спецификатор формата для целых чисел, а не чисел с плавающей точкой. Вместо этого используйте %f, это будет работать для double, а из-за автоматического расширения аргументов c, %f работает также для float.

Большинство компиляторов выдают предупреждение об ошибке такого типа. , Убедитесь, что в вашем компиляторе включены предупреждения. Для G CC используйте -Wall -Wextra.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...