Seltsame Fehler in der Verwendung von abs() habe ich kürzlich festgestellt
Habe ich C++/C mixed code die ich Baue auf
a) Visual C++ 2010 Express(Kostenlose version) auf Win-7 x32.
b) Cygwin/Gcc-Umgebung installiert auf einem Windows-7-Home-premium-edition x32. Die gcc-version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
c) Ubuntu 10.04 Linux - GCC version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
Ich habe einen code, wie unten(eine member-Funktion ist für meine benutzerdefinierte Klasse), die berechnet den absoluten Wert des übergebenen Objekt myhalf-
myhalf::myhalfabs(myhalf a)
{
float tmp;
tmp = abs(a.value); //This abs is from math.h :- float abs(float)
return tmp;
}
Ist dies perfekt funktioniert, wie gewünscht in MS - Visual C++ 2010. abs() von -ve nos zurückgegeben wurden korrekt als +ve nos mit demselben Wert.
Seltsam, wenn ich baute diesen code auf b) Cygwin/gcc-Umgebung & c) - Linux-gcc-4.4.3 bereits erwähnt, war ich immer junk-Ausgabe. So entlassen Sie den gdb, und nach viel Schweiß und "binary-search-Ansatzes' auf den code, um zu entscheiden, wo es begann schief gehen, ich traf dieses Stück code wie oben gezeigt :
tmp = abs(a.value);
war seltsam verhält, unter cygwin/gcc.
Für die -ve-Zahl abs() wurde wieder auf 0(null). WTF????
Dann als eine Arbeit um, vermied Aufruf abs() aus der stdlib, und codierte meine eigenen abs wie folgt:
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;
}
Klappte das auf cygwin/gcc & linux-gcc und der Ausgang war wie gewünscht, Und natürlich lief es auf MS-Visual C++ 2010.
Dies ist das ganze Makefile für die cygwin/gcc und linux-gcc-builds, die ich verwende. Nur wenn jemand supspects da ist doch was faul:-
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] Was ist hier Los? Was ist die Ursache für diesen seltsamen Fehler?
2] Bin ich über einige alte version von gcc auf cygwin, die dieses Problem hat, da bekannte Fehler oder irgendwas?
3] Ist diese Funktion float abs(float) bekannt sein, veraltet oder etwas mit einer neueren version ersetzt es?
Irgendwelche Hinweise, die nützlich sind.
- Es wäre nützlich, wenn Sie erstellt einen kleinen testcase, so dass sich jeder nehmen kann, das snippet, kompilieren unverändert, und selbst sehen, was du meinst.
- Die
abs()
Funktion in der Regel gibt einint
, und du bist die Zuordnung zu einerfloat
. Sind Sie sicher, dass das nicht die Wurzel Ihrer Probleme? - bekommst du das gleiche Verhalten mit
fabs
? - Ich Stimme mit larsks - es gibt eine
fabs()
Funktion speziell für Schwimmer. Es hilft zu verwenden, statt? - Werde versuchen mit fabs am Montag. Wird update. larsks - siehe math.h . abs hat kann faccept float return float.
Du musst angemeldet sein, um einen Kommentar abzugeben.
math.h
hat die C-version vonabs
die arbeitet aufint
s. Verwenden<cmath>
für die C++ - überlastungen oder verwenden Siefabs()
für die C-floating-point-version.Erste, abs() nimmt und gibt ein
int
. Sie verwenden sollten,fabs(), die nimmt und gibt ein Fließkomma-Wert.Nun, die
abs()
du bist zu enden, der Aufruf ist eigentlich ein GCC built-in-Funktion, das gibt einint
, aber anscheinend akzeptiert einefloat
argument und zurück0
in diesem Fall.float
zu einemint
und kürzen Sie den Wert. Das ist 0.001 abgeschnitten wird zu 0, 1.001 abgeschnitten wird, um 1, usw.Fast sicher, was passiert ist, dass in Ihrem Fall MSVC es ist Kommissionierung bis das C++
abs
float überlastung (welche sich wahrscheinlich gebracht in den globalen namespace für einige Grund oder anderen). Und dann g++ - es ist NICHT Kommissionierung bis die C++ - version (die nicht implizit importiert in den globalen namespace), aber die C-version, die funktioniert auf und gibt eineint
was ist dann mit dem abschneiden der Ausgang auf null.Wenn Sie
#include <cmath>
und verwendenstd::abs
es sollte funktionieren auf allen Plattformen.