Странная ошибка при использовании abs (), с которой я столкнулся недавно

У меня есть смешанный код C ++ / C, который я построил на

a) Visual C ++ 2010 Express (бесплатная версия) на Win-7 x32.

b) Среда Cygwin / Gcc, установленная в Windows-7 Home Premium Edition x32. Версия gcc 3.4.4 (специальный cygming, gdc 0.12, с использованием dmd 0.125)

c) Ubuntu 10.04 Linux - GCC версии 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

У меня есть код, как показано ниже (его функция-член для моего пользовательского класса), которая вычисляет абсолютное значение переданного объекта myhalf-

myhalf::myhalfabs(myhalf a)
{
    float tmp;   
    tmp = abs(a.value); //This abs is from math.h :-  float abs(float)
    return tmp;
}

Это отлично работает в MS - Visual C ++ 2010. abs () of -ve nos были возвращены правильно как + ve nos, имеющие то же значение. Как ни странно, когда я создавал этот код в b) среде Cygwin / gcc и c) упомянутом выше Linux-gcc 4.4.3, я получал ненужный вывод. Итак, запустил gdb, и после долгих усилий и «подхода к двоичному поиску» кода, чтобы решить, где что-то пошло не так, я нашел этот фрагмент кода, как показано выше:

tmp = abs(a.value);

, который странно себя ведет под cygwin / gcc.

Для чисел -ve abs () возвращал 0 (ноль). WTF ??

Затем, как обходной маневр, я избегал вызова abs () из stdlib и закодировал свой собственный abs, как показано ниже:

myhalf::myhalfabs(myhalf a)
{
    float tmp;
    unsigned int tmp_dbg;
    // tmp = abs(a.value);
    tmp_dbg = *(unsigned int*)(&a.value);
    tmp_dbg = tmp_dbg & 0x7FFFFFFF;
    tmp = *(float*)(&tmp_dbg);

    return tmp;
}

Это отлично сработало на cygwin / gcc и linux-gcc, и вывод был желаемым конечно, он отлично работал на MS-Visual C ++ 2010.

Это весь Makefile для сборок cygwin / gcc и linux-gcc, которые я использую. Просто если кто-то там подозревает: -

OBJS= <all my obj files listed here explicitly>

HEADERS= <my header files here>
CFLAGS= -Wall
LIBS= -lm
LDFLAGS= $(LIBS)

#MDEBUG=1
ifdef MDEBUG
CFLAGS += -fmudflap
LDFLAGS += -fmudflap -lmudflap
endif

myexe:    $(OBJS)
    g++ $(OBJS) $(LDFLAGS) -o myexe

%.o:    %.cpp $(HEADERS) Makefile
    g++ $(CFLAGS) -c $<

clean:
    rm -f myexe $(OBJS)

1] Что здесь происходит? Какова основная причина этой странной ошибки?

2] Я использую старую версию gcc на cygwin, в которой эта проблема называется известной ошибкой или чем-то в этом роде?

3] Известна ли эта функция float abs (float) быть устаревшим или что-то, заменяющее его более новой версией?

Любые указатели полезны.

23
задан goldenmean 30 September 2011 в 18:26
поделиться

1 ответ

Во-первых, abs () принимает и возвращает int. Вам следует использовать fabs () , которая принимает и возвращает значение с плавающей запятой.

Итак, abs(), который вы в конечном итоге вызываете, на самом деле является встроенной функцией GCC , которая возвращает int, но, очевидно, принимает аргумент float и возвращает 0 в этом случае.

14
ответ дан 29 November 2019 в 01:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: