OVH Cloud OVH Cloud

Conversions de type, perte d informations

33 réponses
Avatar
Dominique de LAPASSE
Bonjour,

Imaginons que j 'ai besoin de convertir la valeur 17.58 ( Euros ) en 1758
( Centimes )

Le calcul qui vient naturellement à l esprit est :


float fValeur1 = (float)17.58;
float fValeur2 = fValeur1 * 100;

long lValeur3;
lValeur3 = (long) fValeur2;

Or lValeur3 vaut 1757 !!!
Quel calcul ou conversions faut-il mettre en oeuvre pour parvenir a un
résultat correct ????

Merci.

10 réponses

1 2 3 4
Avatar
Jean-Marc Bourguet
"Dominique de LAPASSE" writes:

Imaginons que j 'ai besoin de convertir la valeur 17.58 ( Euros ) en 1758
( Centimes )

Le calcul qui vient naturellement à l esprit est :


float fValeur1 = (float)17.58;


Les nombres flottants ne peuvent representer de maniere exacte qu'une
partie des reels. Pour les formats les plus courants, ce sont ceux de
la forme
m * 2 ^ k
ou m et k sont entiers (et ^ designe l'exponentiation). 17.58 ne peut
pas se mettre sous cette forme et donc n'est pas representable
exactement.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Fabien LE LEZ
On Thu, 17 Mar 2005 09:25:19 +0100, "Dominique de LAPASSE"
:

(float)17.58;


La solution qui te vient naturellement à l'esprit est ce genre de
cast ? :-o


Imaginons que j 'ai besoin de convertir la valeur 17.58 ( Euros ) en 1758
( Centimes )


Généralement, quand on parle d'argent, on évite au maximum d'utiliser
des flottants, car la valeur qu'ils stockent est difficile à prévoir
exactement. On préfère utiliser des entiers, en prenant comme unité la
plus petite unité de la monnaie (ici, le centime).

Si tu n'as vraiment pas le choix, i.e. que tu es obligé de faire une
fonction qui prend en entrée un "double euros" et qui renvoie la
valeur en centimes, tu peux tenter ceci :

int ConversionEnCentimes (double euros)
{
return (euros * 100) + 0.5;
}


--
;-)

Avatar
Dominique de LAPASSE
Imaginons que j 'ai besoin de convertir la valeur 17.58 ( Euros ) en
1758


( Centimes )

Le calcul qui vient naturellement à l esprit est :


float fValeur1 = (float)17.58;


Les nombres flottants ne peuvent representer de maniere exacte qu'une
partie des reels. Pour les formats les plus courants, ce sont ceux de
la forme
m * 2 ^ k
ou m et k sont entiers (et ^ designe l'exponentiation). 17.58 ne peut
pas se mettre sous cette forme et donc n'est pas representable
exactement.


Merci bien pour la theorie, mais en pratique , comment peux t on resoudre ce
probleme qui doit se poser assez souvent non ?


Avatar
Marc Boyer
Dominique de LAPASSE wrote:
ou m et k sont entiers (et ^ designe l'exponentiation). 17.58 ne peut
pas se mettre sous cette forme et donc n'est pas representable
exactement.


Merci bien pour la theorie, mais en pratique , comment peux t on resoudre ce
probleme qui doit se poser assez souvent non ?


En pratique, on calcule en entier avec la précision maximum demandée
(avec l'euro, 6 décimales après la virgule je crois), et on surcharge
les fonctions d'E/S pour faire comme si il y avait une virgule.
Ou on veut vraiment des flottants et on commence par recruter
un numéricien...

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.


Avatar
Dominique de LAPASSE
Parfait ca fonctionne sur 300 cas au moins

de 17.00 a 19.99

donc je valide...

Merci.



"Fabien LE LEZ" a écrit dans le message de news:

On Thu, 17 Mar 2005 09:25:19 +0100, "Dominique de LAPASSE"
:

(float)17.58;


La solution qui te vient naturellement à l'esprit est ce genre de
cast ? :-o


Imaginons que j 'ai besoin de convertir la valeur 17.58 ( Euros ) en 1758
( Centimes )


Généralement, quand on parle d'argent, on évite au maximum d'utiliser
des flottants, car la valeur qu'ils stockent est difficile à prévoir
exactement. On préfère utiliser des entiers, en prenant comme unité la
plus petite unité de la monnaie (ici, le centime).

Si tu n'as vraiment pas le choix, i.e. que tu es obligé de faire une
fonction qui prend en entrée un "double euros" et qui renvoie la
valeur en centimes, tu peux tenter ceci :

int ConversionEnCentimes (double euros)
{
return (euros * 100) + 0.5;
}


--
;-)



Avatar
Jean-Marc Bourguet
"Dominique de LAPASSE" writes:

Imaginons que j 'ai besoin de convertir la valeur 17.58 ( Euros ) en
1758


( Centimes )

Le calcul qui vient naturellement à l esprit est :


float fValeur1 = (float)17.58;


Les nombres flottants ne peuvent representer de maniere exacte qu'une
partie des reels. Pour les formats les plus courants, ce sont ceux de
la forme
m * 2 ^ k
ou m et k sont entiers (et ^ designe l'exponentiation). 17.58 ne peut
pas se mettre sous cette forme et donc n'est pas representable
exactement.


Merci bien pour la theorie, mais en pratique , comment peux t on resoudre ce
probleme qui doit se poser assez souvent non ?


Le seul domaine ou je sais que le probleme se presente, c'est la
finance. Ailleurs avoir une bonne precision est plus important
qu'avoir les nombres decimaux representables exactement.

Je ne travaille pas pour la finance, mais une technique possible est
d'utiliser des bibliotheques fournissant des nombres en virgule fixe;
une autre technique est de manipuler des centimes plutot que des euros
(ce qui revient a faire manuellement ce que la bibliotheque fait).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
screetch
dans le cas des francs : on parle en centimes comme tu l'as fait, et on
utilise des long. 1757 centimes, c'est exact. apres, on passe en francs
avec des operateurs sur les entiers.

si tu ne connais pas la precision dont tu as besoin et l'unite, tu dois
adapter au mieux, c'est pas tjs facile.


Dominique de LAPASSE wrote:
Imaginons que j 'ai besoin de convertir la valeur 17.58 ( Euros ) en



1758

( Centimes )

Le calcul qui vient naturellement à l esprit est :


float fValeur1 = (float)17.58;


Les nombres flottants ne peuvent representer de maniere exacte qu'une
partie des reels. Pour les formats les plus courants, ce sont ceux de
la forme
m * 2 ^ k
ou m et k sont entiers (et ^ designe l'exponentiation). 17.58 ne peut
pas se mettre sous cette forme et donc n'est pas representable
exactement.



Merci bien pour la theorie, mais en pratique , comment peux t on resoudre ce
probleme qui doit se poser assez souvent non ?







Avatar
Dominique de LAPASSE
Le seul domaine ou je sais que le probleme se presente, c'est la
finance.


La c est de la gestion toute bete:
1 ) saisir un tarif horaire en Euro ( je me vois mal expliquer a
l'operatrice qu en 2005 il faille saisir en centimes a cause de toute la
théorie ci dessus .... )

2 ) l enregistrer en Base de données en centimes pour eviter les erreurs d
arrondis lors de requetes etc....

Avatar
Jean-Marc Bourguet
"Dominique de LAPASSE" writes:

Le seul domaine ou je sais que le probleme se presente, c'est la
finance.


La c est de la gestion toute bete:
1 ) saisir un tarif horaire en Euro ( je me vois mal expliquer a
l'operatrice qu en 2005 il faille saisir en centimes a cause de toute la
théorie ci dessus .... )


Elle saisit une chaine. Comment tu l'interpretes c'est ton probleme
et rien ne t'oblige a en faire un flottant.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Marc Boyer
Dominique de LAPASSE wrote:
Le seul domaine ou je sais que le probleme se presente, c'est la
finance.


La c est de la gestion toute bete:
1 ) saisir un tarif horaire en Euro ( je me vois mal expliquer a
l'operatrice qu en 2005 il faille saisir en centimes a cause de toute la
théorie ci dessus .... )


L'opératrice saisit une chaine de caractères, c'est le programme
qui décide que ce sont des flottants, des entiers ou une adresse IP.

2 ) l enregistrer en Base de données en centimes pour eviter les erreurs d
arrondis lors de requetes etc....


Oui.

Puisqu'on est en C++, une mini-classe "VirguleFixe" s'impose, non ?

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.


1 2 3 4