• [^] # Re: Autre méthode

    Posté par (site web personnel) . En réponse à la dépêche Dans les kiosques cet été 2011. Évalué à 9. Dernière modification le 07 août 2011 à 17:34.

    Je n'ai pas lu l'article, mais ça avait l'air marrant alors j'ai testé rapidement en C++ :

    #include <iostream>
    #include <limits>
    #include <typeinfo>
    using namespace std;
    template <typename T> void swap1(T & A, T & B) {
     T oldA = A;
     T oldB = B;
     A = A + B;
     B = A - B;
     A = A - B;
     if (!((A==oldB) && (B==oldA))) {
     cout << "swap+\ttype=" << typeid(T).name()
     << "\tavant A=" << oldA << "\tB=" << oldB
     << "\taprès A=" << A << "\tB=" << B << endl;
     }
    }
    template <typename T> void swap2(T & A, T & B) {
     T oldA = A;
     T oldB = B;
     A ^= B;
     B ^= A;
     A ^= B;
     if (!((A==oldB) && (B==oldA))) {
     cout << "swap^\ttype=" << typeid(T).name()
     << "\tavant A=" << oldA << "\tB=" << oldB
     << "\taprès A=" << A << "\tB=" << B << endl;
     }
    }
    template <typename T> void letsTest(void (*swap)(T&, T&)) {
     T a;
     T b;
     a = 42; b = 69; (*swap)(a,b);
     a = numeric_limits<T>::max(); b = 42; (*swap)(a,b);
     a = numeric_limits<T>::min(); b = 42; (*swap)(a,b);
     a = numeric_limits<T>::max(); b = numeric_limits<T>::max(); (*swap)(a,b);
     a = numeric_limits<T>::min(); b = numeric_limits<T>::max(); (*swap)(a,b);
     a = numeric_limits<T>::max(); b = numeric_limits<T>::min(); (*swap)(a,b);
     a = numeric_limits<T>::min(); b = numeric_limits<T>::min(); (*swap)(a,b);
    }
    int main() {
     letsTest<char>(swap1);
     letsTest<bool>(swap1);
     letsTest<short>(swap1);
     letsTest<int>(swap1);
     letsTest<long>(swap1);
     letsTest<long long>(swap1);
     letsTest<unsigned short>(swap1);
     letsTest<unsigned int>(swap1);
     letsTest<unsigned long>(swap1);
     letsTest<unsigned long long>(swap1);
     letsTest<float>(swap1);
     letsTest<double>(swap1);
     letsTest<long double>(swap1);
     letsTest<char>(swap2);
     letsTest<bool>(swap2);
     letsTest<short>(swap2);
     letsTest<int>(swap2);
     letsTest<long>(swap2);
     letsTest<long long>(swap2);
     letsTest<unsigned short>(swap2);
     letsTest<unsigned int>(swap2);
     letsTest<unsigned long>(swap2);
     letsTest<unsigned long long>(swap2);
    }
    

    Les cas erronés (résumé : le premier swap ne marche pas sur les bool et tous les flottants) :

    swap+ type=b avant A=1 B=1 après A=1 B=0
    swap+ type=b avant A=1 B=1 après A=1 B=0
    swap+ type=b avant A=1 B=1 après A=1 B=0
    swap+ type=f avant A=3.40282e+38 B=42 après A=0 B=3.40282e+38
    swap+ type=f avant A=1.17549e-38 B=42 après A=42 B=0
    swap+ type=f avant A=3.40282e+38 B=3.40282e+38 après A=-nan B=inf
    swap+ type=f avant A=1.17549e-38 B=3.40282e+38 après A=3.40282e+38 B=0
    swap+ type=f avant A=3.40282e+38 B=1.17549e-38 après A=0 B=3.40282e+38
    swap+ type=d avant A=1.79769e+308 B=42 après A=0 B=1.79769e+308
    swap+ type=d avant A=2.22507e-308 B=42 après A=42 B=0
    swap+ type=d avant A=1.79769e+308 B=1.79769e+308 après A=-nan B=inf
    swap+ type=d avant A=2.22507e-308 B=1.79769e+308 après A=1.79769e+308 B=0
    swap+ type=d avant A=1.79769e+308 B=2.22507e-308 après A=0 B=1.79769e+308
    swap+ type=e avant A=1.18973e+4932 B=42 après A=0 B=1.18973e+4932
    swap+ type=e avant A=3.3621e-4932 B=42 après A=42 B=0
    swap+ type=e avant A=1.18973e+4932 B=1.18973e+4932 après A=-nan B=inf
    swap+ type=e avant A=3.3621e-4932 B=1.18973e+4932 après A=1.18973e+4932 B=0
    swap+ type=e avant A=1.18973e+4932 B=3.3621e-4932 après A=0 B=1.18973e+4932

    Et le second swap ne marche pas sur les flottants.