Это очевидно, но никто не сказал этого: результат обоих делений - ЕСТЕСТВЕННЫЕ ЧИСЛА.
Значит компилятор где-то не так? Может быть.
И я воспроизвел ту же проблему и в MS VS 2015, так что похоже, что неправильные компиляторы равны 2. И я держу пари, что копейка, что и LLVM делает то же самое.
Так может быть, компиляторы правы?
Отвечая на это не для меня, я просто заметил следующее: похоже, что это проблема неявного приведения из "деления с литералами с десятичными числами" на удвоение.
Следующий небольшой тест показывает, что содержимое двойного числа, присваиваемого из результата времени компиляции деления 2 литералов без приведения, неверно.
Если результат ранее был приведен к плавающему, результат становится правильным.
#include <stdio.h>
int main(void)
{
float fb = (300.65000 / 0.05000);
float fa = (300.6000 / 0.05000);
float fb1 = 6013.0;
float fa1 = 6012.0;
char bufffa[sizeof(float) * 2 +1] = { 0 };
char bufffb[sizeof(float) * 2 +1] = { 0 };
double db = (300.65000 / 0.05000);
double da = (300.6000 / 0.05000);
double db1 = 6013.0;
double da1 = 6012.0;
char buffda[sizeof(double) * 2 + 1] = { 0 };
char buffdb[sizeof(double) * 2 + 1] = { 0 };
int i;
printf("sizeof(float)=%d, sizeof(double)=%d\n", sizeof(float), sizeof(double));
for (i = 0; i < sizeof(fa); i++)
{
sprintf(bufffa + (i * 2), "%02X", ((unsigned char*)(&fa))[i]);
sprintf(bufffb + (i * 2), "%02X", ((unsigned char*)(&fb))[i]);
}
printf("OK: float binary form (compile time division): fa=%s, fb=%s\n", bufffa, bufffb);
for (i = 0; i < sizeof(fa1); i++)
{
sprintf(bufffa + (i * 2), "%02X", ((unsigned char*)(&fa1))[i]);
sprintf(bufffb + (i * 2), "%02X", ((unsigned char*)(&fb1))[i]);
}
printf("OK: float binary form (NOT compile time division): fa1=%s, fb1=%s\n", bufffa, bufffb);
for (i = 0; i < sizeof(da); i++)
{
sprintf(buffda + (i * 2), "%02X", ((unsigned char*)(&da))[i]);
sprintf(buffdb + (i * 2), "%02X", ((unsigned char*)(&db))[i]);
}
printf("NOT OK: double binary form (compile time division): da=%s, db=%s\n", buffda, buffdb);
for (i = 0; i < sizeof(da1); i++)
{
sprintf(buffda + (i * 2), "%02X", ((unsigned char*)(&da1))[i]);
sprintf(buffdb + (i * 2), "%02X", ((unsigned char*)(&db1))[i]);
}
printf("OK: double binary form (NOT compile time division):da1=%s, db1=%s\n", buffda, buffdb);
printf("incorrect values:\n");
printf("printf(int) compile time division, literal: a=%d, b=%d\n", (int)(300.6000 / 0.05000), (int)(300.65000 / 0.05000));
printf("printf(float) compile time division, literal: a=%.15f, b=%.15f\n", (300.6000 / 0.05000), (300.65000 / 0.05000));
printf("printf(double) compile time division: da=%.15f, db=%.15f\n", da, db);
printf("correct values:\n");
printf("printf(int) compile time division, literal with cast: a=%d, b=%d\n", (int)(300.6000 / 0.05000), (int)(float)(300.65000 / 0.05000));
printf("printf(float) compile time division, literal with cast: a=%.15f, b=%.15f\n", (float)(300.6000 / 0.05000), (float)(300.65000 / 0.05000));
printf("printf(float) compile time division: fa=%.15f, fb=%.15f\n", fa, fb);
printf("printf(float) NOT compile time division: fa1=%.15f, fb1=%.15f\n", fa1, fb1);
printf("printf(double) NOT compile time division: da1=%.15f, db1=%.15f\n", da1, db1);
return 0;
}
это выводит следующее в MS-VS.2015:
sizeof(float)=4, sizeof(double)=8
OK: float binary form (compile time division): fa=00E0BB45, fb=00E8BB45
OK: float binary form (NOT compile time division): fa1=00E0BB45, fb1=00E8BB45
NOT OK: double binary form (compile time division): da=00000000007CB740, db=FFFFFFFFFF7CB740
OK: double binary form (NOT compile time division):da1=00000000007CB740, db1=00000000007DB740
incorrect values:
printf(int) compile time division, literal: a=6012, b=6012
printf(float) compile time division, literal: a=6012.000000000000000, b=6012.999999999999091
printf(double) compile time division: da=6012.000000000000000, db=6012.999999999999091
correct values:
printf(int) compile time division, literal with cast: a=6012, b=6013
printf(float) compile time division, literal with cast: a=6012.000000000000000, b=6013.000000000000000
printf(float) compile time division: fa=6012.000000000000000, fb=6013.000000000000000
printf(float) NOT compile time division: fa1=6012.000000000000000, fb1=6013.000000000000000
printf(double) NOT compile time division: da1=6012.000000000000000, db1=6013.000000000000000