|
Dernière réponse | |
---|---|
Sujet : [C] Precision de calcul -- débutant | |
snotling | Ouais j'ai compris en fait : printf("%.17lg", sin(M_PI)); Ca renvoie meme pas 0, donc mes problemes sont tout de suite resolus : ce ne sont plus des problemes, c'est la limite de la becane. :) Merci a tous. @+. |
Aperçu |
---|
Vue Rapide de la discussion |
---|
snotling | Ouais j'ai compris en fait : printf("%.17lg", sin(M_PI)); Ca renvoie meme pas 0, donc mes problemes sont tout de suite resolus : ce ne sont plus des problemes, c'est la limite de la becane. :) Merci a tous. @+. |
BENB | Bon le prog complet pour determiner quel niveau de precision donnent des differents types de donnees du C/C++
int main() { float epsm; double eps; long double eps2; for(epsm=1.0F; (1.0F+epsm)!=1.0F; epsm /= 2.0F); printf("%g\n",(double)(epsm)); for(eps=1.0; (1.0+eps)!=1.0; eps /= 2.0); printf("%g\n",eps); for(eps2 = 1.0L; (1.0L+eps2) != 1.0L; eps2/=2.0L); printf("%g\n",(double)(eps2)); } Le cas float est donne a titre d'exemple, puisque normalement les calculs sont fait en double puis tronque. ton prog, je reprends la version qui minimise le nombre d'addtions successives autant de sources de troncatures... for ( i = 0; i< n ; i++) { long double argument = (long double)(i)*(long double)(M_PI)*2.0L/((long double)(n)); long double result = (long double)(s)*sinl(argument)+(long double)(d) printf("%lg\n",(double)(resultat)); } s,n,d sont des doubles (stockage) mais les calculs sont faits en long double (additions, multiplication, divisions et sinus) donc avec une precision accrue... le resultat est affiche comme un double, la troncature est fait sur le resultat et non lors de calculs intermediaires... |
snotling |
|
BENB |
|
minusplus |
|
BENB |
|
snotling | Salut,
Bah en fait cette precision, je l'ai pas choisi, on ma l'a impose, c'est un programme que j'ai a faire pour mon 'assignment' de ce semestre. Un extrait : The generator must send a data stream representing a sequence of sine wave samples to stdout. Each sample should be should be sent as a double and followed by a new_line code so that, if sent to the screen, a single column of numbers is produced. Samples should have 17 decimal places of accuracy. Four parameters are required to specify the number sequence. They are: n: the number of samples per cycle (an int) s: the scale factor (a double) d: The offset (a double) y: the number of cycles to be sent (a double) The diagram below shows samples of a sine wave where y=2 cycles, n=16 samples per cycle, the scale factor s=1 and the offset d=0.5. In this case there are 32 samples generated. The amplitude of each sample is s * sin(a) + d where a is the angle for the sample. Be aware that the sin( ) function in math.h expects the angle in radians, not degrees. En totalite si vous voulez : http://joule.ee.port.ac.uk:5050/assignment_2001.pdf Voili voilo :) @+. [edtdd]--Message édité par snotling--[/edtdd] |
deathsharp | arf
avait pas caller que c t une variable :D |
BENB |
[edtdd]--Message édité par BENB--[/edtdd] |
deathsharp | eps est pas definie chez moi...
a ne pas oublier non plus le "bug" de tous les processeurs sur les virgules flotants |
BENB | for (eps = 1.0; (1.0+eps)!=1.0;eps /= 2); //sisi il y a un ; a la fin
cette simple ( :D ) ligne te donne la presision machine, c'est a dire la precision a attendre d'une addition. voici les valeurs que j'avais obtenu sur je ne sais quelle machine double 1.11022e-16 long double 9.62965e-35 tu as donc 16 chiffres significatif sur une addition de doubles, et 34 sur une addition de long doubles.... A voir sur ta machine... mais de toute evidence pour avoi tes 17 decimales les doubles sont un peu justes... a voir en long double avec des sinl et cosl mais la ca depend du compilo... [edtdd]--Message édité par BENB--[/edtdd] |
youdontcare | il n'y a pas vraiment moyen avec les flottants/doubles si tu veux 17 décimales après la virgule. à moins de te faire ta classe de nombre décimal et de calculer le sinus à coups de développements limités, tu n'auras jamais la précision que tu veux.
des libs doivent exister pour ça, chercher avec www.google.com pourquoi as-tu besoin d'autant de précision au fait ? |
snotling | Alors personne a une idee pour resoudre mon probleme ? ;-) |
snotling | Merci flo850, mais apparemment ca veux pas marcher ;-) J'ai toujours les meme imprecisions, et comme j'ai besoin de 17 decimales pres la virgule..... Jusqu'a 14 ca va (bien qu'il y ait un petit 1.224606...e-16 d'ou je ne sais ou) mais au dela les resultats sont pas les bons.
D'ailleurs, j'ai essaye avec M_PIl au lieu de M_PI et j'ai un beau 'variable non definie' alors qu'elle est bien dans mon math.h. Peut etre est ce que ca va vient du #ifdef __USE_BSD au lieu de #ifdef __USE_GNU ? Ca veut dire quoi ca ? |
deathsharp | moi g M_PI et M_PI2 (pi/2), M_PI4
pas de PI ni de M_PIl |
flo850 | mes excuses , je savais pas .
mais pour le reste , je crois que mon explicataion tient debout |
verdoux | J'ai M_PI et M_PIl (en long double) dans math.h |
flo850 | en C , tu ne travaille qu'avec des intervalles ( 1/9 ne peux pas etre codé exactement en binaire )
tu fasi a chaque fois un double (+imprecision) + un autre double( avec lui aussi une erreur ), donc a chaque tour de boucle , ton erreur augmente , ce qui peux donner des resultats abberrants . enfin ca c mon explication. pour arranger essaye ca : for ( i = 0; i< n ; i++) { printf("%lg\n",sin(i*M_PI*2/n)); } en plus , ca allège ton code ( moi j'aime pas les for qui font une ligne ) au fait , pi est defini en tant que PI dans math.h ( donc pourkoi M_PI) |
snotling | Salut,
Voila un petit prog de de debutant en C, ce que je comprends pas c'est pourquoi les valeurs ne tombent pas juste. Le programme sert juste a calculer des sinus et ce un certain nb de fois par periode, etc, enfin un truc basique quoi. #include <stdio.h> #include <math.h> int main() { int n=8; double s=1, d=0, y=1, a; // g besoin que ce soit des 'double', c impose, les autres variables sont la pour le nb de periodes, un decalage... for (a=0; a<y*2*M_PI; a=a+M_PI*2/n) { printf("%.20lg\t%.20lg\n", a, s*sin(a)+d); } } Et la sortie du programme, ca donne : 0 0 0.785398163397448279 0.70710678118654746172 1.570796326794896558 1 2.356194490192344837 0.70710678118654757274 3.141592653589793116 1.2246063538223772582e-16 3.926990816987241395 -0.70710678118654746172 4.712388980384689674 -1 5.497787143782137953 -0.70710678118654768376 Et donc la question est de savoir d'ou viennent toutes ces imprecisions. Merci. |