Определение литерала как кратного другого приводит к неверным результатам - PullRequest
0 голосов
/ 01 октября 2019

Почему следующий код дает неверные результаты при использовании литерала для 4 * PI, когда он используется в знаменателе, как в 1.0/FOUR_PI?

#include <stdio.h>
#define PI 3.14159265358979323846
#define FOUR_PI 4.0*PI

int main() {
  printf("4.0*PI   = %.20lf\n", 4.0*PI);
  printf("FOUR_PI  = %.20lf\n", FOUR_PI);
  printf("4.0*PI - FOUR_PI  = %.60lf\n", 4.0*PI - FOUR_PI);
  printf("1.0/(4.0*PI) = %.20lf\n", 1.0/(4.0*PI));
  printf("1.0/FOUR_PI  = %.20lf\n", 1.0/FOUR_PI);
  return 0;
}

1 Ответ

1 голос
/ 01 октября 2019

Оказывается, что при разрешении литерала его выражение заменяется на код, а не на его значение. То есть 1.0/FOUR_PI заменяется на 1.0/4.0*PI. См. Следующий пример для иллюстрации:

#include <stdio.h>
#define PI 3.14159265358979323846
#define FOUR_PI (4.0*PI)
#define FOUR_PI2 4.0*PI

int main() {
  printf("4.0*PI   = %.20lf\n", 4.0*PI);
  printf("FOUR_PI  = %.20lf\n", FOUR_PI);
  printf("FOUR_PI2 = %.20lf\n", FOUR_PI2);
  printf("4.0*PI - FOUR_PI  = %.20lf\n", 4.0*PI - FOUR_PI);
  printf("4.0*PI - FOUR_PI2 = %.20lf\n", 4.0*PI - FOUR_PI2);
  printf("1.0/(4.0*PI)  = %.20lf\n", 1.0/(4.0*PI));
  printf("1.0/FOUR_PI   = %.20lf\n", 1.0/FOUR_PI);
  printf("1.0/(FOUR_PI) = %.20lf\n", 1.0/(FOUR_PI));
  printf("1.0/FOUR_PI2  = %.20lf\n", 1.0/FOUR_PI2);
  return 0;
}

Вывод:

4.0*PI   = 12.56637061435917246399
FOUR_PI  = 12.56637061435917246399
FOUR_PI2 = 12.56637061435917246399
4.0*PI - FOUR_PI  = 0.00000000000000000000
4.0*PI - FOUR_PI2 = 0.00000000000000000000
1.0/(4.0*PI)  = 0.07957747154594767280
1.0/FOUR_PI   = 0.07957747154594767280
1.0/(FOUR_PI) = 0.07957747154594767280
1.0/FOUR_PI2  = 0.78539816339744827900
...