# Problème affichage double



## Anonyme (23 Janvier 2011)

Petit problème :

```
int main() {
	double machin = 555554254.89;
	double machin2 = machin * 10;
	double machin3 = machin2 * 10;
	cout << "machin -> " << machin << endl;
	cout << "machin2 -> " << machin2 << endl;
	cout << "machin3 -> " << machin3 << endl;
	cout << setprecision(20);
	cout << "machin -> " << machin << endl;
	cout << "machin2 -> " << machin2 << endl;
	cout << "machin3 -> " << machin3 << endl;
	return 0;
}
```

donne :


```
machin -> 5.55554e+08
machin2 -> 5.55554e+09
machin3 -> 5.55554e+10
machin -> 555554254.[COLOR="Red"]88999998569[/COLOR]
machin2 -> 5555542548.[COLOR="red"]8999996185[/COLOR]
machin3 -> 55555425489
```

Ça peut pas venir du double... puisque la multiplication marche.
Donc ça vient du cout !
Pareil avec printf.
Je fais comment ??? 

Merci d'avance 
xcode


----------



## PA5CAL (23 Janvier 2011)

Bonsoir

Je ne vois pas où est le problème. Tu réclames l'affichage d'un nombre à virgule flottante dont la représentation n'est pas unique, avec une précision supérieure à celle que le stockage de la variable permet.

Pour rappel, un «double» contient nombre codé sous la forme :(-1)^_(S)_ x 1._(F)_ x 2^_(E)_​avec :- _(S)_ : signe sur 1 bit 
- _(E)_ : exposant signé, sur 11 bits, codé en binaire
- _(F)_ : partie fractionnaire, sur 52 bits, codé en binaire​

En conséquence :
 du fait du codage binaire, les nombres correspondant à une représentation finie en base 10 ne peuvent pas toujours être stockés de façon exacte,
 pour la même raison, la représentation décimale d'un «double» varie en fonction de la précision considérée,
 les 52 bits de partie fractionnaire ne permettent qu'une précision de 15 chiffres décimaux (moins de 16).

Bref, tu n'obtiens rien que de très normal. Si ce n'est pas ce que tu souhaitais, alors soit tu ajoutes à ton programme le code lui permettant de répondre à tes propres spécifications, soit tu acceptes d'utiliser la représentation prévue par défaut par le système.


----------



## Anonyme (23 Janvier 2011)

Quand je met "setprecision(15)" et que j'affiche 55544526301254.89 il me met "55544526301254.9". 

Tu dit que je pourrait faire mon propre type ?


----------



## PA5CAL (23 Janvier 2011)

xcode a dit:


> Quand je met "setprecision(15)" et que j'affiche 55544526301254.89 il me met "55544526301254.9".


Là, tu demandes 15 chiffres... et il te donne bien 15 chiffres. C'est correct.


xcode a dit:


> Tu dit que je pourrait faire mon propre type ?


En fait, si l'affichage ne te convient pas, il faut que tu crées ta propre routine de conversion d'un «double» en une chaîne de caractères représentant le nombre en base 10.

Par ailleurs, si tu as besoin de stocker des nombres avec une précision plus grande que 15 chiffres décimaux, alors il faut que tu utilises un autre type de variable. Par exemple un «long double».


----------



## Anonyme (23 Janvier 2011)

> En fait, si l'affichage ne te convient pas, il faut que tu crées ta propre routine de conversion d'un «double» en une chaîne de caractères représentant le nombre en base 10.


C'est ce que je suis en train de faire depuis pas mal de temps mais je suis bloqué à plusieurs endroits. Je te met mon algo?



> Là, tu demandes 15 chiffres... et il te donne bien 15 chiffres. C'est correct.


J'avais pas vu qu'il arrondissait...


```
long double
```
Ça existe ? Tu as mieux ? Ou je passe à une librairie de grands nombres ? Ce sera peut-être plus simple ?

Merci d'avance


----------



## PA5CAL (23 Janvier 2011)

Oui, le « long double » existe.

