beckerich
Messages postés302Date d'inscriptionjeudi 29 septembre 2005StatutMembreDernière intervention17 septembre 20132 1 nov. 2008 à 20:07
ahh ces programmeurs, tu leur file un grain de riz, ils te nourissent la Chine ... ;-))
jackalunion
Messages postés128Date d'inscriptionmercredi 8 janvier 2003StatutMembreDernière intervention14 juillet 2008 22 juin 2008 à 17:58
Trés bon code
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 1 nov. 2007 à 22:36
Allez!
T'as bien travaillé, Kenavo.
Merci pour la leçon.
Tu prendras bien un petit Kinder-Suicide?
Maintenant, j'mets des petits morceaux de nougat dans le beurre de cacao...
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 1 nov. 2007 à 21:46
Monstrueux ! D'accord !
C'est toi qui est monumental ! Plus de 20 decimales exactes dans ce calcul piège à ordi ...
... et j'aime bien le goût du petit morceau
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 1 nov. 2007 à 21:31
Je serais quand même curieux de voir ce que tout ça donne "à la sauce Fortran"...
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 1 nov. 2007 à 21:01
Pas monumentaux, Kenavo.
Pas monumentaux mais monstrueux! Beurk!
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 1 nov. 2007 à 20:42
Cari, j'obtiens le même résultat que toi avec les Extended
Je rapelle à tous que le résutat par le calcul direct en employant la méthode des nombres monumentaux (que je reconnais avec honte ne pas avoir encore adoptée)de Cari, et seule à ne pas se vautrer lamentablement avait donné :
0.039 938 729 673 230 208 903 671 306 691 037 268 151 500 8 (vous pouvez vérifier plus haut)
Si Cari, entre deux Kinder, pouvait pousser assez loin le second calcul avec ses nombres monumentaux, pour obtenir autant de chiffres significatif, nous aurions, je crois, la réponse la plus précise à la question : "de combien le banquier m'a t'il enflé ?"
Et en conclusion, je dirais l'informatique, c'est bon, mais c'est meilleur avec des vrais morceaux de mathématiques dedans.
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 1 nov. 2007 à 20:07
...
Moi, sur ma bécane j'ai une chaîne qui ressemble à ça :
0,039 938 729 673 230 208 903
et
0,039 938 729 673 230 2 avec Delphi et Extended.
Pour le moment, c'est Delphi qui porte le maillot jaune!
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 1 nov. 2007 à 18:47
D'où ces quelques lignes :
procedure TForm1.Button2Click(Sender: TObject);
var
i : integer;
x,y : double;
begin
x:=0;
y:=1;
for i:=26 to 50 do
begin
y:= y*i;
x:= x + 1/y;
end;
Edit1.Text :=FloatToStrf(x,ffFixed,25,12);
end;
On remarque qu'au bout d'un certain nombre d'itérations la valeur n'évolue plus ... Ben oui on est encore parti dans un calcul où pointe la factorielle ! Mais, heureusement, ici, il n'y a pas d'incident d'emballement de l'erreur qui conduisait à des chiffres monumentaux et des dépassements de capacité.
En grattant un peu mathématiquement, je ne serais pas étonné de voir apparaître 1/n (n : nombre d'années) dans le résultat ....
La valeur finale de X dans mon message précédent m'a été donné par OpenOffice Calc. Avec Delphi les valeurs (selon le type de réel utilisé) sont différentes.
Laquelle est la plus juste ?
Avec quel type de réel calcule Calc ?
Que dit Excel ?
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 1 nov. 2007 à 18:18
Pour ceux que ça intéresse :
si on développe la formule, on obtient (après quelques calculs)
X : Valeur au bout de n itérations
En remplaçant plus haut, on voit que tous les termes de l'équation X s'annulent. Restent les petits termes du developpement de en! après n!/n!
donc :
X = n!/(n+1)! + n!/(n+2)! + n!/(n+3)! + ......
pour pouvoir calculer on vire les factorielles n! (division haut et bas):
X = 1/(n+1) + 1/(n+1)/(n+2) + 1/(n+1)/(n+2)/(n+3) +....
ce qui pour n=25 donne
X = 1/26 + 1/(26*27) + 1/(26*27*28) + ....
et c'est dans les cordes de nos ordinateurs, si on ne cherche pas trop de décimales
ce qui donne
X = 0.0399368525...
J'espère vous avoir amusé !
Ken@vo
Albedo039
Messages postés18Date d'inscriptionmercredi 8 novembre 2006StatutMembreDernière intervention31 janvier 2008 1 nov. 2007 à 14:09
Pour programmer un algo dans son langage de prédilection, il faut toujours suivre le "mode d'emploi" :)
c.a.d. il faut toujours considérer le contexte et les règles de son utilisation, qui sont en général livrés avec la description formelle de l'algo.
Par exemple, le contexte bancaire et les règles (lois et/ou décrets) régissant la manière d'arrondir et la précision des nombres à virgule.
Dans ce cas, 5 lignes peuvent à priori parfaitement suffirent.
La méthode de WhiteHippo est utile ... lorsqu'il n'existe pas de telles règles :)
Ouaaaaahhh, ça commence à faire drôlement compliqué pour un calcul qui codé de façon "simple" se résume à 5 lignes !!
Mais tu as raison, quitte à prendre des précautions, autant toutes les prendre.
Sinon, l'autre moyen c'est de séparer les calculs (un calcul sur e, l'autre sur la constante qu'il y a derrière) et de faire la soustraction avec une méthode CariKinder.
WhiteHippo
Messages postés1154Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 avril 20123 31 oct. 2007 à 19:46
Bonsoir à tous.
Ce qui suit, fruits d'expériences passées, n'a pas été testé dans ce cas spécifique par faute de temps, alors soyez indulgent si erreur il y a ;)
Pour utiliser les flottants de la façon la plus propre possible, il faudrait utiliser TOUTES les exceptions disponibles par le FPU. Hors ce n'est pas le cas par défaut en Delphi.
Pour activer toutes les exceptions, il faut :
Mask := SetExceptionMask( [] );
La variable Mask étant définie comme suit :
var
Mask : TFPUExceptionMask ;
Ensuite, intercepté les exceptions :
try
// calculs ici
except
on E : EMathError do
begin
case E.ExceptionRecord.ExceptionCode of
STATUS_FLOAT_INEXACT_RESULT :
// Le résultat de l''opération ne peut pas être représenté
// par une fraction décimale.
;
STATUS_FLOAT_INVALID_OPERATION :
// Opération sur nombres flottants invalide.
;
STATUS_FLOAT_STACK_CHECK :
// Débordement de pile
;
STATUS_FLOAT_DIVIDE_BY_ZERO :
// Division par 0
;
STATUS_FLOAT_OVERFLOW :
// Dépassement de capacité. Des chiffres significatifs sont
// perdus par manque de précision dans le format défini.
// Le type n'a pas suffisamment de place pour stocker la valeur.
;
STATUS_FLOAT_UNDERFLOW :
// Dépassement de capacité. Le calcul a donné un nombre trop petit pour
// être stocké dans le type défini.
;
STATUS_FLOAT_DENORMAL_OPERAND :
// Nombre dénormalisé.
;
ELSE
// AUTRE EXCEPTION
;
end ;
end ;
end ;
N.B. Ne pas oublier de remettre le masque à la fin :
SetExceptionMask( Mask ) ;
Avec TOUTES les exceptions actives, les boucles ne s'executeront alors plus jusqu'à la fin. Une exception sera levée en cours. Laquelle ? A vous de travailler :P
N.B. Pour ceux qui seront intéressés de tester tout ça, il faudra également jouer avec TFPUPrecisionMode et TFPURoundingMode.
!! ATTENTION !! En activant TOUTES les exceptions, vous constaterez que cela implique une gestion autrement plus rigoureuse des flottants que celle existante par défaut en Delphi. A titre d'exemple, un simple appel à une fonction comme la fonction Exp peut se solder par une exception de précision !!
Cordialement.
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 31 oct. 2007 à 19:10
En fait, si on "oublie" le "-1" (mais en le gardant dans la tête quand même), on aura, après n itérations, un coefficient n! devant e.
Ce qui fait que, pour n = 25, on aura 25!, soit 620'448'401'733'239'439'360'000
Alors, forcément, pour avoir de la précision sur le calcul final, il faut que tu aies e avec au moins 24 chiffres significatifs, ce qui n'est pas gagné d'avance vu le nombre de décimales que permettent les nombres flottants.
Voila donc "l'oubli": adapter son calcul à la capacité de sa machine. Et éviter à tout prix les suites définies par récurrence, sous peine de perdre en précision à chaque tour de boucle.
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 31 oct. 2007 à 17:20
@Cari: comme je le disais (mais de manière moins nette): le nombre de décimales est trèèèèès important: la preuve, ce pauvre nombre e doit être manié avec beaucoup de précision pour arriver au bon résultat (faut dire que faire *2 puis *3, *4, *5, ... et *25 si tu te goures d'une décimale, ça part vite - merci f0xi pour la métaphore ^^).
Mais ton exemple est parfait,
Conclusion: faut faire du calcul formel !! ça irait même plus vite que de calculer avec des nombres à 100 chiffres significatifs.
Au moins là, t'es sûr de ton coup !
cs_MAURICIO
Messages postés2106Date d'inscriptionmardi 10 décembre 2002StatutModérateurDernière intervention15 décembre 20145 31 oct. 2007 à 16:30
Pour ceux qui se demandent si j' ai fait tout ça à la main: non!
Donc, ça fait 25 multiplié par 4 fois d' affilé.
Un peu bourrin je sais, mais faut bien se chauffer en cette saison froide .
Astuce: J' ai utilisé Delphi: Je pratique Delphi, moi aussi ! lol
cs_MAURICIO
Messages postés2106Date d'inscriptionmardi 10 décembre 2002StatutModérateurDernière intervention15 décembre 20145 31 oct. 2007 à 16:20
Salut à tous.
J' ai fait un petit résumé des calculs.
S' il y a un problème d' affichage, copier coller dans le notepad et seleccionner la police courrier New!!!
Fichier d' aide DELPHI :
Real48 2.9 x 10^-39 .. 1.7 x 10^38 11-12 6
Single 1.5 x 10^-45 .. 3.4 x 10^38 7-8 4
Double 5.0 x 10^-324 .. 1.7 x 10^308 15-16 8
Extended 3.6 x 10^-4951 .. 1.1 x 10^4932 19-20 10
Comp -2^63+1 .. 2^63 -1 19-20 8
Currency -922337203685477.5808.. 922337203685477.5807 19-20 8
Le problème est directement lié à la taille em byte de la nature de la variable qui va influencer sur le stockage de la valeur, mais ça vous avez déjá tous compris.
Le problème soulevé para Albedo039 je m' y suit confronté plusieurs fois!
" ??? Mais quand doivent-ils calculer la TVA ???
:)
1) (somme des prix HT)* Taux de TVA
2) (Prix HT 1)*TVA + (Prix HT 2)*TVA + ..."
Disons qu' au Portugal on trouve les 2 méthodes en fonctionnement, tout dépend comme tu dis du nombre de décimaux dans le prix HT qui fait foirer le total de la TVA !!!
A+
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 31 oct. 2007 à 15:39
Si je ne me fais guère de souci pour un banquier et, pour tout dire, si je lui fais confiance pour me taxer un max...
J'ai par contre une légère anxiété quant au pauvre bougre qui est volontaire pour un voyage vers la lune.
Neil Armstrong a eu du bol!
Pour se libérer du caractère anxiogène des types flottants, j'ai effectué le calcul sur des chaînes. Donc sans aucun arrondi.
Sauf erreur de ma part, il semble que y'a pas que les types flottants qui font chier!
Au secour, Évariste!!!
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 31 oct. 2007 à 15:25
"puisqu'une toute petite erreur fait partir vers les infinis très rapidement !!"
C'est des flottants Buzz l'eclair!
VERS L'INFINI ET AU DELAAAAA!
Albedo039
Messages postés18Date d'inscriptionmercredi 8 novembre 2006StatutMembreDernière intervention31 janvier 2008 31 oct. 2007 à 12:16
Matière à réflexion:
--------------------
Il existe un autre problème bien plus subtil en ce qui concerne les "finances":
le calcul de la TVA.
En l'occurrence, beaucoup de logiciels affichent des factures ayant plusieurs produits et leurs prix...
??? Mais quand doivent-ils calculer la TVA ???
:)
1) (somme des prix HT)* Taux de TVA
2) (Prix HT 1)*TVA + (Prix HT 2)*TVA + ...
Dans beaucoup de cas, le résultat est identique. Mais (parcequ'il y a un "mais") pas toujours !
C'est dû à la manière et le moment d'arrondir les montants et au nombre de chiffres significatifs utilisés....
Et dire qu'en réalité, ça converge vers 0 !! (si je me suis pas gouré...)
Pas très doués ces types flottants.
Mais en même temps, c'est ta valeur initiale e-1 qui pose problème. Si tu avais mis autre chose (je sais bien que tu l'as fait exprès ^^), par exemple 1.8, tu serais multimilliardaire. Avec 1.6, tu serais plus endetté que l'État français...
Le problème est donc du à l'arrondi de la dernière décimale, et qui donc détermine la précision. Mais sur le coup, tu as raison, chaque décimale compte, puisqu'une toute petite erreur fait partir vers les infinis très rapidement !!
D'ailleurs, c'est quoi le terme général de cette suite ?
Bravo pour cette démonstration de la faiblesse de nos ordis, ça fait du bien de faire quelques calculs à la main...
Albedo039
Messages postés18Date d'inscriptionmercredi 8 novembre 2006StatutMembreDernière intervention31 janvier 2008 31 oct. 2007 à 10:15
Ben en fait non.
(je suis pas banquier, mais j'ai déjà progé des logiciels financiers)
Le banquier, y travaille au burin! Y découpe tout ce qui dépasse au moins une fois par an.
en d'autres termes, il utilise seulement un nombre restreint de chiffres significatifs et il arrondit au besoin.
Donc:
pour tout problème périodique (annuaire/mensuel...), la formule de calcul "simple" (purement mathématique) n'est pas utilisable.
Conclusion:
ce n'est pas un problème de type de flottant, c'est une erreur de logique du programmeur ;)
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 31 oct. 2007 à 00:55
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 30 oct. 2007 à 23:38
Faut bien dire que la Currency, c'est une fragile ! Elle est juste faite pour compter les talbins dans n'importe quel clandé, pas pour aller chercher les limites des gars qui savent compter dans des suites convergentes (non, il n'y a pas de gros mots). Là, elle risque d'y laisser au moins sa mantisse et son exposant. Ce serait une bien triste fin !... 20 fois tout de même !... Bravo ! On y mettra ds fleurs
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 30 oct. 2007 à 23:14
Ecoute, si je lui laisse la mantisse froide, c'est peut-être qu'elle y met pas du sien, la Currency.
Parce que c'est pas mon style de foncer sans préliminaires.
Faudrait pas essayer de me faire passer pour un gougnafier.
Tout dans la finesse et la délicatesse, le père japee. L'approche feutrée, la démarche légère. La main ferme et assurée, mais toujours dans un gant de velours.
Alors si j'y ai explosé l'exposant, ça ne peut être que dans le feu de l'action (parce que 20 fois, quand même ^^).
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 30 oct. 2007 à 22:40
Mon bon Japee,
Tu dépasses là, non point mon entendement, mais la capacité du type Currency, qui, s'il dipose d'une mantisse d'un fort bel accabit, souffre néanmoint d'un déficit notoire quant à la taille de son exposant.
En gros, si tu lui laisse la mantisse froide, tu lui explose l'exposant ...
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 30 oct. 2007 à 22:07
Salut Kenavo,
Si j'étais ton banquier, j'aurais utilisé le type Currency, et tes économies auraient crashé la 21ème année. Désolé ^^
Mais je suis certainement moins dégourdi que ton banquier...
En tout cas, voilà de quoi méditer pendant les longues soirées d'hiver qui approchent.
P-S: faut quand même que je comprenne pourquoi ça crashe à la 21ème boucle avec une opération en virgule flottante incorrecte (j'obtiens 44 209 578 480 511 à la 20ème itération et puis plouf !).
1 nov. 2008 à 20:07
22 juin 2008 à 17:58
1 nov. 2007 à 22:36
T'as bien travaillé, Kenavo.
Merci pour la leçon.
Tu prendras bien un petit Kinder-Suicide?
Maintenant, j'mets des petits morceaux de nougat dans le beurre de cacao...
1 nov. 2007 à 21:46
C'est toi qui est monumental ! Plus de 20 decimales exactes dans ce calcul piège à ordi ...
... et j'aime bien le goût du petit morceau
1 nov. 2007 à 21:31
1 nov. 2007 à 21:01
Pas monumentaux mais monstrueux! Beurk!
Alors, sans morceau:
0.039 938 729 673 230 208 903 671 306 691 037 268 151 500 8
et avec morceaux:
0.039 938 729 673 230 208 903 671 455 210 361 060 981 080 0
On sent bien la présence du petit morceau, hein?
1 nov. 2007 à 20:42
Je rapelle à tous que le résutat par le calcul direct en employant la méthode des nombres monumentaux (que je reconnais avec honte ne pas avoir encore adoptée)de Cari, et seule à ne pas se vautrer lamentablement avait donné :
0.039 938 729 673 230 208 903 671 306 691 037 268 151 500 8 (vous pouvez vérifier plus haut)
Si Cari, entre deux Kinder, pouvait pousser assez loin le second calcul avec ses nombres monumentaux, pour obtenir autant de chiffres significatif, nous aurions, je crois, la réponse la plus précise à la question : "de combien le banquier m'a t'il enflé ?"
Et en conclusion, je dirais l'informatique, c'est bon, mais c'est meilleur avec des vrais morceaux de mathématiques dedans.
1 nov. 2007 à 20:07
Moi, sur ma bécane j'ai une chaîne qui ressemble à ça :
0,039 938 729 673 230 208 903
et
0,039 938 729 673 230 2 avec Delphi et Extended.
Pour le moment, c'est Delphi qui porte le maillot jaune!
1 nov. 2007 à 18:47
procedure TForm1.Button2Click(Sender: TObject);
var
i : integer;
x,y : double;
begin
x:=0;
y:=1;
for i:=26 to 50 do
begin
y:= y*i;
x:= x + 1/y;
end;
Edit1.Text :=FloatToStrf(x,ffFixed,25,12);
end;
On remarque qu'au bout d'un certain nombre d'itérations la valeur n'évolue plus ... Ben oui on est encore parti dans un calcul où pointe la factorielle ! Mais, heureusement, ici, il n'y a pas d'incident d'emballement de l'erreur qui conduisait à des chiffres monumentaux et des dépassements de capacité.
En grattant un peu mathématiquement, je ne serais pas étonné de voir apparaître 1/n (n : nombre d'années) dans le résultat ....
La valeur finale de X dans mon message précédent m'a été donné par OpenOffice Calc. Avec Delphi les valeurs (selon le type de réel utilisé) sont différentes.
Laquelle est la plus juste ?
Avec quel type de réel calcule Calc ?
Que dit Excel ?
1 nov. 2007 à 18:18
si on développe la formule, on obtient (après quelques calculs)
X : Valeur au bout de n itérations
X = (e-1)n! - n!/1! - n!/2! - n!/3! - ... - n!/n!
X = en! - n! - n!/1! - n!/2! - n!/3! - ... - n!/n!
C'est là quarrive le moment de vous rapeller le developpement limité de e :
e = 1 + 1/1! + 1/2! + 1/3! + ....
donc
en! = n! + n!/1! + n!/2! + ... + n!/n! + n!/(n+1)! + .....
En remplaçant plus haut, on voit que tous les termes de l'équation X s'annulent. Restent les petits termes du developpement de en! après n!/n!
donc :
X = n!/(n+1)! + n!/(n+2)! + n!/(n+3)! + ......
pour pouvoir calculer on vire les factorielles n! (division haut et bas):
X = 1/(n+1) + 1/(n+1)/(n+2) + 1/(n+1)/(n+2)/(n+3) +....
ce qui pour n=25 donne
X = 1/26 + 1/(26*27) + 1/(26*27*28) + ....
et c'est dans les cordes de nos ordinateurs, si on ne cherche pas trop de décimales
ce qui donne
X = 0.0399368525...
J'espère vous avoir amusé !
Ken@vo
1 nov. 2007 à 14:09
c.a.d. il faut toujours considérer le contexte et les règles de son utilisation, qui sont en général livrés avec la description formelle de l'algo.
Par exemple, le contexte bancaire et les règles (lois et/ou décrets) régissant la manière d'arrondir et la précision des nombres à virgule.
Dans ce cas, 5 lignes peuvent à priori parfaitement suffirent.
La méthode de WhiteHippo est utile ... lorsqu'il n'existe pas de telles règles :)
1 nov. 2007 à 12:07
Mais tu as raison, quitte à prendre des précautions, autant toutes les prendre.
Sinon, l'autre moyen c'est de séparer les calculs (un calcul sur e, l'autre sur la constante qu'il y a derrière) et de faire la soustraction avec une méthode CariKinder.
31 oct. 2007 à 19:46
Ce qui suit, fruits d'expériences passées, n'a pas été testé dans ce cas spécifique par faute de temps, alors soyez indulgent si erreur il y a ;)
Pour utiliser les flottants de la façon la plus propre possible, il faudrait utiliser TOUTES les exceptions disponibles par le FPU. Hors ce n'est pas le cas par défaut en Delphi.
Pour activer toutes les exceptions, il faut :
Mask := SetExceptionMask( [] );
La variable Mask étant définie comme suit :
var
Mask : TFPUExceptionMask ;
Ensuite, intercepté les exceptions :
try
// calculs ici
except
on E : EMathError do
begin
case E.ExceptionRecord.ExceptionCode of
STATUS_FLOAT_INEXACT_RESULT :
// Le résultat de l''opération ne peut pas être représenté
// par une fraction décimale.
;
STATUS_FLOAT_INVALID_OPERATION :
// Opération sur nombres flottants invalide.
;
STATUS_FLOAT_STACK_CHECK :
// Débordement de pile
;
STATUS_FLOAT_DIVIDE_BY_ZERO :
// Division par 0
;
STATUS_FLOAT_OVERFLOW :
// Dépassement de capacité. Des chiffres significatifs sont
// perdus par manque de précision dans le format défini.
// Le type n'a pas suffisamment de place pour stocker la valeur.
;
STATUS_FLOAT_UNDERFLOW :
// Dépassement de capacité. Le calcul a donné un nombre trop petit pour
// être stocké dans le type défini.
;
STATUS_FLOAT_DENORMAL_OPERAND :
// Nombre dénormalisé.
;
ELSE
// AUTRE EXCEPTION
;
end ;
end ;
end ;
N.B. Ne pas oublier de remettre le masque à la fin :
SetExceptionMask( Mask ) ;
Avec TOUTES les exceptions actives, les boucles ne s'executeront alors plus jusqu'à la fin. Une exception sera levée en cours. Laquelle ? A vous de travailler :P
N.B. Pour ceux qui seront intéressés de tester tout ça, il faudra également jouer avec TFPUPrecisionMode et TFPURoundingMode.
!! ATTENTION !! En activant TOUTES les exceptions, vous constaterez que cela implique une gestion autrement plus rigoureuse des flottants que celle existante par défaut en Delphi. A titre d'exemple, un simple appel à une fonction comme la fonction Exp peut se solder par une exception de précision !!
Cordialement.
31 oct. 2007 à 19:10
31 oct. 2007 à 17:41
Ce qui fait que, pour n = 25, on aura 25!, soit 620'448'401'733'239'439'360'000
Alors, forcément, pour avoir de la précision sur le calcul final, il faut que tu aies e avec au moins 24 chiffres significatifs, ce qui n'est pas gagné d'avance vu le nombre de décimales que permettent les nombres flottants.
Voila donc "l'oubli": adapter son calcul à la capacité de sa machine. Et éviter à tout prix les suites définies par récurrence, sous peine de perdre en précision à chaque tour de boucle.
31 oct. 2007 à 17:20
Ou t'ouvres un livret bleu.
31 oct. 2007 à 16:44
Mais ton exemple est parfait,
Conclusion: faut faire du calcul formel !! ça irait même plus vite que de calculer avec des nombres à 100 chiffres significatifs.
Au moins là, t'es sûr de ton coup !
31 oct. 2007 à 16:30
Donc, ça fait 25 multiplié par 4 fois d' affilé.
Un peu bourrin je sais, mais faut bien se chauffer en cette saison froide .
Astuce: J' ai utilisé Delphi: Je pratique Delphi, moi aussi ! lol
31 oct. 2007 à 16:20
J' ai fait un petit résumé des calculs.
S' il y a un problème d' affichage, copier coller dans le notepad et seleccionner la police courrier New!!!
Fichier d' aide DELPHI :
Real48 2.9 x 10^-39 .. 1.7 x 10^38 11-12 6
Single 1.5 x 10^-45 .. 3.4 x 10^38 7-8 4
Double 5.0 x 10^-324 .. 1.7 x 10^308 15-16 8
Extended 3.6 x 10^-4951 .. 1.1 x 10^4932 19-20 10
Comp -2^63+1 .. 2^63 -1 19-20 8
Currency -922337203685477.5808.. 922337203685477.5807 19-20 8
Ligne Real Single Double Extended
-------------------------------------------------------------------------------------------
1 0.718282 0.718282 0.718282 0.718282
2 0.436564 0.436564 0.436564 0.436564
3 0.309691 0.309691 0.309691 0.309691
4 0.238764 0.238765 0.238764 0.238764
5 0.193819 0.193824 0.193819 0.193819
6 0.162916 0.162943 0.162916 0.162916
7 0.140415 0.140600 0.140415 0.140415
8 0.123323 0.124802 0.123323 0.123323
9 0.109911 0.123215 0.109911 0.109911
10 0.099109 0.232147 0.099112 0.099112
11 0.090200 1.553619 0.090234 0.090234
12 0.082405 17.643433 0.082808 0.082808
13 0.071260 228.364624 0.076507 0.076507
14 -0.002362 3196.104736 0.071100 0.071093
15 -1.035431 47940.570313 0.066493 0.066392
16 -17.566889 767048.125000 0.063894 0.062274
17 -299.637119 13039817.000000 0.086192 0.058657
18 -5394.468140 234716704.000000 0.551450 0.055829
19 -102495.894656 4459617280.000000 9.477546 0.060751
20 -2049918.893112 89192341504.000000 188.550924 0.215029
21 -43048297.755371 1873039196160.000000 3958.569412 3.515602
22 -947062551.618164 41206864150528.000000 87087.527059 76.343250
23 -21782438688.218750 947757883850752.000000 2003012.122351 1754.894755
24 -522778528518.500000 22746189749288960.000000 48072289.936418 42116.474110
25 -13069463212960.000000 568654735142289408.000000 1201807247.410449 1052910.852757
Le problème est directement lié à la taille em byte de la nature de la variable qui va influencer sur le stockage de la valeur, mais ça vous avez déjá tous compris.
Le problème soulevé para Albedo039 je m' y suit confronté plusieurs fois!
" ??? Mais quand doivent-ils calculer la TVA ???
:)
1) (somme des prix HT)* Taux de TVA
2) (Prix HT 1)*TVA + (Prix HT 2)*TVA + ..."
Disons qu' au Portugal on trouve les 2 méthodes en fonctionnement, tout dépend comme tu dis du nombre de décimaux dans le prix HT qui fait foirer le total de la TVA !!!
A+
31 oct. 2007 à 15:39
J'ai par contre une légère anxiété quant au pauvre bougre qui est volontaire pour un voyage vers la lune.
Neil Armstrong a eu du bol!
Pour se libérer du caractère anxiogène des types flottants, j'ai effectué le calcul sur des chaînes. Donc sans aucun arrondi.
Voici le résultat avec e-1 = 1,7182818285
1 = 0.7182818285
2 = 0.436563657
3 = 0.309690971
4 = 0.238763884
5 = 0.19381942
6 = 0.16291652
7 = 0.14041564
8 = 0.12332512
9 = 0.10992608
10 = 0.0992608
11 = 0.0918688
12 = 0.1024256
13 = 0.3315328
14 = 3.6414592
15 = 53.621888
16 = 856.950208
17 = 14567.153536
18 = 262207.763648
19 = 4981946.509312
20 = 99638929.18624
21 = 2092417511.91104
22 = 46033185261.04288
23 = 1058763261002.98624
24 = 25410318264070.66976
25 = 635257956601765.744
Normalement, si je m'a pas trompé, le potage est exempt de couille.
Et avec e-1 = 1,71828182845904523536028747135266249775724709369995
1 = 0.718 281 828 45904523536028747135266249775724709369995
2 = 0.4365636569180904707205749427053249955144941873999
3 = 0.3096909707542714121617248281159749865434825621997
4 = 0.2387638830170856486468993124638999461739302487988
5 = 0.193819415085428243234496562319499730869651243994
6 = 0.162916490512569459406979373916998385217907463964
7 = 0.140415433587986215848855617418988696525352247748
8 = 0.123323468703889726790844939351909572202817981984
9 = 0.109911218335007541117604454167186149825361837856
10 = 0.09911218335007541117604454167186149825361837856
11 = 0.09023401685082952293648995839047648078980216416
12 = 0.08280820220995427523787950068571776947762596992
13 = 0.07650662872940557809243350891433100320913760896
14 = 0.07109280221167809329406912480063404492792652544
15 = 0.0663920331751713994110368720095106739188978816
16 = 0.0622725308027423905765899521521707827023661056
17 = 0.0586330236466206398020291865869033059402237952
18 = 0.0553944256391715164365253585642595069240283136
19 = 0.0524940871442588122939818127209306315565379584
20 = 0.049881742885176245879636254418612631130759168
21 = 0.047516600588701163472361342790865253745942528
22 = 0.045365212951425596391949541399035582410735616
23 = 0.043399897882788717014839452177818395446919168
24 = 0.041597549186929208356146852267641490726060032
25 = 0.0399387296732302089036713066910372681515008
Sauf erreur de ma part, il semble que y'a pas que les types flottants qui font chier!
Au secour, Évariste!!!
31 oct. 2007 à 15:25
C'est des flottants Buzz l'eclair!
VERS L'INFINI ET AU DELAAAAA!
31 oct. 2007 à 12:16
--------------------
Il existe un autre problème bien plus subtil en ce qui concerne les "finances":
le calcul de la TVA.
En l'occurrence, beaucoup de logiciels affichent des factures ayant plusieurs produits et leurs prix...
??? Mais quand doivent-ils calculer la TVA ???
:)
1) (somme des prix HT)* Taux de TVA
2) (Prix HT 1)*TVA + (Prix HT 2)*TVA + ...
Dans beaucoup de cas, le résultat est identique. Mais (parcequ'il y a un "mais") pas toujours !
C'est dû à la manière et le moment d'arrondir les montants et au nombre de chiffres significatifs utilisés....
AFAIK, seul la solution de type 2) est valable:
http://www.legalbiznext.com/droit/La-facturation-electronique-la
http://rfcomptable.grouperf.com/article/0298/ms/rfcompms0298fisfac01.html
http://www.legifrance.gouv.fr/WAspad/UnTexteDeJorf?numjo=BUDF0300016D
Il reste le problème de l'arrondi... ;)
31 oct. 2007 à 10:15
Pas très doués ces types flottants.
Mais en même temps, c'est ta valeur initiale e-1 qui pose problème. Si tu avais mis autre chose (je sais bien que tu l'as fait exprès ^^), par exemple 1.8, tu serais multimilliardaire. Avec 1.6, tu serais plus endetté que l'État français...
Le problème est donc du à l'arrondi de la dernière décimale, et qui donc détermine la précision. Mais sur le coup, tu as raison, chaque décimale compte, puisqu'une toute petite erreur fait partir vers les infinis très rapidement !!
D'ailleurs, c'est quoi le terme général de cette suite ?
Bravo pour cette démonstration de la faiblesse de nos ordis, ça fait du bien de faire quelques calculs à la main...
31 oct. 2007 à 10:15
(je suis pas banquier, mais j'ai déjà progé des logiciels financiers)
Le banquier, y travaille au burin! Y découpe tout ce qui dépasse au moins une fois par an.
en d'autres termes, il utilise seulement un nombre restreint de chiffres significatifs et il arrondit au besoin.
Donc:
pour tout problème périodique (annuaire/mensuel...), la formule de calcul "simple" (purement mathématique) n'est pas utilisable.
Conclusion:
ce n'est pas un problème de type de flottant, c'est une erreur de logique du programmeur ;)
31 oct. 2007 à 00:55
2 = 0,43656365691809
3 = 0,309690970754271
4 = 0,238763883017086
5 = 0,193819415085428
6 = 0,16291649051257 >> Currency hors service
7 = 0,140415433587987
8 = 0,123323468703892
9 = 0,109911218335032 >> Single hors service
10 = 0,0991121833503217
11 = 0,0902340168535391
12 = 0,0828082022424692
13 = 0,0765066291520997
14 = 0,071092808129396
15 = 0,06639212194094 >> Real48 hors service
16 = 0,0622739510550403 >> Double hors service
17 = 0,0586571679356851
18 = 0,0558290228423317
19 = 0,0607514340043025
20 = 0,21502868008605
21 = 3,51560228180705
22 = 76,3432501997551
23 = 1754,89475459437
24 = 42116,4741102648
25 = 1052910,85275662
y'a comme une couille dans le potage en effet.
30 oct. 2007 à 23:38
30 oct. 2007 à 23:14
Parce que c'est pas mon style de foncer sans préliminaires.
Faudrait pas essayer de me faire passer pour un gougnafier.
Tout dans la finesse et la délicatesse, le père japee. L'approche feutrée, la démarche légère. La main ferme et assurée, mais toujours dans un gant de velours.
Alors si j'y ai explosé l'exposant, ça ne peut être que dans le feu de l'action (parce que 20 fois, quand même ^^).
30 oct. 2007 à 22:40
Tu dépasses là, non point mon entendement, mais la capacité du type Currency, qui, s'il dipose d'une mantisse d'un fort bel accabit, souffre néanmoint d'un déficit notoire quant à la taille de son exposant.
En gros, si tu lui laisse la mantisse froide, tu lui explose l'exposant ...
30 oct. 2007 à 22:07
Si j'étais ton banquier, j'aurais utilisé le type Currency, et tes économies auraient crashé la 21ème année. Désolé ^^
Mais je suis certainement moins dégourdi que ton banquier...
En tout cas, voilà de quoi méditer pendant les longues soirées d'hiver qui approchent.
P-S: faut quand même que je comprenne pourquoi ça crashe à la 21ème boucle avec une opération en virgule flottante incorrecte (j'obtiens 44 209 578 480 511 à la 20ème itération et puis plouf !).