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

Langage PHP Discussion :

Problème de type ? [PHP 5.5]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Avatar de Stef.web
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2003
    Messages : 104
    Par défaut Problème de type ?
    Hello,

    j'ai fait le plein de capsule de café, servez vous.
    Je me prends la tête avec un truc en php où le problème d'un typage de données mais je trouve pas où

    voila le code partiel :


    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
    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
        if (file_exists($fichier)) {
            echo "La taille du fichier est de :" . filesize($fichier) . " octets <BR><BR>";
            $ligne = 1; // compteur de ligne
            $fic = fopen($fichier, "a+");
            while ($tab = fgetcsv($fic, 0, ';', '"')) {
                $champs = count($tab); //nombre de champ dans la ligne en question
                $ligne ++;
                //affichage de chaque champ de la ligne en question
                if ($tab[$vente["Statut"]] == $statut) {
                    // Facture OK
                    // détail
                    // COMPTE
                    echo $type_reglement[$tab[$vente["Mode paiement"]]] . ";";
                    // LIBELLE
                    $libelle = strtoupper($tab[$vente["Nom"]] . " " .
                            $tab[$vente["Prenom"]] . " - " .
                            $tab[$vente["Num_commande"]]);
     
                    echo $libelle . ";";
                    //DEBIT / CREDIT
                    echo $tab[$vente["Total commande TTC"]] . ";0.00" . "<br />";
     
                    // écriture TVA
                    if ($tab[$tva["20"]] != 0) {
                        echo "445668;" . $libelle . ";0.00;" . $tab[$tva["20"]] . "<BR>";
                    }
                    if ($tab[$tva["10"]] != 0) {
                        echo "445666;" . $libelle . ";0.00;" . $tab[$tva["10"]] . "<BR>";
                    }
                    if ($tab[$tva["5.5"]] != 0) {
                        echo "445665;" . $libelle . ";0.00;" . $tab[$tva["5.5"]] . "<BR>";
                    }
     
                    // PORT
                    if ($tab[$vente["Frais livraison HT"]] != 0) {
                        echo "6242xxx;" . $libelle . ";0.00;" . $tab[$vente["Frais livraison HT"]] . "<BR>";
                    }
     
                    // COMPTE 700
                    echo "700;" . $libelle . ";0.00;" . $tab[$vente["Sous-total HT"]] . "<BR>";
     
                    // PERTE OU PROFIT
                    $pp = ($tab[$vente["Total commande TTC"]] - ($tab[$tva["20"]] + $tab[$tva["10"]] + $tab[$tva["5.5"]] + $tab[$vente["Frais livraison HT"]] + $tab[$vente["Sous-total HT"]]));
                    if ($pp != 0) {
                        if ($pp > 0)
                            echo "758;" . $libelle . ";0.00;" . $pp . "<BR>";
                        else
                            echo "658;" . $libelle . ";" . $pp . ";0.00" . "<BR>";
                        print_r($tab);
                        print_r(" PP=".$pp."<BR>");
                        $pp = $tab[$tva["20"]] + $tab[$tva["10"]] + $tab[$tva["5.5"]] + $tab[$vente["Frais livraison HT"]] + $tab[$vente["Sous-total HT"]];
                        print_r(" PP=".$pp."<BR>");
                        print_r(" PPmoins=".($tab[$vente["Total commande TTC"]]-$pp)."<BR>");
                        //print_r(" PP=".($tab[$tva["20"]] + $tab[$tva["10"]] + $tab[$tva["5.5"]] + $tab[$vente["Frais livraison HT"]] + $tab[$vente["Sous-total HT"]]));
                        echo " Total TTC=".$tab[$vente["Total commande TTC"]] . "<BR>";
                        print_r (" 20%=".$tab[$tva["20"]]) . "<BR>";
                        print_r (" 10%=".$tab[$tva["10"]]) . "<BR>";
                        print_r (" 5.5%=".$tab[$tva["5.5"]]) . "<BR>";
                        echo " Livraison HT=".$tab[$vente["Frais livraison HT"]] . "<BR>";
                        echo " ssTotal HT=".$tab[$vente["Sous-total HT"]] . "<BR>";
                        echo "<BR>";
     
                    }
     
     
                    echo "<BR>";
                }
            }
        }
        ?>
    et voila le résultat

    411CLIENTPP;VENET PHILIPPE - 59;31.62;0.00
    445668;VENET PHILIPPE - 59;0.00;5.27
    6242xxx;VENET PHILIPPE - 59;0.00;6.35
    700;VENET PHILIPPE - 59;0.00;20.00
    758;VENET PHILIPPE - 59;0.00;3.5527136788005E-15
    Array ( [0] => 59 [1] => 56 [2] => 11-03-2014 [3] => [4] => 78 [5] => philippe [6] => *** [7] => **@*fr [8] => 11-03-2014 [9] => En cours de livraison [10] => 20.00 [11] => 24.00 [12] => 6.35 [13] => 7.62 [14] => Colissimo France sans signature [15] => 26.35 [16] => 31.62 [17] => PayPal [18] => 2 [19] => 12-03-2014 [20] => € Euro [21] => [22] => [23] => [24] => Payment accepted. [25] => philippe [26] => *** [27] => [28] => 6, avenue [29] => [30] => 69000 [31] => corbas [32] => France [33] => [34] => 0615****** [35] => 5.27 [36] => [37] => [38] => ) PP=3.5527136788005E-15
    PP=31.62
    PPmoins=3.5527136788005E-15
    Total TTC=31.62
    20%=5.27 10%= 5.5%= Livraison HT=6.35
    ssTotal HT=20.00


    411CLIENTCB;ELISABETE DE LIMA VAZ - 60;90.00;0.00
    445668;ELISABETE DE LIMA VAZ - 60;0.00;15.00
    700;ELISABETE DE LIMA VAZ - 60;0.00;75.00

    411CLIENTCB;GALLIGARI MURIEL - 61;90.00;0.00
    445668;GALLIGARI MURIEL - 61;0.00;15.00
    700;GALLIGARI MURIEL - 61;0.00;75.00

    411CLIENTPP;VOYER DANIEL - 62;180.00;0.00
    445668;VOYER DANIEL - 62;0.00;30.00
    700;VOYER DANIEL - 62;0.00;150.00

    411CLIENTPP;PESSAH FRANCOIS - 63;90.00;0.00
    445668;PESSAH FRANCOIS - 63;0.00;15.00
    700;PESSAH FRANCOIS - 63;0.00;75.00
    Le soucis est au niveau du calcul de $pp ( Pertes et Profits )
    c'est qu'un squelette d'une moulinette d'où les print_r et echo à tout va!

    je comprends pas comment peux trouver
    31.62-31.62 = 3.5527136788005E-15????

    mais pas sur toutes les lignes ...

    Merci par avance.

    Amicalement

    Stéf

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    c'est un problème d'arrondi lors des calculs avec décimales.


  3. #3
    Membre confirmé
    Avatar de Stef.web
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    104
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2003
    Messages : 104
    Par défaut
    Merci de ta réponse, mais ce que je ne comprends pas, c'est qu'il s'agisse de simple addition/soustraction issu d'un import CSV 2 décimales ...
    Pour être obligé de passer par un round?
    Ca doit venir de php, mais je ne me l'explique pas !

  4. #4
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,

    ce n'est pas un problème d'arrondi mais de représentation interne d'un nombre réel.
    Tu vas trouver sur le net des cours entiers concernant cette problématique.

    Voici comment la contourner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ht  = 12.34;
    $tva = 10;
    $ttc = $ht * (1+$tva/100);  // $ttc = 13.574
     
    echo $ttc, '<br>';
     
    $b = 13.574;
     
    echo $ttc-$b, '<br>';   // 1.7763568394003E-15
     
    echo bcsub($ttc, $b);   // zéro
    Un peu de doc par ici

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    ...représentation interne d'un nombre réel...
    Oui, c'est bien ce à quoi je pensais (mais je ne me souvenais plus du terme)
    Cela dit, on n'est pas ici dans le cas de "nombres de grande taille".

    Voir aussi : Nombres décimaux (lire l'avertissement concernant la précision des nombres décimaux)

    Les nombres décimaux ont une précision limitée.
    Même s'ils dépendent du système, PHP utilise le format de précision des décimaux IEEE 754, qui donnera une erreur maximale relative de l'ordre de 1.11e-16 (dûe aux arrondis).
    Les opérations arithmétiques non-élémentaires peuvent donner des erreurs plus importantes et bien sûr les erreurs doivent être prises en compte lorsque plusieurs opérations sont liées.

    [...]

  6. #6
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    @jreaux62
    Effectivement, on n'est pas dans le cas des nombres de grande taille mais la bibliothèque BCMath te permet de manipuler des décimaux pleine précision sans te préoccuper de ce léger "détail"

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

Discussions similaires

  1. [ tinyint et char ] problème de type
    Par shirya dans le forum Installation
    Réponses: 3
    Dernier message: 05/11/2005, 08h08
  2. [debutant] problème avec type à utiliser
    Par mlequim dans le forum Autres SGBD
    Réponses: 2
    Dernier message: 15/07/2005, 17h08
  3. Problème de type chaîne
    Par champijulie dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 12/05/2005, 21h23
  4. Réponses: 4
    Dernier message: 30/01/2005, 15h23
  5. [Sybase] Problème de type sous ASE
    Par Hotchotte dans le forum Sybase
    Réponses: 1
    Dernier message: 18/12/2004, 12h04

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