1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
   | #include <iostream>
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <string>
 
using namespace std;
 
typedef long long int_64;
 
//#define D2I_CONVERSION_FACTOR (1.5 * 4503599627370496.0)
#define D2I_CONVERSION_FACTOR          6755399441055744.0
inline int d2i(double val)
{
    union {
        int i[2];
        double d;
    } dlong;
    dlong.d = val + D2I_CONVERSION_FACTOR;
    return dlong.i[0];
}
 
// la fonction qui fait le test
 
void tt(void)
{
    // nombre de boucles à faire
 
    #define NB 100000000
 
    LARGE_INTEGER t1,t2,t3,t4; // pour stocker les points de QueryPerformanceCounter
                               // encadrant les boucles
 
    double d = -12345.1234665;
    int n1 = 0, n2 = 0;
 
    // boucle utilisant "l'astuce" d2i
 
    QueryPerformanceCounter(&t1);
    for (int i=0;i<NB;++i)
    {
        n1 = d2i(d);
    }
    QueryPerformanceCounter(&t2);
 
    // boucle utilisant le cast classique, ou l'assembleur
    // (commenter/décommenter la version à tester)
 
    QueryPerformanceCounter(&t3);
    for (int i=0;i<NB;++i)
    {
        // pour tester le cast classique
        //n2 = (int)d;
 
        // pour tester en assembleur
        __asm__ (
            "fldl %[orig]\n\t"
            "fistpl %[dest]\n\t"
            : [dest] "=g" (n2)
            : [orig] "m" (d)
            :
        );
    }
    QueryPerformanceCounter(&t4);
 
    // calcul des durées et du rapport, et affichage des résultats
 
    int_64 r12 = t2.QuadPart - t1.QuadPart;
    int_64 r34 = t4.QuadPart - t3.QuadPart;
 
    double rapport;
    if (r34)
    {
        rapport = (double)r12/(double)r34;
    }
    else
    {
        rapport = -1;
    }
 
    cout<<"special : "<<r12<<",   cast : "<<r34<<", rapport (astuce/cast) = "<<rapport<<endl;
 
    if (n1!=n2)
    {
        cout<<"error  (n1 = "<<n1<<") != (n2 = "<<n2<<")"<<endl;
        cout<<"n1 = "<<n1<<",  n2 = "<<n2<<endl;
    } else
    {
        cout<<"bravo, n1 == n2 = "<<n1<<endl;
    }
 
}
 
int main()
{
    tt();
 
    return 0;
} | 
Partager