float double et arrondi - Java - Programmation
Marsh Posté le 25-08-2007 à 13:34:52
NE JAMAIS UTILISER DE FLOAT/DOUBLE EN COMPTA ! JAMAIS !
N'utilise que des types entiers : int, long, BigInteger et surtout BigDecimal
Marsh Posté le 25-08-2007 à 13:40:29
ok merci beaucoup pour cette réponse
Mais j'ai un souci avec bigdecimal : Comment faire un vrai modulo avec ?
Merci d'avance
Marsh Posté le 25-08-2007 à 21:28:46
oui j'avais regardé mais je ne vois que remainder qui n'est pas vraiment un modulo.
Donc je me demandais s'il y avait une autre méthode ou si je devais trouver un autre moyen ?
Merci encore
Marsh Posté le 25-08-2007 à 22:24:21
Taz a écrit : NE JAMAIS UTILISER DE FLOAT/DOUBLE EN COMPTA ! JAMAIS ! |
ca me rappelle un gars qui ne savait pas que int existait et qui utilisait bigdecimal partout. Un vrai cauchemar
Marsh Posté le 26-08-2007 à 00:37:52
En même temps pour pas connaitre int je pense que la personne a abordé la programmation sans commencer par les bases
Marsh Posté le 26-08-2007 à 00:47:32
simla a écrit : oui j'avais regardé mais je ne vois que remainder qui n'est pas vraiment un modulo. |
Comment ça pas vraiment modulo ? t'as lu la définition de remainder ? y a écris en gros que ça équivaut à this % that ...
Marsh Posté le 26-08-2007 à 00:58:31
Il y a écrit pour remainder sur la version 5 et 6 de java : Note that this is not the modulo operation (the result can be negative) .
Donc c'est pas vraiment le reste puisque parfois c'est négatif.
Si je comprends bien il ne doit pas y avoir de vrai méthode modulo.
Au pire je pense qu'il suffit de faire une méthode qui vérifie le résultat de remainder et qui, si remainder est négatif et si on fait x % y, rajoute une fois y au reste et fait +1 au dividende.
Vous le comprenez comme cela aussi ?
Marsh Posté le 26-08-2007 à 17:16:07
Re-bonjour,
j'ai toujours le même problème d'arrondi avec BigDecimal :
BigDecimal nbt = new BigDecimal(1.2);
System.out.println(nbt);
-->1.1999999999999999555910790149937383830547332763671875
au lieu de 1.2.
N'y-a-t-il pas de format "non destructeur" ?
Marsh Posté le 27-08-2007 à 09:29:09
nan mais le problème ici c'est pas le BigDecimal, c'est le double que tu utilises pour le construire. Utilise un autre constructeur.
Marsh Posté le 01-07-2010 à 12:59:20
ReplyMarsh Posté le 01-07-2010 à 13:45:32
Et en passant, pourquoi il ne faut pas utiliser float&double pour de la compta? Je demande parce que j'ai déjà vu des compta écrites avec ..
Marsh Posté le 01-07-2010 à 17:16:38
esox_ch a écrit : Et en passant, pourquoi il ne faut pas utiliser float&double pour de la compta? Je demande parce que j'ai déjà vu des compta écrites avec .. |
La majorité le sont, en fait
C'est pour des problèmes de précisions, surtout quand tu effectues de grandes séries d'opérations (d'autant plus quand elles sont répétées) ou que les chiffres impliqués ont de grandes différences dans les ordres de grandeur. Floats et doubles sont par définition inexacts, et tendent donc à mener à des aberrations dans les calculs et les résultats. D'autant plus quand les personnes qui écrivent les softs ne comprennent rien aux différentes méthodes d'arrondis.
Marsh Posté le 01-07-2010 à 19:22:11
frabfr57 a écrit : Peut on m'explique comment faire car j'ai exactement le même problème? |
La réponse a été donnée plus haut. Il faut utiliser BigDecimal avec un autre constructeur.
Dans "new BigDecimal(1.2);" le 1.2 est un double. Regarde dans la doc pour d'autre constructeurs.
Marsh Posté le 01-07-2010 à 19:32:41
masklinn a écrit : |
Merci bien
Donc je comprend qu'en Java il faut utiliser BigDecimal pour ce genre d'applications, mais qu'en est-il par exemple en C? Il existe quelque chose de built-in ?
Marsh Posté le 01-07-2010 à 20:00:23
esox_ch a écrit : |
Ya rien du tout de builtin en C, t'as vu la taille du langage?
Par contre t'as des libs, genre GMP qui est fréquemment utilisé pour implémenter les systèmes à précision arbitraire dans d'autres langages.
Marsh Posté le 03-07-2010 à 09:20:26
Oui justement, il me semblait d'avoir fait le tour et de rien avoir vu
Merci pour la lib
Marsh Posté le 03-07-2010 à 10:53:03
Je travail avec un outil propriétaire qui affiche les données à l'écran dans un objet float, est ce que si je récupére le float le convertie en Bigdecimal (new BigDecimal(String.valueOf(monfloat)), puis fais mes calculs avec l'objet bigdecimal et qu'ensuite j'affiche en réaffectant mon bigDecimal dans l'objet float iul n'y a pas de risque d'erreur d'arrondi?
Merci
Marsh Posté le 06-07-2010 à 08:42:26
frabfr57 a écrit : Je travail avec un outil propriétaire qui affiche les données à l'écran dans un objet float, est ce que si je récupére le float le convertie en Bigdecimal (new BigDecimal(String.valueOf(monfloat)), puis fais mes calculs avec l'objet bigdecimal et qu'ensuite j'affiche en réaffectant mon bigDecimal dans l'objet float iul n'y a pas de risque d'erreur d'arrondi? |
c'est amusant que la plupart des gens comprennent bien qu'on ne peut pas représenter 1/3 de manière exacte en décimal mais ont de la peine à imaginer qu'un nombre apparement simple comme 1.2 ne puisse pas se représenter de manière exacte en binaire. Donc désolé, mais si tu travailles avec des float (ou des double) il y aura toujours des arrondis et des erreurs.
1.2 = 1 + 0/2 + 0/4 + 1/8 + 1/16 + 0/32 + 0/64 + 1/128 + 1/256 ...
1.2 = 1.001100110011001100110011001100110011.... (développement périodique illimité donc pas de représentation exacte)
Marsh Posté le 06-07-2010 à 09:25:21
Question : Alors pourquoi ces problèmes d'arrondi disparaissent avec le BigDecimal ?
Marsh Posté le 06-07-2010 à 09:37:57
esox_ch a écrit : Question : Alors pourquoi ces problèmes d'arrondi disparaissent avec le BigDecimal ? |
Parce que c'est pas la même chose du tout
Les décimaux ont une précision arbitraire (mais habituellement configurable). Ça se traduit par des perfs misérables comparé aux doubles/floats (les opérations basiques sur les floats & doubles sont implémentées en hardware directement) et une explosion de la mémoire utilisée (sous Python, un objet decimal.Decimal est un peu plus de 3 fois plus gros qu'un float [qui correspond au double C]), mais tu n'as pas d'imprécisions de calcul.
Marsh Posté le 06-07-2010 à 17:34:06
Très bien, merci
Marsh Posté le 25-08-2007 à 01:19:23
Bonjour,
je fais un programme qui comprend une partie de comptabilité.
Mon problème est au niveau d'arrondi pour des petits nombres que ce soit en double ou float, ce qui est un problème quand c'est de la compta...
Par exemple pou récupérer la partie entière et après la virgule je fais ça :
double nombre = xxx;
int partieEntiere = (int)nombre;
int partieApresVirg = (int)((nombre - (double)partieEntiere) * 100);
1.20 me rend 1 et 19 ....
Quelqu'un sait omment je pourrai procéder ?
Merci d'avance