IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Erreur de compilation ou exécution Builder 64bits: Passage d'un double en int [Langage/Algorithme]


Sujet :

C++Builder

  1. #1
    Membre habitué
    Homme Profil pro
    Chercheur génie électrique
    Inscrit en
    Mai 2002
    Messages
    263
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur génie électrique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 263
    Points : 136
    Points
    136
    Par défaut Erreur de compilation ou exécution Builder 64bits: Passage d'un double en int
    Bonjour à tous,
    je suis en train de migrer une app C++Builder 32bits vers Sydney 10.4 en 64bits.
    Voici un cas de plantage de compilation ou d'exécution lors du passage d'une valeur en doube vers int:
    Voici le code ci-dessous:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double tmpVal64 = 1E100;
    int kk; 
    kk = tmpVal64;  // ou kk = (int) tmpVal64;
    Ce code a été testé sous 32bits, tout est OK (bien sure que la valeur kk n'est pas correct, mais on s'enfiche car une valeur 1e100 est une exception, au moins pas de plantage).
    Dans le système Sydney 10.4, 64bits, ce sera un plantage!
    Mon code n'est pas très professionnel, mais il tourne OK depuis 15 ans.
    Pour le moment, je fais une limite de valeur tmpVal < 1e9 (max d'un int).
    Est-ce qu'il y a d'autre méthode professionnelle permettant d'éviter ce plantage sous 64 bits, svp.
    Merci d'avance de votre aide.
    Xavier

  2. #2
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    salut
    en utilisant la gestion des exceptions avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    try
    {
     
    // ton code pouvant provoquer des exceptions ici
     
     
    }
    catch (Exception&E)
    {
     
    // traitement des exceptions Ici
     
    }
    par ailleurs un nouveau type de données est apparu avec les version 64 bits
    ils s'agit de

    typedef long long Int64;

    plage de donnée -2^63 à 2^63-1.

    aide ici

    tu peux utiliser également la librairie boost exemple ici



    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  3. #3
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    double tmpVal64 = 1E100;
    int kk = tmpVal64;
    est un "undefined behavior" donc le compilateur peut l'accepter ou pas. Et à l'exécution tout est possible, ça peut faire fumer le PC, éteindre la tour Eiffel ou autre, en tout cas aucune exception n'est prévue pour cela. Si le compilateur l'acceptait avant on ne peut pas le blâmer, mais la refuser désormais est tout aussi correct.

    Quand au fait que ça ne plantait pas c'était donc un bug enfoui. Pour éviter le plantage, il ne faut pas faire cela! Tous les "undefined behavior" ont un comportement aléatoire, on ne peut donc pas en attendre un comportement.

    A noter que la norme a évolué, ainsi la ligne suivante est désormais interdite à la compilation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    constexpr int kk = 1e100; // conversion impossible d'une constante
    Un autre exemple de code qui a souvent marché mais qui peut aussi planter un programme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    double  a;
    double  b = a; // copie d'une donnée non initialisée

  4. #4
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    J’aime particulièrement ta citation

    est un "undefined behavior" donc le compilateur peut l'accepter ou pas. Et à l'exécution tout est possible, ça peut faire fumer le PC, éteindre la tour Eiffel ou autre, en tout cas aucune exception n'est prévue pour cela. Si le compilateur l'acceptait avant on ne peut pas le blâmer, mais la refuser désormais est tout aussi correct.
    Il est à noter que ce n’est pas parce qu’un code a fonctionné qu’il fonctionnera toujours, la plus part des compilos sont mis à jour avec les nouvelles évolutions des languages et également corrigés.

    Bien cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  5. #5
    Membre habitué
    Homme Profil pro
    Chercheur génie électrique
    Inscrit en
    Mai 2002
    Messages
    263
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur génie électrique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 263
    Points : 136
    Points
    136
    Par défaut
    Merci tous les deux!
    J'apprends des choses sans arrêt.
    Bien cordialement
    Xavier

  6. #6
    Membre habitué
    Homme Profil pro
    Chercheur génie électrique
    Inscrit en
    Mai 2002
    Messages
    263
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur génie électrique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 263
    Points : 136
    Points
    136
    Par défaut
    J'ai fait une fonction très artisanale:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int DoubleToInt32(double inValue)
    {
    	if (inValue < -1E9) return(-1E9);
     	else 
            if (inValue > 1E9) return (1E9);
            else
    	return ((int) inValue);
    }

  7. #7
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    On peut créer un Int32 qui va saturer à ses limites si on lui en demande un peu trop.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    class SafeInt32 {
    public:
    	template<typename T, std::enable_if_t<
    		   std::is_arithmetic_v<T>
    		&& (   std::numeric_limits<T>::max() > std::numeric_limits<std::int32_t>::max()
    		    || std::numeric_limits<T>::min() < std::numeric_limits<std::int32_t>::min() )
    		,int> =0>
    	constexpr SafeInt32( T x )noexcept {
    		if constexpr ( std::is_unsigned_v<T> ) { // c'est juste pour éviter un warning comparaison signed/unsigned
    			if ( x > static_cast<std::uint32_t>(std::numeric_limits<std::int32_t>::max()) )
    				val_ = std::numeric_limits<std::int32_t>::max();
    			else
    				val_ = static_cast<std::int32_t>(x);
    		}
    		else { // on se limite à ce qui tiens dans dans les bornes
    			if ( x > std::numeric_limits<std::int32_t>::max() )
    				val_ = std::numeric_limits<std::int32_t>::max();
    			else if ( x < std::numeric_limits<std::int32_t>::min() )
    				val_ = std::numeric_limits<std::int32_t>::min();
    			else
    				val_ = static_cast<std::int32_t>(x);
    		}
    	}
     
    	template<typename T, std::enable_if_t<
    		   std::is_arithmetic_v<T>
    		&& std::numeric_limits<T>::max() <= std::numeric_limits<std::int32_t>::max()
    		&& std::numeric_limits<T>::min() >= std::numeric_limits<std::int32_t>::min()
    		,int> =0>
    	constexpr SafeInt32( T x )noexcept : val_{static_cast<std::int32_t>(x)} {
    	}
     
    	constexpr SafeInt32()noexcept = default;
     
    	constexpr operator std::int32_t()const noexcept {
    		return  val_;
    	}
    private:
    	std::int32_t  val_{};
    };
    Ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SafeInt32  a{1e100};  // => 2147483647
    SafeInt32  b{-0xffffffffffffLL};  // => -2147483648

  8. #8
    Membre habitué
    Homme Profil pro
    Chercheur génie électrique
    Inscrit en
    Mai 2002
    Messages
    263
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur génie électrique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 263
    Points : 136
    Points
    136
    Par défaut
    Merci dalfab,
    je vais essaie d'implanter ta classe car elle est beaucoup plus complète que ma fonction artisanale.
    Cordialement
    Xavier

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Compilation Composants C++Builder 64bits
    Par phpdev dans le forum EDI
    Réponses: 1
    Dernier message: 15/02/2021, 16h28
  2. Erreur de compilation et erreur d'exécution
    Par une_tite_question dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 10/09/2008, 11h28
  3. Réponses: 5
    Dernier message: 18/07/2008, 09h18
  4. Réponses: 4
    Dernier message: 07/05/2008, 05h14
  5. Réponses: 2
    Dernier message: 23/09/2003, 14h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo