long double unter GCC
-
volkard schrieb:
Meinst 10 Byte?
Vielleicht biste auf alignment/padding reingefallen.
Ja, das könnte sein. Also
sizeof(long double)
gibt 12 aus. Wie ich dann auf die 10 komme ist mir nicht bewusst. Gibt es also einen plattformunabhängigen Weg das zu implementieren? Wäre das eine Idee?if(std::numeric_limits<T>::is_iec559) { return !!(x & T(-0.L)); } else { ... }
Aber ich weiß nicht, wie das auf verschiedenen Compilern aussieht. -0.L nach
float
gecastet kann ja auch etwas anderes als nur dieses Signbit ergeben, oder? Und -0.L alleine zwingt den Compiler doch nicht, nur das Signbit als einziges zu setzen...
-
Ich bleibe bei 10 Bytes. Denke nicht, daß Du eine Maschine mit 12 Bytes findest.
http://en.wikipedia.org/wiki/Long_double
-
volkard schrieb:
Ich bleibe bei 10 Bytes. Denke nicht, daß Du eine Maschine mit 12 Bytes findest.
http://en.wikipedia.org/wiki/Long_doublehttp://ideone.com/J3cxGk
Bei mir zu Hause im uebrigen auch.
-
volkard schrieb:
Ich bleibe bei 10 Bytes. Denke nicht, daß Du eine Maschine mit 12 Bytes findest.
http://en.wikipedia.org/wiki/Long_doubleIch glaube dir schon wenn du sagst, dass die long doubles 10 Bytes haben (Hab mich weiter oben vertan, wollte Bytes statt Bits schreiben, die Zahlenwerte bleiben aber dieselben). Die Sache ist nun einmal, dass ich plattformunabhängig sein möchte (wenn möglich). Und theoretisch kann long double auch tatsächlich 12 Bytes groß sein (und nicht nur 10 + Padding wie auf GCC; das ist wenn ich mir das recht überlege auch das einzige was Sinn ergibt, sonst wären zuhinterst nicht diese beiden leeren Bytes...). Laut IEEE Standard gibt es 128 Bit Floats, woher weiß ich denn z.B. dass nicht so einer vorliegt?
-
Bei mir gibt's
16
aus.
-
Kellerautomat schrieb:
volkard schrieb:
Ich bleibe bei 10 Bytes. Denke nicht, daß Du eine Maschine mit 12 Bytes findest.
http://en.wikipedia.org/wiki/Long_doublehttp://ideone.com/J3cxGk
Bei mir zu Hause im uebrigen auch.Im Link steht doch
On the x86 architecture, most C compilers implement long double as the 80-bit extended precision type supported by x86 hardware (sometimes stored as 12 or 16 bytes to maintain data structure alignment), as specified in the C99 / C11 standards (IEC 60559 floating-point arithmetic (Annex F)).
Es geht mir nicht um sizeof, sondern wo der TO sein Vorzeichenbit findet. Da bleibe ich bei 10, auch wenns nach standard 16 sein dürfen.
-
Mittels numeric_limits<..>::digits und max_exponent sollte sich ausrechnen lassen, welches Bit für das Vorzeichen verwendet wird und entsprechend in welchem Byte es zu finden ist.
-
GCC 4.8.2 auf x64 ubuntu: long double ist 16, auch mit #pragma pack(1)
-
camper schrieb:
Mittels numeric_limits<..>::digits und max_exponent sollte sich ausrechnen lassen, welches Bit für das Vorzeichen verwendet wird und entsprechend in welchem Byte es zu finden ist.
Etwa so?
#include <iostream> #include <limits> #include <cmath> #include <climits> int main() { for (long double x : {-0., 0., -1.1, 1.684}) { unsigned char const* ptr = reinterpret_cast<unsigned char const*>(&x); static auto const index = std::numeric_limits<decltype(x)>::digits + (int)std::log2(std::numeric_limits<decltype(x)>::max_exponent) + 1; // log2 sollte hier durch eine constexpr-Funktion oder __builtin_clz o.ä. ersetzt werden. std::cout << ((ptr[index/CHAR_BIT] & (1 << (index % CHAR_BIT))) != 0); } }
Edit: Der obige Code funktioniert gar nicht für
double
oderfloat
daindex==64
bzw.32
. Man muss also 1 vonindex
abziehen (bzw, das+1
entfernen). Es scheint als ob beilong double
irgend ein Padding stattfindet.Natürlich ist das nicht zuverlässig. Beispielsweise könnte das Vorzeichenbit ja auch nicht das MSB sein. Man kann aber
T(-0)^T(0)
als Mask verwenden, oder? Also im Prinzip wie vom TE schon erwähnt.if(std::numeric_limits<T>::is_iec559)
Könnte dir Warnungen geben. Sowas wie "condition of if-Statement is always true" - vielleicht auch nicht wenn der Compiler sieht dass der Ausdruck (Typ-)abhängig ist.
auch mit #pragma pack(1)
Betrifft das nicht nur Klassen?
-
Arcoth schrieb:
Edit: Der obige Code funktioniert gar nicht für
double
oderfloat
daindex==64
bzw.32
. Man muss also 1 vonindex
abziehen (bzw, das+1
entfernen). Es scheint als ob beilong double
irgend ein Padding stattfindet.float und double speichern das höhchstwertige Bit der Mantisse für normalisierte Zahlen nicht - die 53 signifikanten Stellen von double benötigen also nur 52 bits in der Darstellung. bei den 80bit-long doubles ist das nicht der Fall.
-
Binäre Operatoren gehen auf Fließkommatypen erschreckenderweise nicht. Gibt's einen standardkonformen Workaround?