Pour savoir ce que tu dois faire, il faut déjà déterminer précisément quels sont tes besoins, et ce que tu veux obtenir. Parce que pour l'instant, ce n'est pas clair.

Pourquoi le système par défaut ne te convient-il pas ?


----------



## Anonyme (23 Janvier 2011)

15.78 je veux qu'il m'affiche "15.78"
150 000 000 je veux qu'il m'affiche "150 000 000" et non "1.50000e+8"
1556.454557 je veux qu'il m'affiche "1 556.454557" et non "5.55445e+13"
Je ne veux pas qu'il m'arrondisse ou autre chose...


----------



## ntx (23 Janvier 2011)

xcode a dit:


> 15.78 je veux qu'il m'affiche "15.78"
> 150 000 000 je veux qu'il m'affiche "150 000 000" et non "1.50000e+8"
> 1556.454557 je veux qu'il m'affiche "1 556.454557" et non "5.55445e+13"
> Je ne veux pas qu'il m'arrondisse ou autre chose...


Il y a encore quelques petites choses à apprendre, petit scarabée. 

Donc pour le formatage de ta sortie en utilisant l'opérateur << ça se passe ici.  Par exemple pour un affichage scientiifique.


----------



## Anonyme (23 Janvier 2011)

Sans les espaces des milliers c'est bien aussi

---------- Nouveau message ajouté à 21h35 ---------- Le message précédent a été envoyé à 21h32 ----------

Surtout pas scientifique !!!


----------



## PA5CAL (23 Janvier 2011)

xcode a dit:


> 15.78 je veux qu'il m'affiche "15.78"
> 150 000 000 je veux qu'il m'affiche "150 000 000" et non "1.50000e+8"
> 1556.454557 je veux qu'il m'affiche "1556.454557" et non "5.55445e+13"
> Je ne veux pas qu'il m'arrondisse ou autre chose...


Il faut que tu définisses ce que tu veux sous forme de règles beaucoup plus explicites, sinon la solution risque d'être extrêmement compliquée (comme par exemple refaire toutes les structures et les routines de calcul et d'affichage en base 10).

15,78 n'est pas un nombre représentable de façon finie en base 2. L'affichage de "15.78" revient à appliquer une règle d'arrondi, qu'il convient de définir.

En effet, demander que l'affichage du nombre 15,78 produise les caractères "15.78" revient au même que demander que l'affichage du nombre 1/3 produise les caractères "0.333"... plutôt que "0.333333" par exemple.


----------



## Anonyme (23 Janvier 2011)

Y'a rien qui me plaît, là dedans !!
Et puis je connaissait déjà...


----------



## ntx (23 Janvier 2011)

Fouille dans les différents flags de formatage, tu devrais y trouver ton bonheur.


----------



## Anonyme (23 Janvier 2011)

PA5CAL a dit:


> Il faut que tu définisses ce que tu veux sous forme de règles beaucoup plus explicites, sinon la solution risque d'être extrêmement compliquée (comme par exemple refaire toutes les structures et les routines de calcul et d'affichage en base 10).


Le nombre à l'état brut !



PA5CAL a dit:


> 15,78 n'est pas un nombre représentable de façon finie en base 2. L'affichage de "15.78" revient à appliquer une règle d'arrondi, qu'il convient de définir.
> 
> En effet, demander que l'affichage du nombre 15,78 produise les caractères "15.78" revient au même que demander que l'affichage du nombre 1/3 produise les caractères "0.333"... plutôt que "0.333333" par exemple.


Donc je fait mon propre type... Je crois pas... 

---------- Nouveau message ajouté à 21h47 ---------- Le message précédent a été envoyé à 21h45 ----------




ntx a dit:


> Fouille dans les différents flags de formatage, tu devrais y trouver ton bonheur.



Non ! Je veux le nombre à l'état brut !
Et je connaissait déjà !


----------



## PA5CAL (23 Janvier 2011)

xcode a dit:


> Je veux le nombre à l'état brut !


Il est important que tu prennes conscience qu'une telle demande n'a pas de sens.

