Partage
  • Partager sur Facebook
  • Partager sur Twitter

Calcul de prix

Fonctions affine en C

Sujet résolu
    13 août 2019 à 9:39:18

    Bonjour,

    Je suis débutant en C et je me suis lancé dans un programme de calcul automatique de prix avec marge : 

    - Le principe est que je veux appliquer une marge sur mes tarifs mais de façon dégressive; ainsi la marge doit être plus importante pour un tarif bas et moins importante pour un tarif haut. Pour l'instant j'ai choisi de procéder comme ceci pour le calcul :

    if (prixBase < 50)
        {
            prixMarge = prixBase / 0.40;
        }
        else if (prixBase >= 50 && prixBase <= 99)
        {
            prixMarge = prixBase / 0.45;
        }
        else if (prixBase >= 100 && prixBase <= 149)
        {
            prixMarge = prixBase / 0.50;
        }
        else if (prixBase >= 150 && prixBase <= 199)
        {
            prixMarge = prixBase / 0.55;
        }
        else if (prixBase >= 200  && prixBase <= 299)
        {
            prixMarge = prixBase / 0.60;
        }
        else if (prixBase >= 300  && prixBase <= 399)
        {
            prixMarge = prixBase / 0.65;
        }
        else if (prixBase >= 400  && prixBase <= 499)
        {
            prixMarge = prixBase / 0.70;
        }
        else if (prixBase >= 500  && prixBase <= 599)
        {
            prixMarge = prixBase / 0.75;
        }
        else
        {
            prixMarge = prixBase / 0.80;
        }


    Cette façon de faire me pose un problème : il y a un décalage important entre chaque tranche ; si je réduis l'écart entre les tranches, je risque de faire une forêt de ifs.

    On m'a conseillé de créer une fonction affine mais je n'ai aucune idée de comment la traduire en C. Je cherche donc un moyen de le faire, ou, le cas échéant, un moyen de solutionner ce problème d'une autre manière.

    Je vous remercie d'avance !

    -
    Edité par AugustinDebureaux 13 août 2019 à 9:40:33

    • Partager sur Facebook
    • Partager sur Twitter
      13 août 2019 à 10:30:46

      Bonjour ! Apparemment c'est surtout un problème d'algorithme.

      Je propose la méthode suivante :

      − Tu calcules la division entière prixBase/50 (par exemple si prixBase = 170, ça donne 3.

      − Cette valeur est l'indice d'un tableau qui contient le nombre à diviser.

      Avec les valeurs de ton exemple, ce serait : {0.40, 0.45, 0.50, 0.55, 0.60, 0.60, 0.65, 0.65, 0.70, 0.70, 0.75, 0.75}.

      Le test serait alors plus simple, quelque chose comme :

      double diviseurMarge ;
      double diviseur[11] = {0.40, 0.45, 0.50, 0.55, 0.60, 0.60, 0.65, 0.65, 0.70, 0.70, 0.75, 0.75} ;
      if (prixBase < 600)  // (il faudrait s'assurer que prixBase est positif...)
          diviseurMarge = diviseur[prixBase/50] ;
      else
          diviseurMarge = 0.80 ;
      prixMarge = prixBase / diviseurMarge ;

      (Je n'ai pas essayé, c'est juste pour donner une idée.)

      -
      Edité par robun 13 août 2019 à 10:32:48

      • Partager sur Facebook
      • Partager sur Twitter
        13 août 2019 à 12:38:49

        Salut,

        Sans table : on ajoute ici 0.05 par tranche de 50, donc diviseurMarge vaut : 0.40 + (int)(prixBase/50) * 0.05;

        Donc une forme ax+b, d'où la suggestion d'une fonction affine j'imagine.

        à completer par le code fourni par Robun pour les limites.

        Bonne continuation.

        • Partager sur Facebook
        • Partager sur Twitter

        Bonhomme !! | Jeu de plateforme : Prototype.

          13 août 2019 à 17:57:07

          Merci pour vos réponses ! j'y vois beaucoup plus clair :)
          • Partager sur Facebook
          • Partager sur Twitter
            13 août 2019 à 19:35:23

            Hello,

            Sans calcul, avec deux tableaux:

            #include <stdio.h>
            
            int main(void) {
            
            	int pb[]={ 599, 499, 399, 299, 199, 149, 99,  50};
            	float r[]={ .8, .75,  .7, .65,  .6, .55, .5, .45, .4};
            	
            	int prix_base=212;    // exemple
            	
            	int i;
            	for(i=0;i<sizeof(pb)/sizeof(pb[0]);i++)
            		if(prix_base>pb[i])
            			break;
            
            	printf("prix_base=%d, r[%d]=%.2f, prix_marge=%.2f",
            		prix_base,i,r[i],(float)(prix_base*r[i]));
            	
            	return(0);
            }
            	
            

            -
            Edité par edgarjacobs 13 août 2019 à 20:36:01

            • Partager sur Facebook
            • Partager sur Twitter

            On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

              14 août 2019 à 16:34:39

              edgarjacobs a écrit:

              Hello,

              Sans calcul, avec deux tableaux:

              #include <stdio.h>
              
              int main(void) {
              
              	int pb[]={ 599, 499, 399, 299, 199, 149, 99,  50};
              	float r[]={ .8, .75,  .7, .65,  .6, .55, .5, .45, .4};
              	
              	int prix_base=212;    // exemple
              	
              	int i;
              	for(i=0;i<sizeof(pb)/sizeof(pb[0]);i++)
              		if(prix_base>pb[i])
              			break;
              
              	printf("prix_base=%d, r[%d]=%.2f, prix_marge=%.2f",
              		prix_base,i,r[i],(float)(prix_base*r[i]));
              	
              	return(0);
              }
              	
              

              -
              Edité par edgarjacobs il y a environ 19 heures

              Merci pour ta réponse, j'ai finalement utilisé la méthode de Robun (en modifiant les valeurs) comme suit :

                  // Calcul du tarif avec la marge
                  double diviseur[40] = { 0.30, 0.40, 0.45, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.735, 0.740, 0.745, 0.750, 0.755, 0.760, 0.765, 0.770, 0.775, 0.780, 0.785, 0.790, 0.795 };
              
                  if (prixBase < 500)
                  {
                      div = prixBase / 12.5;
                      diviseurMarge = diviseur[div];
                  }
                  else
                  {
                      diviseurMarge = 0.80;
                  }
              
                  prixMarge = prixBase / diviseurMarge;


              Mais je dois avouer que ta méthode est intéressante aussi, je la garde de côté pour essayer plus tard :)

              -
              Edité par AugustinDebureaux 14 août 2019 à 16:38:19

              • Partager sur Facebook
              • Partager sur Twitter
                14 août 2019 à 18:53:33

                L'utilisation de tables à son charme (et son intérêt, notamment de pouvoir charger les coefficients depuis un fichier), mais pour éliminer la forêt de if, il y a une solution, l'utilisation de l'expression conditionnelle "ternaire".

                float taux = 
                      (prixBase <  50) ? 0.40
                    : (prixBase < 100) ? 0.45
                    : (prixBase < 150) ? 0.50
                    : (prixBase < 200) ? 0.55
                    : (prixBase < 300) ? 0.60
                    : (prixBase < 400) ? 0.65
                    : (prixBase < 500) ? 0.70
                    : (prixBase < 600) ? 0.75    
                    :                    0.80;
                
                prixMarge = prixBase / taux;

                L'avantage, c'est la lisibilité : même le stagiaire de la compta peut vérifier que ce bout de code correspond au barême qui est sur un papier.


                ---

                Pour l'utilisation d'un tableau de coefficients par tranche, attention, elles n'ont pas la même largeur : 50 pour les 4 premières, 100 pour les suivantes.

                Une idée est de dire qu'une tranche de 100, c'est deux tranches de 50. Ce qui donne les coefficients

                float tauxTranche[] = { 
                                 0.40, 
                                 0.50, 
                                 0.55,
                                 0.60, 0.60,
                                 0.65, 0.65,
                                 0.70, 0.70,
                                 0.75, 0.75 }; 
                

                puis

                int numeroTranche = prixBase / 50;

                et enfin

                float taux = (numeroTranche < 11) ? tauxTranche[numeroTranche] 
                                                  : 0.8;
                prixMarge = prixBase / taux;
                





                -
                Edité par michelbillaud 14 août 2019 à 19:12:42

                • Partager sur Facebook
                • Partager sur Twitter
                  14 août 2019 à 21:34:28

                  Merci michelbillaud, c'est très clair, je comprend beaucoup mieux grâce à tes explications !

                  Un seul point sur lequel je voudrais revenir : je voulais au départ que chaque 'prixBase' ait sont 'tauxMarge' à lui, de sorte que l'on ait pas de gros décalage entre les tranches. Enfaite le 'prixBase' correspond à mon prix d'achat et le 'prixMarge' à mon prix de vente, donc un client ne devrait pas payer moins cher pour un produit que j'achète plus cher.

                  Je m'explique :

                  - Un 'prixBase' à 599 euros aura un 'tauxMarge' à 0.75 soit 599 / 0.75 = 798 euros

                  - Un 'prixBase' à 601 euros aura un 'tauxMarge' à 0.80 soit 601 / 0.80 =  751 euros

                  Dans le bout de code que j'ai posté un peu plus haut, j'ai tenté de régler ce problème en mettant des taux de marge avec de gros écarts au début et puis de plus en plus serrés.

                  michelbillaud a écrit:

                  L'utilisation de tables à son charme (et son intérêt, notamment de pouvoir charger les coefficients depuis un fichier), mais pour éliminer la forêt de if, il y a une solution, l'utilisation de l'expression conditionnelle "ternaire".

                  float taux = 
                        (prixBase <  50) ? 0.40
                      : (prixBase < 100) ? 0.45
                      : (prixBase < 150) ? 0.50
                      : (prixBase < 200) ? 0.55
                      : (prixBase < 300) ? 0.60
                      : (prixBase < 400) ? 0.65
                      : (prixBase < 500) ? 0.70
                      : (prixBase < 600) ? 0.75    
                      :                    0.80;
                  
                  prixMarge = prixBase / taux;

                  L'avantage, c'est la lisibilité : même le stagiaire de la compta peut vérifier que ce bout de code correspond au barême qui est sur un papier.


                  ---

                  Pour l'utilisation d'un tableau de coefficients par tranche, attention, elles n'ont pas la même largeur : 50 pour les 4 premières, 100 pour les suivantes.

                  Une idée est de dire qu'une tranche de 100, c'est deux tranches de 50. Ce qui donne les coefficients

                  float tauxTranche[] = { 
                                   0.40, 
                                   0.50, 
                                   0.55,
                                   0.60, 0.60,
                                   0.65, 0.65,
                                   0.70, 0.70,
                                   0.75, 0.75 }; 
                  

                  puis

                  int numeroTranche = prixBase / 50;

                  et enfin

                  float taux = (numeroTranche < 11) ? tauxTranche[numeroTranche] 
                                                    : 0.8;
                  prixMarge = prixBase / taux;
                  





                  -
                  Edité par michelbillaud il y a environ 1 heure



                  • Partager sur Facebook
                  • Partager sur Twitter
                    14 août 2019 à 23:30:36

                    AugustinDebureaux a écrit:

                    Merci michelbillaud, c'est très clair, je comprend beaucoup mieux grâce à tes explications !

                    Un seul point sur lequel je voudrais revenir : je voulais au départ que chaque 'prixBase' ait sont 'tauxMarge' à lui, de sorte que l'on ait pas de gros décalage entre les tranches. Enfaite le 'prixBase' correspond à mon prix d'achat et le 'prixMarge' à mon prix de vente, donc un client ne devrait pas payer moins cher pour un produit que j'achète plus cher.

                    Je m'explique :

                    - Un 'prixBase' à 599 euros aura un 'tauxMarge' à 0.75 soit 599 / 0.75 = 798 euros

                    - Un 'prixBase' à 601 euros aura un 'tauxMarge' à 0.80 soit 601 / 0.80 =  751 euros

                    Dans le bout de code que j'ai posté un peu plus haut, j'ai tenté de régler ce problème en mettant des taux de marge avec de gros écarts au début et puis de plus en plus serrés.

                    Dans ce cas c'est une autre histoire. De la façon dont c'était posé, c'était un problème de programmation à partir d'un système de barême donné.

                    En fait c'est une histoire de définition du système de barême, de façon à avoir une fonction PrixBase/PrixMarge continue, et décroissante.

                    C'est effectivement une histoire de droite affine par morceaux. Ca revient aux taux marginaux des tranches d'imposition : le taux d'une tranche s'applique à ce qui dépasse la valeur de début de tranche.



                    • Partager sur Facebook
                    • Partager sur Twitter

                    Calcul de prix

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown