2016-08-05 17 views
24

ist das Gießen der Unendlichkeit zu einer ganzen Zahl ein undefiniertes Verhalten (durch Schwimmers dargestellt)?Wird Unendlich in Ganzzahl undefiniert?

Der Standard sagt:

4,10 Gleitpunktarithmetik integrales Konvertierungen

A prvalue einer Gleitkomma-Typ in einen prvalue eines Integer-Typ umgewandelt werden kann. Die Konvertierung wird abgebrochen. das heißt, der Bruchteil wird verworfen. Das Verhalten ist nicht definiert, wenn der abgeschnittene Wert kann nicht in dem Zieltyp dargestellt werden.

aber ich kann nicht sagen, ob "abgeschnittenen Wert nicht dargestellt werden kann" deckt Unendlichkeit. Ich versuche zu verstehen, warum std::numeric_limits<int>::infinity() und static_cast<int>(std::numeric_limits<float>::infinity()) unterschiedliche Ergebnisse haben.

#include <iostream> 
#include <limits> 

int main() 
{ 
    std::cout << std::numeric_limits<int>::infinity() << std::endl; 
    std::cout << static_cast<int> (std::numeric_limits<float>::infinity()) << std::endl; 
    return 0; 
} 

Ausgang:

0 
-2147483648 

Das Ergebnis std::numeric_limits<int>::infinity()is well defined und gleich 0, aber ich kann keine Informationen finden über die Unendlichkeit werfen.

+9

Vergessen Sie nicht, dass 'std :: numeric_limits :: infinity()' nur nützlich ist, wenn 'std :: numeric_limits :: has_infinity == true' ist und es nicht ist. – NathanOliver

+0

@NathanOliver, Sie haben Recht, aber selbst wenn 'has_infinity == false' Ergebnis von 'infinity()' definiert ist. – Gluttton

+0

Ich bin mir ziemlich sicher, dass der Wert unendlich in einem "int" nicht dargestellt werden kann. – aschepler

Antwort

15

sagte Sie

Ich kann nicht sagen, ob deckt unendlich

„abgeschnittene Wert nicht dargestellt werden kann“, aber es läuft alles auf

Was das ist Ergebnis des Abschneidens der Unendlichkeit.

Der C-Standard (in C eingebaut ++ über 26,9) Antworten, die ganz deutlich:

C standard semantics for <code>trunc</code>

Da Abschneiden der Unendlichkeit noch unendlich ist, und Unendlichkeit kann nicht in int dargestellt werden (ich hoffe nicht da ist Frage zu diesem Teil), das Verhalten ist undefiniert.

+3

Gibt es Hinweise darauf, dass "Trunkierung" in diesem Sinne dem Verhalten der C-Bibliothek "trunc" -Funktion entspricht? –

20

Gießen von unendlich bis integer ist undefiniert.

Das Verhalten ist nicht definiert, wenn der abgeschnittene Wert nicht im Zieltyp dargestellt werden kann.

sagt alles. Da die Trunkierung die Genauigkeit, aber nicht die Größe entfernt, ist eine abgeschnittene Unendlichkeit immer noch unendlich, und ganze Zahlen können keine Unendlichkeit darstellen.

4

Ich versuche zu verstehen, warum std::numeric_limits<int>::infinity() und static_cast<int>(std::numeric_limits<float>::infinity()) unterschiedliche Ergebnisse haben.

Der Standard sagt: 18.3.2.4

statische constexpr T unendlich() noexcept;

47 Darstellung der positiven Unendlichkeit, falls vorhanden. [216]

48 Bedeutungsvolles für alle Spezialisierungen für die has_infinity! = False. Erforderlich für Spezialisierungen, für die is_iec559! = False ist.

--- edit ---

Nach 18.3.2.7/1 [numeric.special]

1 Alle Mitglieder für alle Spezialisierungen zur Verfügung gestellt werden soll. Viele Werte müssen jedoch nur unter bestimmten Bedingungen sinnvoll sein (z. B. ist epsilon() nur sinnvoll, wenn is_integer falsch ist). Jeder Wert, der nicht "sinnvoll" ist, muss auf 0 oder false gesetzt werden.

+0

Die Spezialisierung für 'float' § 18.3.2.7 hat 'inline statisch constexpr float infinity() noexcept {Rückgabewert; } ' – NathanOliver

+0

@BenVoigt Das ist 18.3.2.7 in meinem, wird entsprechend bearbeiten. – kfsone