Non pas que je ne comprenne pas ce que tu recherches, mais cette approche est suffisamment limitative pour s'avérer majoritairement inconsistante et inexploitable.

Tu veux pouvoir afficher exactement le "vrai" nombre. Or, tous les nombres ne sont pas représentables de manière exacte sous une forme décimale finie.

Ceux qui le sont sont les nombres rationnels dont le dénominateur de la fraction réduite est constitué d'un produit de puissance de 2 et de 5, à l'exclusion de tous les autres !!!

Si tu peux représenter 15,78 , c'est seulement parce que ce nombre vaut 789/50 avec 50=(2^1)x(5^2) .


Utiliser un système restreint à ne traîter que des nombres représentables de manière exacte sous une forme décimale finie, c'est s'interdire d'effectuer des calculs autres que l'addition, la soustraction et la multiplication.

En effet, faire une division ou appliquer un logarithme, un sinus ou n'importe quelle fonction courante aboutirait dans presque tous les cas à un résultat non représentable.


Ce n'est pas sans raison que le système de représentation numérique de l'ordinateur est comme ça : il a été conçu pour être utilisé, c'est-à-dire pour produire des résultats de calculs en tenant compte des difficultés inhérentes aux mathématiques appliquées et aux techniques de calcul numérique.

Bref, il est absolument nécessaire qu'avant toute chose tu réfléchisses à tes besoins réels, afin de ne pas démarrer ton projet sur une grosse erreur de conception fonctionnelle.


----------



## ntx (23 Janvier 2011)

xcode a dit:


> machin -> 555554254.88999998569


Notre ami n'a pas compris que les processeurs calculent faux, en tout cas sur les réels  

L'électronique numérique, et donc l'informatique, est un monde qui fonctionne de manière discrète (au sens mathématique du terme) et pas de façon continue comme l'analogique. Donc il est impossible qu'un processeur te donne à chaque fois le résultat brut que tu souhaites. Il y a de forte chance qu'il ne connaisse pas cette valeur car elle n'est pas une des valeurs discrètes qu'il peut atteindre.


----------



## Anonyme (23 Janvier 2011)

PA5CAL a dit:


> Tu veux pouvoir afficher exactement le "vrai" nombre. Or, tous les nombres ne sont pas représentables de manière exacte sous une forme décimale finie.



Ça, j'ai compris... Mais si l'utilisateur d'un logiciel rentre 15.78, c'est que c'est un nombre décimal !
Après que le nombre ne soit pas représentable en binaire, c'est autre chose...



> En effet, faire une division ou appliquer un logarithme, un sinus ou n'importe quelle fonction courante aboutirait dans presque tous les cas à un résultat non représentable.



Ça aussi je sais ! Si "cin" est capable de le faire dans un sens, je ne voit pas pourquoi ça ne serait pas possible dans l'autre. 

Je dis à l'état brut, comme l'utilisateur l'a rentré. Et ne sortez pas le coup de la chaîne de caractère, je dois faire des calculs dessus...  Pour les nombres non décimaux, j'affiche ça sous forme fractionnaire.

---------- Nouveau message ajouté à 23h19 ---------- Le message précédent a été envoyé à 23h17 ----------




ntx a dit:


> Notre ami n'a pas compris que les processeurs calculent faux, en tout cas sur les réels



Je sais 
Mais là, c'est cout qui mache pas bien. J'ai fait aucun calcul.

---------- Nouveau message ajouté à 23h21 ---------- Le message précédent a été envoyé à 23h19 ----------




ntx a dit:


> [...] Donc il est impossible qu'un processeur te donne à chaque fois le résultat brut que tu souhaites. Il y a de forte chance qu'il ne connaisse pas cette valeur car elle n'est pas une des valeurs discrètes qu'il peut atteindre.



Ce n'est pas le résultat, c'est l'affichage...
Je n'ai fait aucun calcul.


----------



## PA5CAL (23 Janvier 2011)

xcode a dit:


> Ça, j'ai compris... Mais si l'utilisateur d'un logiciel rentre 15.78, c'est que c'est un nombre décimal !
> Après que le nombre ne soit pas représentable en binaire, c'est autre chose...


Alors tu devrais savoir qu'à moins de disposer de librairies spécifiques de calcul en BCD (ce qui revient à peu près à calculer directement sur des chaînes de caractères), l'ordinateur ne traite pas de nombres décimaux. Il les traite en binaire !




xcode a dit:


> Ça aussi je sais ! Si "cin" est capable de le faire dans un sens, je ne voit pas pourquoi ça ne serait pas possible dans l'autre.


Tu pourrais m'afficher 2/3 , Log(2) ou sin(0.4) par exemple ? Tu penses vraiment que ce que tu verrais serait le résultat « à l'état brut », comme tu dis ? 



xcode a dit:


> Je dis à l'état brut, comme l'utilisateur l'a rentré. Et ne sortez pas le coup de la chaîne de caractère, je dois faire des calculs dessus... Pour les nombres non décimaux, j'affiche ça sous forme fractionnaire.


Voir plus haut ma remarque sur le format BCD.


Si ton problème d'affichage se limite exclusivement aux nombres décimaux entrés par l'utilisateur (sous formes de caractères, donc), il n'y a pas lieu de faire de conversion vers un format numérique avant de procéder aux calculs. Si tu dois afficher ce qu'a entré l'utilisateur, alors présente-lui la chaîne de caractères qu'il a tapée.

Ensuite, si tes calculs se résument finalement à des manipulations sur des nombres entiers (avec une virgule virtuelle), il n'est pas recommandé de passer par un type «double». Les types entiers sont faits pour ça.


Encore une fois, réfléchis à tes besoins fonctionnels avant de décider quoi faire, et surtout comment faire.


----------



## tatouille (24 Janvier 2011)

tes double represente les en floattant avec la precision de chiffre derrire la virgule que tu veux

http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/

ou fait une template du genre je n'ajoute pas les doubles/flottant (fait expres je les enlevé volontairement ansi que d'autres joyeusetées)

```
template <class T>
static inline std::string toString(const T& t, std::ios_base& (*f)(std::ios_base&) = 0)
{
    std::ostringstream ss;
    if(f == std::oct || f == std::hex) {
        ss << f << t;
    } else {
        ss << t;
    }
    return ss.str();
}

std::cout << "begin toString: " << toString(something) << " end toString" <<std::endl;
```
*WHAT IS C++? A TEMPLATING LANGUAGE*

http://www.amazon.com/dp/0201734842...iveASIN=0201734842&adid=1TBQ8GRVVFPTZ8E2PKMR&

http://www.amazon.com/C-Standard-Template-Library/dp/0134376331#reader_013437633

* C++ Template Metaprogramming* 

http://www.boostpro.com/mplbook/

enfin ca a un maximum sinon on utilise ce genre de chose http://gmplib.org/ (e.g on represente les chiffres par exemple en chaine de characteres et on fait des calculs independant de la machine, enfin juste un racourci pour newb)

les chiffres sont decomposés en structure exemple:

```
typedef stuct
{
    char exponent,
    bool isNegative
    bool isNotNaN
    size_t length
    unsigned char mantissa[38];
} decimal_t;
```
+ arrete d'inclure le standard namespace il y a que les blaireaux qui font ca et apprend le c++ c'est si simple, au lieu d'ecrire du chmeuk++ (bis)
*
A PROPOS DE LONG DOUBLE (TU M'AS FAIT BIEN RIRE, car tu ne sembles par comprendre ce que veux dire long)

*sur une architecture x86, la plupart des compilateurs traite les long double sur 80-bits (parfois stockés sur 12 ou 16 bytes pour garantir l'alignement). Avec Microsoft Visual C++ long double est synonyme de double, C99 est trop dur pour leurs ingenieurs Woinwoin M$..., Intel C++ compiler est plus intelligent sur Woinwoin il utilise le concept de Qlong-double pour acceder a un vraie long double enfin tout simplement il le force. Certains compilers peuvent aussi declarer un long double comme 128 bits ce qu'on appel le "quadruple precision", sur powerpc tu peux avoir le concept de double double, ca revient au meme.

tu viens juste de decouvrir que les ordinateurs sont une hérisie mathematique, la representation binaire a ses avantages mais beaucoup de defauts et la part des defauts est bien plus importante que celle des avantages mais que veux tu nous vivons dans un mode mercantil ou les gens preferent croire ce que leur dit une entreprise que la communautée scientifique, par ailleurs les premiers conceptes d'ordinateur etaient basé sur une representation floattante mais cela etait trop compliqué pour la connaissance de l'epoque donc on a finalement  basculé dans la facilité et l'argent et l'imbecilité: merci IBM, tu me diras bien que ce monde ce veut rationnel mais la populace se base sur un concepte purement irrationnel appelé materialisme et la est tout le comique de ce monde peuplé malheuresement par une majorité de jacking-tuning (TM)


----------



## Anonyme (24 Janvier 2011)

> à moins de disposer de librairies spécifiques de calcul en BCD


Génial ! Le BCD , je l'utilise en électronique ! :love:



> ce qui revient à peu près à calculer directement sur des chaînes de caractères


Je m'en fiche, j'ai pas besoin de vitesse... 

---------- Nouveau message ajouté à 17h40 ---------- Le message précédent a été envoyé à 17h24 ----------




PA5CAL a dit:


> Tu pourrais m'afficher 2/3 , Log(2) ou sin(0.4) par exemple ? Tu penses vraiment que ce que tu verrais serait le résultat « à l'état brut », comme tu dis ?


Ces nombres, je les affiche sous forme fractionnaire.  Et pour les nombres irrationnels, là, bien sur, je me limite à ce que peux contenir un long double. 



PA5CAL a dit:


> Ensuite, si tes calculs se résument finalement à des manipulations sur des nombres entiers (avec une virgule virtuelle), il n'est pas recommandé de passer par un type «double». Les types entiers sont faits pour ça.



Alors oui, la plupart des nombres de mon prog sont entier mais le problème, c'est que quand je compile mon prog pour Windaube (c'est un logiciel qui fait les devoirs de math, tt le monde est sous widaube), via Code::Blocks qui tourne sous wine, pour un long, je suis limité à (vous allez rire) 2^16 ! :bebe: Soit 65534 ! On va pas loin... :rateau:

---------- Nouveau message ajouté à 18h33 ---------- Le message précédent a été envoyé à 17h40 ----------




tatouille a dit:


> *WHAT IS C++? A TEMPLATING LANGUAGE*
> 
> * C++ Template Metaprogramming*



Mon programme est fait presque uniquement de templates à part les classes que tu a déjà vu.
Et oui, ton bouquin, je vais essayer de l'avoir...
Mais c'est de l'anglais... ça va pas être facile... 

Et jamais je mettrait des "std:" partout ! Je sais je fais du chmeurk++ et j'ai un style de merde... Je changerais pas pour ça. Point. :casse:

GMP j'arrive pas à l'installer ! Grrrrrr... :hein::afraid::hosto::hein::casse: Ouinnn... Quand je fais le make, après cinq minutes, y'a le compilo qui m'insulte... Mais c'est une erreur qui arrive à pas mal de monde et on peut rien faire 
Je veux GMP...

En fait, c'est quoi la mantisse ? c'est ça : 





> - (F) : partie fractionnaire, sur 52 bits, codé en binaire


 



tatouille a dit:


> tu viens juste de decouvrir que les ordinateurs sont une hérisie mathematique, la representation binaire a ses avantages mais beaucoup de defauts et la part des defauts est bien plus importante que celle des avantages mais que veux tu nous vivons dans un mode mercantil ou les gens preferent croire ce que leur dit une entreprise que la communautée scientifique, par ailleurs les premiers conceptes d'ordinateur etaient basé sur une representation floattante mais cela etait trop compliqué pour la connaissance de l'epoque donc on a finalement basculé dans la facilité et l'argent et l'imbecilité: merci IBM, tu me diras bien que ce monde ce veut rationnel mais la populace se base sur un concepte purement irrationnel appelé materialisme et la est tout le comique de ce monde peuplé malheuresement par une majorité de jacking-tuning (TM)



Les premiers ordis (disons portes logiques), c'était des lampes... Donc analogique, mais ça a pas duré longtemps...


----------



## PA5CAL (24 Janvier 2011)

xcode a dit:


> > - (F) : partie fractionnaire, sur 52 bits, codé en binaire
> 
> 
> En fait, c'est quoi la mantisse ? c'est ça :


Ça c'est la partie fractionnaire de la mantisse. Pour avoir la mantisse complète, il faut rajouter un 1 devant (sauf pour les nombres spéciaux comme zéro, NaN, infini, etc.).

---------- Nouveau message ajouté à 19h40 ---------- Le message précédent a été envoyé à 19h15 ----------




xcode a dit:


> Les premiers ordis (disons portes logiques), c'était des lampes... Donc analogique, mais ça a pas duré longtemps...


En fait, les premiers ordinateurs étaient mécaniques.

Précision de vocabulaire : les ordinateurs _analogiques_ ne sont pas constitués de portes logiques, mais d'opérateurs à réponse continue. S'il y a des portes logiques (à relais, à lampes ou à transistors) alors c'est déjà du _numérique_.


----------



## Anonyme (24 Janvier 2011)

PA5CAL a dit:


> les ordinateurs _analogiques_ ne sont pas constitués de portes logiques, mais d'opérateurs à réponse continue. S'il y a des portes logiques (à relais, à lampes ou à transistors) alors c'est déjà du _numérique_.



Il faut décidément que je réfléchisse plus avant d'écrire... 



> opérateurs à réponse continue


Des AOPs, des transistors (c'est la même chose, à la fin...), des lampes...

---------- Nouveau message ajouté à 19h57 ---------- Le message précédent a été envoyé à 19h54 ----------

GMP..... 

Pas trouvé de librairie BCD...
J'en fabrique une...


----------



## tatouille (24 Janvier 2011)

xcode a dit:


> Les premiers ordis (disons portes logiques), c'était des lampes... Donc analogique, mais ça a pas duré longtemps...



et non ca c'est a la fin des années 50 quand on a finalement opté pour une implementation binaire , mais disons que dans certaines branches on utilise toujours des systemes a variation continue  .

mantissa: http://www.tpub.com/math1/9b.htm un peu de math  et en anglais

"Des AOPs, des transistors" pas tout a fait c'est plus evolué une lampe c'est eteint allumé avec plus ou moins d'intensité (variateur) c'est pour cela que c'est nommé numerique: les valeurs sont quantifiées et non analogique les lampes.

voir http://fr.wikipedia.org/wiki/Lois_de_De_Morgan derivé de l'Algèbre de Boole e.g -1 , 0 , 1

le boolean en informatique (code) est stupide il devrait etre implementé comme ceci


```
enum {
     nontrue = -1,
     false,
     true
}

// pour ma part j'aime bien faire ca 8-)

typedef enum {
     not  = -1,
     no,
     yes
} bool_t
```
tu peux voir une simple implementation de lib BCD ici http://www.crbond.com/extended_precision.htm
mais ce que tu veux c'est GMP voir MPFR cherche pour une dll ou une lib deja portée et compilée pour windows (ca existe cherche plus dans les downloads)


----------



## Anonyme (24 Janvier 2011)

tatouille a dit:


> mais ce que tu veux c'est GMP voir MPFR cherche pour une dll ou une lib deja portée et compilée pour windows (ca existe cherche plus dans les downloads)



Oui mais je veux aussi GMP pour mac. Mon logiciel, je le fait pour mac et pour windaube.

---------- Nouveau message ajouté à 22h06 ---------- Le message précédent a été envoyé à 21h58 ----------

Youpiiii... :style::style::style:
GMP compile !!! J'ai pris la version 4.3.1 et ça bug plus ! Enfin 
J'ai mis "gmp.h" et "gmp_lib.a" dans le SDK 10.5 de xcode.
C'est génial. On peut mettre des nombres énormes ! 
Je vais tester la transfo en chaine de caractères...


----------

