Потолочная операция дает неправильный ответ - PullRequest
0 голосов
/ 03 сентября 2018

`когда я запускаю следующий код, он дает мне ответ как 16777216, но он должен дать 16777215, почему это так ..

    int d=33554431;
    d=d-ceil(d/(float)2);
    cout<<d<<" ";

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Хорошо, сначала я неправильно понял ваш вопрос; название звучит так, как будто вы спрашиваете, почему потолок (функция 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<<" ";
0 голосов
/ 03 сентября 2018

Ну, мой калькулятор говорит, что 33,554,431 / 2 на самом деле 16,777,215.5 , что означает, что ceil (16,777,215.5) = 16,777,216 на самом деле правильно.

Ceil округляется до следующего большего целого числа, если это было неясно.

...