[résolu] Tronquer un nombre à virgule

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
cowpowah
Messages : 41
Inscription : mer. 02/juin/2010 12:41

[résolu] Tronquer un nombre à virgule

Message 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:
Dernière modification par cowpowah le ven. 12/oct./2018 18:02, modifié 1 fois.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Tronquer un nombre à virgule

Message 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+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Tronquer un nombre à virgule

Message 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)
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
cowpowah
Messages : 41
Inscription : mer. 02/juin/2010 12:41

Re: Tronquer un nombre à virgule

Message 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()...
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

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

Message par Micoute »

Moi à ta place je le convertirais en string, Left("2.99999", 3) ça fait 2.9, mais c'est de la bidouille.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

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

Message 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.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

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

Message par PAPIPP »

Bonjour à tous

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

A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Répondre