Page 1 sur 1

[résolu] Tronquer un nombre à virgule

Publié : jeu. 11/oct./2018 22:09
par cowpowah
Salut,

Je n'arrive pas à tronquer un nombre, c'est surement très bête mais j'y arrive pas...

Code : Tout sélectionner

a=2.99999
Debug FormatNumber(a, 2)
Debug StrD(a, 2)
me donne:

Code : Tout sélectionner

3.00
3.00
Il arrondit, alors que je voudrais 2.99!

C'est quoi l'opposé de la fonction Round()?? :mrgreen:

Re: Tronquer un nombre à virgule

Publié : jeu. 11/oct./2018 23:06
par PAPIPP
Bonjour cowpowah

Et comme cela

Code : Tout sélectionner

procedure.s formatd(va.d,nbdec)
  va$=strd(va)
procedurereturn  left(va$,FindString(va$,".")+nbdec)
endprocedure
a.d=2.99999
debug formatd(a,2)
debug formatd(a,3)

A+

Re: Tronquer un nombre à virgule

Publié : ven. 12/oct./2018 2:17
par falsam
Quoi qu'il arrive
a = 2.99999 donnera toujours 3
tout comme a = 2.50 donnera lui aussi 3 car tu n'as pas défini la bonne variable.

Une variable décimale devra être définie dans une variable de type décimale

Code : Tout sélectionner

a.f = 2.99999
Debug a
donnera bien 2.99999

Par contre si tu souhaite arrondir un tel nombre tu auras 3 comme résultat.
a.f = 2.99999
Debug a
Debug StrF(a, 2)
un contre exemple avec ce code qui montre que l'arrondit de 2.51999 sera 2.52

Code : Tout sélectionner

a.f = 2.51999
Debug a
Debug StrF(a, 2)

Re: Tronquer un nombre à virgule

Publié : ven. 12/oct./2018 18:01
par cowpowah
Merci PAPIPP! ça fonctionne ;)

@falsam: au contraire je cherche à tronquer sans arrondir

accessoirement:

Code : Tout sélectionner

a.f=2.99999
Debug a
me donne 2.99998998641968 8O

Enfin, je trouve bizarre qu’il y ait la fonction Round() et pas de fonction Truncate(), pas même en option dans une autre fonction, particulièrement FormatNumber()...

Re: [résolu] Tronquer un nombre à virgule

Publié : sam. 13/oct./2018 6:48
par Micoute
Moi à ta place je le convertirais en string, Left("2.99999", 3) ça fait 2.9, mais c'est de la bidouille.

Re: [résolu] Tronquer un nombre à virgule

Publié : sam. 13/oct./2018 9:09
par Fig
Il est bon de rappeler aussi que les type flottant (float) en informatique (ce n'est pas spécifique à PB) ne peuvent pas représenter précisément tous les chiffres après la virgule.
Je te renvoie à la page wikipédia:
https://fr.wikipedia.org/wiki/Virgule_flottante
wikipedia a écrit :Précautions d'emploi
Les calculs en virgule flottante sont pratiques, mais présentent divers désagréments, notamment :

leur précision limitée, qui se traduit par des arrondis (dus aux opérations, ainsi qu'aux changements de base implicites) qui peuvent s'accumuler de façon gênante. En particulier, la soustraction de deux nombres très proches et entachés d'erreur provoque une grande perte de précision relative : on parle de cancellation (plus précisément, cancellation catastrophique) ;
une plage d'exposants limitée, autorisant une certaine dynamique, mais pouvant donner lieu au-delà à des débordements (overflows) lorsque le résultat d'une opération est plus grand, en valeur absolue, que la plus grande valeur représentable, et à des sous-passements (underflows), lorsqu'un résultat est plus petit, en valeur absolue, que le plus petit flottant normalisé positif, puis à des résultats n'ayant plus aucun sens.
Il est par exemple tentant de réorganiser des expressions en virgule flottante comme on le ferait d'expressions mathématiques. Cela n'est cependant pas anodin :

les calculs en virgule flottante, contrairement aux calculs sur les réels, ne sont pas associatifs. Par exemple, avec une précision relative de 3 chiffres décimaux, on aurait (0,999+0,0004)+0,0004 = 0,999 + 0,0004 = 0,999 mais 0,999+(0,0004+0,0004)=0,999+0,0008 = 1,000 ; on dit qu'il y a absorption lorsqu'un opérande comme 0,999 absorbe ainsi un plus petit non nul ;
l'évaluation des expressions est parfois faite en précision étendue, avec retour à la précision normale lors du rangement des valeurs ; dans ce cas, on peut avoir une meilleure précision en éliminant certaines variables intermédiaires peu utiles, et les rangements associés.
cowpowah a écrit :Merci PAPIPP! ça fonctionne ;)

@falsam: au contraire je cherche à tronquer sans arrondir

accessoirement:

Code : Tout sélectionner

a.f=2.99999
Debug a
me donne 2.99998998641968 8O

Enfin, je trouve bizarre qu’il y ait la fonction Round() et pas de fonction Truncate(), pas même en option dans une autre fonction, particulièrement FormatNumber()...
Ceci s'explique par la manière dont sont codés les floats. Dans ce cas, 2.99998998641968 tombe rond (pour lui) alors que 2.99999000000000000 non. Nous sommes en base 2 et non en base 10, il ne faut pas l'oublier.

Re: [résolu] Tronquer un nombre à virgule

Publié : sam. 13/oct./2018 15:22
par PAPIPP
Bonjour à tous

Problème déjà traité ici : https://www.purebasic.fr/french/viewtop ... 56#p115656

A+