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++ Discussion :

Arrondir un entier le plus proche possible de sa dizaine..?


Sujet :

C++

  1. #1
    Membre averti
    Homme Profil pro
    Cimentage
    Inscrit en
    Septembre 2014
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Cimentage
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Septembre 2014
    Messages : 44
    Par défaut Arrondir un entier le plus proche possible de sa dizaine..?
    Bonjour / Bonsoir à tous !

    Alors voilà, j'aimerais que vous m'expliquiez comment je pourrais faire pour arrondir un nombre / chiffre ENTIER de sa dizaine la plus proche ?

    Exemple :

    Si je mets ma variable NUMBER à 4, que le programme m'affiche 0 ( car 4 est plus proche de 0 que de 10 ) et inversement, si je mets ma variable NUMBER à 6 ( par exemple ), que le programme m'affiche 10..

    Et ce, pour TOUTES les dizaines entre 0 et 100, donc si je mets ma variable NUMBER à 87, je veux que le résultat 90 s'affiche.
    Bref, je pense avoir été clair :-)

    Merci à vous pour l'aide car je n'ai trouvé sur google que des explications pour des chiffres à virgules... ! :-)

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 491
    Billets dans le blog
    1
    Par défaut
    Diviser par 10.0f pour obtenir un float, std::round pour arrondir, multiplier par 10 et enfin récupérer un entier ?

  3. #3
    Invité
    Invité(e)
    Par défaut _ _ _
    Bonsoir,
    Je propose sa:
    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
     
    #include <cmath>
     
    long arrondir( long nombre/*   Nombre a arrondir    */, unsigned k/* 1 pour dizaine, 2 pour ...*/)    {
        if( k > 0)    {
            int signe = 1;
            if( nombre < 0)    {
                nombre = -nombre;
                signe = -1;
            }
            unsigned long p = std::pow( 10, k);
            /*    Arrondir a droite    */
            if( ( nombre % p) >= p/2)    {
                return signe * ( ( nombre/p)*p + p);
            }
            /*    Arrondir a gauche    */
            return signe * ( nombre / p)*p;
        }
        return nombre;
    }
    C'est un peu plus compliquer que ce que t'attendais, mais si elle s’exécute comme je le veut bien, tu pourras arrondir au-dela de la dizaine, enfin j'espère.
    En plus elle devrait supporter les entiers négatif enfin j'espère

    Si quelqu'un a une proposition d’amélioration ou un autre code je suis prenant bien sur.

  4. #4
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 510
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 510
    Par défaut
    @Ratator :
    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
    #include <iostream>
    #include <cassert>
     
    int arrondir(int entier, int precision)
    {
        assert(precision > 0);
        const int offset = (entier >= 0) ? precision/2 : -precision/2;
        return ( (entier+offset) / precision ) * precision;
    }
     
    int main() {
        std::cout << "arrondir(-36, 10)   : " << arrondir(-36, 10)   << '\n'
                  << "arrondir(-25, 10)   : " << arrondir(-25, 10)   << '\n'
                  << "arrondir(-14, 10)   : " << arrondir(-14, 10)   << '\n'
                  << "arrondir(104, 10)   : " << arrondir(104, 10)   << '\n'
                  << "arrondir(225, 10)   : " << arrondir(225, 10)   << '\n'
                  << "arrondir(346, 10)   : " << arrondir(346, 10)   << '\n'
                  << "arrondir(2547, 100) : " << arrondir(2547, 100) << '\n'
                  << "arrondir(121, 25)   : " << arrondir(121, 25)   << '\n'
                  << "arrondir(-18, 5)    : " << arrondir(-18, 5)    << '\n'
                  << "arrondir(-17, 5)    : " << arrondir(-17, 5);
        return 0;
    }
    Sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    arrondir(-36, 10)   : -40
    arrondir(-25, 10)   : -30
    arrondir(-14, 10)   : -10
    arrondir(104, 10)   : 100
    arrondir(225, 10)   : 230
    arrondir(346, 10)   : 350
    arrondir(2547, 100) : 2500
    arrondir(121, 25)   : 125
    arrondir(-18, 5)    : -20
    arrondir(-17, 5)    : -15

  5. #5
    Invité
    Invité(e)
    Par défaut _ _ _
    Merci pour le poste, sa m'as pas permis de me renseigner un peu sur <cassert>.
    Mais il y-a quelques choses que je ne comprends pas pourquoi l'avez-vous utiliser?
    Sa me dépasse, puisque lorsque precision est <= 0 sa arrête le programme.
    Dernière modification par LittleWhite ; 14/11/2016 à 20h45. Motif: Pas besoin de citer l'intégralité du message précédent

  6. #6
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 510
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 510
    Par défaut
    Citation Envoyé par Ratator Voir le message
    pourquoi l'avez-vous utiliser?
    Sa me dépasse, puisque lorsque precision est <= 0 sa arrête le programme.
    La macro assert ne peut avoir d'effet que si la macro NDEBUG n'est pas définie. On utilise assert pour détecter les erreurs de programmation.
    Dans cet exemple, j'impose à l'appelant que precision > 0. S'il a un entier precision qui peut être négatif, alors il est obligé de faire un contrôle explicite, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if(precision > 0)
    {
        resultat = arrondir(entier, precision);
    } else {
        // Afficher un message qui demande à l'utilisateur de
        // choisir une précision strictement positive.
    }
    S'il oublie de le faire, alors c'est détecté comme étant une erreur de programmation.

    En général, on compile le programme dans deux modes différents :
    • Le mode Debug qui permet d'analyser facilement les bogues au moment où le programme est développé. Il permet d'exécuter le programme ligne par ligne. La macro NDEBUG n'est pas définie. Quand une erreur de programmation est trouvée par assert, le programme s'arrête tout de suite et le développeur peut visualiser l'état du programme. Si on n'avait pas arrêté le programme, le programme aurait dysfonctionné plus tard, à un endroit plus éloigné de l'origine de l'erreur. Analyser l'erreur aurait alors été plus long.
    • Le mode Release qui est le mode utilisé pour déployer le logiciel. Le compilateur peut faire des optimisations agressives en changeant les instructions et leur ordre. La macro NDEBUG est définie pour désactiver les assert.


    En mode Release, il y a plusieurs manières de gérer les erreurs de programmation.
    1. Ne pas les gérer. C'est ce que j'ai fait :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      int arrondir(int entier, int precision)
      {
          assert(precision > 0);
          const int offset = (entier >= 0) ? precision/2 : -precision/2;
          return ( (entier+offset) / precision ) * precision;
      }
      Quand NDEBUG est définie, mon code se comporte n'importe comment si precision <= 0. L'appelant n'avait qu'à faire attention.
    2. Les réparer sur place.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      int arrondir(int entier, int precision)
      {
          assert(precision > 0);
          if(precision > 0) {
              const int offset = (entier >= 0) ? precision/2 : -precision/2;
              return ( (entier+offset) / precision ) * precision;
          } else {
              return entier;
          }
      }
      C'est un tout petit peu moins performant, car on a un if en plus, mais c'est plus sécurisé. L'inconvénient est que cela a tendance à cacher partiellement l'erreur de programmation. Donc elle risque de traîner dans le programme plus longtemps.
    3. Lever une exception.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      #include <stdexcept>
       
      int arrondir(int entier, int precision)
      {
          assert(precision > 0);
          if(precision <= 0)
              throw std::domain_error("arrondir : la precision (" + std::to_string(precision) + ") aurait du etre > 0.");
          const int offset = (entier >= 0) ? precision/2 : -precision/2;
          return ( (entier+offset) / precision ) * precision;
      }
      C'est ma préférée. Mais peut-être que FrostfallDelphi et vous n'avez pas encore vu les exceptions.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Quand NDEBUG est définie, mon code se comporte n'importe comment si precision <= 0. L'appelant n'avait qu'à faire attention.
    Bien fait pour lui .

    Mais peut-être que FrostfallDelphi et vous n'avez pas encore vu les exceptions.
    Effectivement je n'ai vu que comment gérer les exceptions avec , mais j'ai pas encore vue comment générer des exceptions, je n'en voyais pas l'utilité, c'est plus le cas maintenant grâce à vous.
    Vous connaissez un cours/tutoriel assez bien fait sur la gestion des erreurs?

  8. #8
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 510
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 510
    Par défaut
    Citation Envoyé par Ratator Voir le message
    Vous connaissez un cours/tutoriel assez bien fait sur la gestion des erreurs?
    Dans l'ensemble, je trouve la page suivante plutôt bien faite :
    https://isocpp.org/wiki/faq/exceptions

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 144
    Billets dans le blog
    4
    Par défaut
    Technique du round des flottants appliqué aux entiers : +5 / 10 : int arrondiDizaine(int i) { return (i+5) / 10; }
    Plutôt qu'un assert, pourquoi ne pas avoir precision en unsigned int ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Invité
    Invité(e)
    Par défaut
    J'aurais préféré que se soit en Français.

    J'ai l'impression que plus j'apprends/découvre des nouvelles choses et plus il me reste des choses a découvrir, plus qu'avant.

    C'est juste moi ou est ce le cas pour tout le monde?

  11. #11
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 491
    Billets dans le blog
    1
    Par défaut
    C'est tout le monde normalement. Ceux qui disent le contraire sont des menteurs. Il y a d'ailleurs une citation plutôt célèbre à ce sujet.

  12. #12
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 510
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 510
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Plutôt qu'un assert, pourquoi ne pas avoir precision en unsigned int ?
    Avec un unsigned, il faudrait quand même un assert pour exclure le cas precision == 0.
    J'ai hésité à mettre un unsigned. Mais, de toutes façons, il aurait fallu convertir en int :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int arrondir(int entier, unsigned precision)
    {
        assert(precision > 0);
        if(precision == 0)
            throw std::domain_error("arrondir : la precision (" + std::to_string(precision) + "aurait du etre > 0.");
        const int intPrecision = static_cast<int>(precision);
        const int offset = (entier >= 0) ? intPrecision/2 : -intPrecision/2;
        return ( (entier+offset) / intPrecision ) * intPrecision;
    }
    Sans la conversion en int, (entier+offset) / precision aurait été non signé et le résultat aurait été erroné.
    Du coup, j'ai préféré le type int.

Discussions similaires

  1. [Débutant] arrondir au nombre le plus proche d'une liste
    Par Invité dans le forum MATLAB
    Réponses: 1
    Dernier message: 30/04/2015, 04h46
  2. [XL-2013] Rechercher le nombre entier le plus proche
    Par C'dric dans le forum Excel
    Réponses: 7
    Dernier message: 05/02/2014, 11h30
  3. Arrondi au nombre entier le plus proche
    Par heliy dans le forum SAP
    Réponses: 4
    Dernier message: 21/04/2011, 08h44
  4. Arrondir à la cinquantaine la plus proche
    Par vitch8 dans le forum Langage
    Réponses: 9
    Dernier message: 16/04/2009, 14h26
  5. Réponses: 1
    Dernier message: 17/12/2008, 19h00

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