Double Cast to unsigned int auf Win32 wird auf 2.147.483.648 gekürzt

Lesezeit: 3 Minuten

Benutzeravatar von Matheus Rossi Saciotto
Matheus Rossi Saciotto

Kompilieren des folgenden Codes:

double getDouble()
{
    double value = 2147483649.0;
    return value;
}

int main()
{
     printf("INT_MAX: %u\n", INT_MAX);
     printf("UINT_MAX: %u\n", UINT_MAX);

     printf("Double value: %f\n", getDouble());
     printf("Direct cast value: %u\n", (unsigned int) getDouble());
     double d = getDouble();
     printf("Indirect cast value: %u\n", (unsigned int) d);

     return 0;
}

Ausgänge (MSVC x86):

INT_MAX: 2147483647
UINT_MAX: 4294967295
Double value: 2147483649.000000
Direct cast value: 2147483648
Indirect cast value: 2147483649

Ausgänge (MSVC x64):

INT_MAX: 2147483647
UINT_MAX: 4294967295
Double value: 2147483649.000000
Direct cast value: 2147483649
Indirect cast value: 2147483649

Im Microsoft-Dokumentation Der maximale Wert der vorzeichenbehafteten Ganzzahl in Konvertierungen von wird nicht erwähnt double zu unsigned int.

Alle Werte oben INT_MAX werden abgeschnitten 2147483648 wenn es sich um die Rückgabe einer Funktion handelt.

Ich benutze Visual Studio 2019 um das Programm zu bauen. Dies passiert nicht auf gcc.

Mache ich etwas falsch? Gibt es eine sichere Möglichkeit, umzuwandeln double zu unsigned int?

  • Und nein, Sie machen nichts falsch (vielleicht außer zu versuchen, den “C”-Compiler von Microsoft zu verwenden)

    – Antti Haapala – Слава Україні

    20. September 2020 um 20:26 Uhr

  • Funktioniert auf meiner Maschine™, getestet auf VS2017 v15.9.18 und VS2019 v16.4.1. Verwenden Sie „Hilfe“ > „Feedback senden“ > „Fehler melden“, um sie über Ihre Version zu informieren.

    – Hans Passant

    20. September 2020 um 20:39 Uhr

  • Ich kann reproduzieren, ich habe die gleichen Ergebnisse wie die des OP. VS2019 16.7.3.

    – Anastaciu

    20. September 2020 um 20:42 Uhr


  • @EricPostpischil in der Tat, es ist das Bitmuster von INT_MIN

    – Antti Haapala – Слава Україні

    20. September 2020 um 21:42 Uhr

  • Behebung ausstehend

    – Antti Haapala – Слава Україні

    22. September 2020 um 10:47 Uhr

  • Lustig, wie sie sagen “ok mit aktivierten Optimierungen, undefiniertes Verhalten wird wirklich undefiniert sein” => der Code funktioniert tatsächlich korrekt :F

    – Antti Haapala – Слава Україні

    21. September 2020 um 10:06 Uhr


  • @AnttiHaapala, ja, ja, Microsoft vom Feinsten.

    – Anastaciu

    21. September 2020 um 10:13 Uhr

  • Die angewendeten Optimierungen waren Inlining und dann die Auswertung konstanter Ausdrücke. Es führt zur Laufzeit keine Float-to-Int-Konvertierung mehr durch. Ich frage mich, ob der Fehler zurückkommt, wenn Sie erzwingen getDouble aus der Reihe und/oder ändern Sie ihn so, dass er einen Wert zurückgibt, von dem der Compiler nicht beweisen kann, dass er konstant ist.

    – zol

    21. September 2020 um 13:55 Uhr


  • @zwol, du hattest Recht, das Erzwingen von Out-of-Line und das Verhindern einer ständigen Bewertung wird den Fehler zurückbringen, aber diesmal in beiden Konvertierungen.

    – Anastaciu

    21. September 2020 um 17:44 Uhr

  • Ich wäre versucht, mir diesen Code anzusehen, aber zum Glück habe ich kein MSVC … : D

    – Antti Haapala – Слава Україні

    21. September 2020 um 16:25 Uhr

  • @AnttiHaapala: Ja, ich auch nicht

    – Peter Cordes

    21. September 2020 um 16:36 Uhr

  • Sie können es jetzt kostenlos herunterladen (Community Edition), natürlich für Forschungszwecke

    – MM

    17. Januar 2021 um 23:16 Uhr

  • _dtoui3 löst auch eine ungültige FP-Ausnahme aus, wenn Werte konvertiert werden, die den uint-Wertebereich überschreiten. (Das ist mir aufgefallen, seit VS2017 aufgerufen wird _ftol3 für eine Konvertierung von in XMM-Registern gespeicherten FP-Zwischenergebnissen zu unsigned long int (ohne Ausnahme), während VS2019 jetzt aufruft _dtoui3 Jetzt wird die Ausnahme ausgelöst.)
    Worüber ich mir nicht sicher bin: Ist es richtig, eine solche Ausnahme bei fp -> uint-Konvertierung auszulösen?

    – MattTT

    24. Februar um 14:06 Uhr

  • @MattTT: Ja, wie ich in meiner Antwort erwähnt habe, x86 FP->int-Konvertierungshardwareanweisungen wie fistp und cvtsd2si Erhöhen des FP-Ungültig-Flags bei Überlauf des Ausgangs. Gleiches gilt für AVX-512 FP-> unsignierte Konvertierungen wie vcvtsd2usi. Wenn es demaskiert ist, wird es tatsächlich eine Ausnahme machen, andernfalls setzen Sie einfach das Flag im x87-Statusregister oder MXCSR. Es ist also definitiv nicht falsch, wenn eine emulierte Konvertierung dasselbe tut, wenn das Ergebnis außerhalb des Bereichs liegt.

    – Peter Cordes

    24. Februar um 14:28 Uhr

1419020cookie-checkDouble Cast to unsigned int auf Win32 wird auf 2.147.483.648 gekürzt

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy