Хорошо, сначала я неправильно понял ваш вопрос; название звучит так, как будто вы спрашиваете, почему потолок (функция ceil) неверен.
int d=33554431;
d=d-ceil(d/(float)2);
cout<<d<<" ";
Во второй строке вы приводите литерал 2 к значению с плавающей запятой, поэтому компилятор также преобразует d в число с плавающей запятой при вычислении d / 2. Из-за внутреннего представления значения с плавающей запятой (с плавающей запятой одинарной точности) ограничены в значениях, которые они могут точно представлять. Обычно я предполагаю не более 7 цифр точности, если мне нужно больше, я использую двойные числа. В любом случае, если вы посмотрите на эту ссылку (https://en.wikipedia.org/wiki/Single-precision_floating-point_format) целых чисел в диапазоне [16777217,33554432], округленных до кратного 2. Поэтому, когда компилятор преобразует d в число с плавающей точкой, он становится 33554432. Вы можете видеть, что выполняется следующий код:
int d1 = 33554431;
float f = d1;
int d2 = f;
cout << d1 << endl;
cout << f << endl;
cout << d2 << endl;
Чтобы исправить свой оригинальный код, попробуйте это:
int d=33554431;
d=d-ceil(d/(double)2);
cout<<d<<" ";
или
int d=33554431;
d=d-ceil(d/2.0);
cout<<d<<" ";