Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

nombres complexes

3 réponses
Avatar
Francois Lauze
Hello fr.comp.lang.c:

Une simple question. J'utilise <complex.h>, et ISO99:
puis-je modifier uniquement la valeur reelle ou imaginaire d'un complex?
I.e un accesseur pour la partie réelle ou complexe?

#include <complex.h>
...
double complex a = 3.0 + 2.0*I;
....
double f = cimg(a);
>>>>>>>>>>>>>>>
mais l'inverse, du type

cimg(a) = 4*f; /* pas possible cimg(a) ne peut être utilisé comme lvalue */


n'est pas défini, cimag est souvent une fonction "built-in"? (ça a l'air
de ça avec un gcc récent).

Je me retrouve à écrire : a = creal(a) + 4*f*I;
....




Par avance merci,
François

3 réponses

Avatar
Marc
Francois Lauze wrote:

Une simple question. J'utilise <complex.h>, et ISO99:
puis-je modifier uniquement la valeur reelle ou imaginaire d'un complex?
I.e un accesseur pour la partie réelle ou complexe?

#include <complex.h>
...
double complex a = 3.0 + 2.0*I;
....
double f = cimg(a);
>>>>>>>>>>>>>>>
mais l'inverse, du type

cimg(a) = 4*f; /* pas possible cimg(a) ne peut être utilisé comme lvalue */


n'est pas défini, cimag est souvent une fonction "built-in"? (ça a l'air
de ça avec un gcc récent).

Je me retrouve à écrire : a = creal(a) + 4*f*I;
....



Oui, il me semble que c'est bien ce qu'il faut faire.

Avec gcc, si je me souviens bien, on peut tricher et écrire __imag__ a
= 4 * f; mais il vaut mieux éviter.
Avatar
Antoine Leca
Francois Lauze écrivit :
Hello fr.comp.lang.c:

Une simple question. J'utilise <complex.h>, et ISO99:
puis-je modifier uniquement la valeur reelle ou imaginaire d'un complex?



Logiquement oui, puisque la représentation est obligatoirement la forme
cartésienne en tableau avec d'abord la partie réelle.

Mais ce n'est pas « joli ».


cimg(a) = 4*f; // pas possible [...]

Je me retrouve à écrire : a = creal(a) + 4*f*I;



D'abord, sommes-nous d'accord qu'il s'agit là d'une économie de 5
caractères (11 contre 16) ?

Ensuite, il y a de très bonnes chances qu'un compilateur de 2011 (qui
supporte les complexes) réécrive tout seul cela sous la forme
((double[2])a)[1] = 4*f;

Et je ne crois pas être le seul à penser que ta formulation est plus
claire à relire que la mienne...


Enfin, est-ce que tu attends que les compilateurs C99 permettent

cproj(z) /= 2;

Si oui, ÀMHA ton niveau d'espérance n'est pas en rapport avec le niveau
d'abstraction du langage C... ;-)

Si non, donc si tu ne t'attends pas à ce que C permette de manipuler
directement la forme polaire, tu fais donc l'hypothèse implicite que le
compilateur manipule toujours les nombres complexes en forme
cartésienne, même au milieu d'une expression ; et de plus que tu es
capable de mieux savoir que le compilateur la représentation des
données. Mais cela va à l'encontre des principes de fonctionnement des
compilateurs optimisateurs, qui ont besoin de la plus grande liberté
possible pour pouvoir donner de bons résultats.

Il se trouve ici que la représentation en mémoire est forcée par la
norme (cf. supra). Mais la représentation au sein d'une expression est
libre, exactement comme la représentation des 'double' au sein d'une
expression peut avoir une meilleure précision. Et il est plus productif
sur le long terme de donner au compilateur des indications exactes
quoique légèrement redondantes, que de chercher à le contraindre dans
les représentations, ce qui oblige l'optimisateur à devoir considérer
plus de cas et donc à proposer moins d'optimisations (la contrainte se
situant ici au niveau de force de travail... des implémenteurs).


Antoine
Avatar
Francois Lauze
On 02/01/2012 10:50, Antoine Leca wrote:
Francois Lauze écrivit :
Hello fr.comp.lang.c:

Une simple question. J'utilise<complex.h>, et ISO99:
puis-je modifier uniquement la valeur reelle ou imaginaire d'un complex?



Logiquement oui, puisque la représentation est obligatoirement la forme
cartésienne en tableau avec d'abord la partie réelle.

Mais ce n'est pas « joli ».


cimg(a) = 4*f; // pas possible [...]



Je me retrouve à écrire : a = creal(a) + 4*f*I;



D'abord, sommes-nous d'accord qu'il s'agit là d'une économie de 5
caractères (11 contre 16) ?



Je suis d'accord avec toi, ma question était plutôt autour du style,
lecture du code plus simple?

Ensuite, il y a de très bonnes chances qu'un compilateur de 2011 (qui
supporte les complexes) réécrive tout seul cela sous la forme
((double[2])a)[1] = 4*f;

Et je ne crois pas être le seul à penser que ta formulation est plus
claire à relire que la mienne...


Enfin, est-ce que tu attends que les compilateurs C99 permettent

cproj(z) /= 2;


Non, je ne m'y attends pas, c'est seulement que la représentation (reel,
imag) est naturelle et qu'on aurait pu imaginer d'avoir des accesseurs
en écriture aussi. Néanmoins je je peux bien comprendre ton point sur la
representation. J'ai d'ailleurs un peu joué avec différentes options
d'otimisation pour gcc, et il se passe clairement quelque chose.

En tout cas merci à tous les deux pour vos réponses.


François

--
Francois Lauze, Associate Professor, PhDs...
The Image Group, Institute of Computer Science (DIKU),
University of Copenhagen
tel: +45 35 32 14 65
email: