Έχει αυτήν την εφαρμογή της frexp κάθε απροσδιόριστη συμπεριφορά;

ψήφοι
0

Έχω δημιουργήσει μια προσαρμοσμένη έκδοση του frexp:

auto frexp(float f) noexcept
{
    static_assert(std::numeric_limits<float>::is_iec559);

    uint32_t u;
    std::memcpy(&u, &f, sizeof(float)); // well defined bit transformation from float to int

    int exp = ((u >> 23) & 0xff) - 126; // extract the 8 bits of the exponent (it has an offset of 126)

    // divide by 2^exp (leaving mantissa intact while placing 0 into the exponent)
    u &= ~(0xff << 23); // zero out the exponent bits
    u |= 126 << 23; // place 126 into exponent bits (representing 0)

    std::memcpy(&f, &u, sizeof(float)); // copy back to f
    return std::make_pair(exp, f);
}

Με τον έλεγχο is_iec559Είμαι βεβαιωθείτε ότι floatπληροί

οι απαιτήσεις του IEC 559 (IEEE 754) πρότυπο.

Η ερώτησή μου είναι: Μήπως αυτό σημαίνει ότι οι πράξεις bit που κάνω είναι σαφώς καθορισμένες και κάνω αυτό που θέλω; Αν όχι, είναι ένας τρόπος για να το διορθώσω εκεί;

Θα δοκιμαστεί για κάποιες τυχαίες τιμές και φαίνεται να είναι σωστή, τουλάχιστον για τα Windows 10 καταρτίζονται με MSVC και wandbox . Σημειώστε, ωστόσο, ότι (επίτηδες) Δεν είμαι χειρισμό των υποθέσεων άκρη 0, NaNκαι inf.

Αν κάποιος αναρωτιέται γιατί το κάνω αυτό: Σε αναφοράς βρήκα ότι αυτή η εκδοχή του frexpείναι έως και 15 φορές πιο γρήγορα από std::frexpτα Windows 10. Δεν το έχω δοκιμάσει άλλες πλατφόρμες ακόμα. Αλλά θέλω να βεβαιωθείτε ότι αυτό λειτουργεί όχι μόνο από συμπίπτουν και μπορεί φρένο στο μέλλον.

Δημοσιεύθηκε 09/10/2019 στις 17:58
πηγή χρήστη
Σε άλλες γλώσσες...                            


1 απαντήσεις

ψήφοι
0

«Μήπως αυτό σημαίνει ότι οι πράξεις bit που κάνω είναι σαφώς καθορισμένες ...»

Το TL? DR ;, από τον αυστηρό ορισμό της «σαφώς καθορισμένες»: όχι .

Παραδοχές σας είναι πιθανό σωστές , αλλά δεν σαφώς καθορισμένες , επειδή δεν υπάρχουν εγγυήσεις για το πλάτος bit, ή η εφαρμογή της float. Από § 3.9.1:

Υπάρχουν τρεις τύποι κινητής υποδιαστολής: float, δίκλινα και καιρό διπλό. Ο τύπος παρέχει διπλό τουλάχιστον όσο η ακρίβεια ως πλωτήρας, και ο τύπος παρέχει μακρύ διπλό τουλάχιστον όσο η ακρίβεια ως διπλό. Το σύνολο των τιμών του πλωτήρα τύπου είναι ένα υποσύνολο του συνόλου των αξιών του τύπου διπλής? το σύνολο των αξιών του τύπου διπλού είναι ένα υποσύνολο του συνόλου των αξιών του τύπου μακρύ διπλό. Η παράσταση αξία των ειδών κινητής υποδιαστολής είναι η εφαρμογή καθορισμένη.

Η is_iec559ρήτρα πληροί τις προϋποθέσεις μόνο:

True αν και μόνο αν οι προσκολλάται τύπου σε 559 πρότυπο IEC

Αν η γραμματική τζίνι που έγραψε ένα τρομερό compiler, και έκανε float= binary16 , double= binary32 , και long double= binary64 , και έκανε is_iec559ισχύει για όλους τους τύπους, θα εξακολουθούν να τηρούν το πρότυπο.

Μήπως αυτό σημαίνει ότι μπορώ να εξαγάγετε εκθέτη και δεκαδικό σε ένα καλά καθορισμένο τρόπο;

Η TL? DR ;, από τις περιορισμένες εγγυήσεις της C ++ πρότυπο: όχι .

Ας υποθέσουμε ότι χρησιμοποιείτε float32_tκαι is_iec559είναι αλήθεια, και λογικά προκύπτει από το σύνολο των κανόνων που θα μπορούσε να είναι μόνο binary32 χωρίς παραστάσεις παγίδα, και πολύ σωστά υποστήριξε ότι memcpyείναι μια καλά καθορισμένη για τη μετατροπή μεταξύ αριθμητικών τύπων του ίδιου πλάτους, και δεν θα σπάσει την αυστηρή aliasing. Ακόμη και με όλες αυτές τις υποθέσεις, η συμπεριφορά θα μπορούσε να είναι σαφώς καθορισμένες , αλλά αυτό είναι μόνο πιθανό και δεν εγγυάται ότι μπορείτε να εξαγάγετε το δεκαδικό αυτόν τον τρόπο.

Το πρότυπο IEEE 754 και συμπλήρωμα ως 2 του κωδικοποιήσεις λίγο εγχόρδων , και η συμπεριφορά του memcpyπεριγράφεται με τη χρήση bytes . Ενώ είναι εύλογο να υποθέσουμε το string κομμάτι της uint32_tκαι float32_tθα πρέπει να κωδικοποιηθεί με τον ίδιο τρόπο (π.χ. ίδια endianness), δεν υπάρχει καμία εγγύηση στο πρότυπο γι 'αυτό. Αν οι χορδές λίγο αποθηκεύονται με διαφορετικό τρόπο και θα μετατοπίσει και να καλύψουν την αντιγραφή ακέραιο παράσταση για να πάρει το δεκαδικό μέρος, η απάντηση θα είναι λανθασμένη, παρά το γεγονός ότι memcpyη συμπεριφορά είναι σαφώς καθορισμένες.

Όπως αναφέρθηκε στα σχόλια, endianess θα μπορούσε να είναι ένα ζήτημα. Ξέρει κανείς;

Τουλάχιστον μερικές αρχιτεκτονικές έχουν χρησιμοποιήσει διαφορετικά endianness για πλωτά μητρώα σημείο και μητρώων ακέραιος. Το ίδιο σύνδεσμο λέει ότι εκτός από τις μικρές ενσωματωμένοι επεξεργαστές, αυτό δεν είναι μια ανησυχία. Πιστεύω Wikipedia πλήρως για όλα τα θέματα και αρνείται να κάνει οποιαδήποτε περαιτέρω έρευνα.

Απαντήθηκε 16/12/2019 στις 22:55
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more