Неправильное поведение с плавающей запятой - программирование
Подтвердить что ты не робот

Неправильное поведение с плавающей запятой

Когда я запускаю приведенную ниже программу на С++ в 32-битном ядре powerpc, которое поддерживает плавающую эмуляцию программного обеспечения (аппаратная с плавающей запятой отключена), я получаю неправильную условную оценку. Может ли кто-нибудь сказать мне, какая здесь проблема?

#include <stdio.h>

int main() {
   int newmax = 1;
   if ((newmax + 0.0) > 256) {
       printf("\nShouldn't be here\n");
   } else {
       printf("\nShould be here\n");
   }
}

Compile:

powerpc-linux-g++ -msoft-float -c floating.cxx
powerpc-linux-g++  -o floating floating.o

Вывод в целевой системе:

[linux:/]$ ./floating
Shouldn't be here
4b9b3361

Ответ 1

Вы должны указать -msoft-float также при связывании  Дайте нам разборку с флагом -S: powerpc-linux-g++ -msoft-float -c floating.cxx -S -o floating.s

Ответ 2

Во-первых, почему аппаратная плавающая запятая отключена?

В связи с этим типы приведения могут выполняться в неправильном порядке.

(double)1 = 0x3FF0000000000000
(float) 1 = 0x3F800000

Это ваше условие.

if ((newmax + 0.0) > 256)

В вашем случае: 1) отливка newmax для поплавка или двойная; 2) добавление 0,0; 3) получил значение, возвращающее значение int.

Это зависит от вашего компьютера, но int обычно имеет 32-битное значение. Чтобы проверить это, вы можете использовать:

int i;
printf("%d", sizeof(i));

В любом случае, возвращаясь к вашей проблеме, после преобразования рассчитанного значения в int вы получите большое положительное число. В вашей ситуации я бы распечатал его или сравнил не с 0x100, а с

0x3F800000, 0x3FF0000000000000, 0x3FF00000

Чтобы узнать, что произошло, но лучше всего разборка.

Возможно, это было не так полезно, но это была моя идея, что произошло.

Ответ 3

Это может быть что угодно: от ошибки компилятора до ошибки ассемблера до ошибки компоновщика с ошибкой ядра. Как уже отмечали другие люди: ошибки компилятора, которые являются наиболее вероятным источником этой ошибки, могут быть проверены (или исключены), если вы предоставили результат компиляции с параметром -S. Если это не ошибка компилятора, ошибка ядра с эмуляцией с плавающей запятой станет следующим вероятным источником проблемы.

Ответ 4

Заявление в вашем коде newmax + 0.0 дает результат в float или double, но сравнивается с целым значением.

таким образом, эта ошибка.

Попробуйте это,

int i=1;
printf("%d",(i+0.0));

вы получаете результат 0 каждый раз независимо от значения i. Принимая во внимание,

int i=1;
printf("%f",(i+0.0));

Это дает 1.0000