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

Complexe avec fonction réelle

11 réponses
Avatar
Eric Levenez
Je viens de voir que l'on peut utiliser des flottants complexes avec les
fonctions réelles (non complexes). Est-ce un comportement normalisé
(utilisation du module ou de la partie réelle) ?

float complex z;
float x;

x = sinf(z);

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

10 réponses

1 2
Avatar
Kojak
Le Wed, 23 Jan 2008 22:32:12 +0100,

Je viens de voir que l'on peut utiliser des flottants complexes avec les
fonctions réelles (non complexes). Est-ce un comportement normalis é


Oui.

(utilisation du module ou de la partie réelle) ?

float complex z;
float x;

x = sinf(z);


sinf attendant un argument de type float, ce dernier
va être transtypé en float après avoir viré la partie
imaginaire (donc utilisation de la partie réelle).

--
Jacques.

Avatar
Antoine Leca
En news:C3BD70EC.C39B5%, Eric Levenez va escriure:
Je viens de voir que l'on peut utiliser des flottants complexes avec
les fonctions réelles (non complexes). Est-ce un comportement
normalisé (utilisation du module ou de la partie réelle) ?


6.3.1.7 Real and complex
[2] When a value of complex type is converted to a real type,
the imaginary part of the complex value is discarded and the
value of the real part is converted according to the
conversion rules for the corresponding real type.


Antoine

Avatar
Eric Levenez
Le 24/01/08 13:36, dans <47988647$0$2351$, « Antoine
Leca » a écrit :

En news:C3BD70EC.C39B5%, Eric Levenez va escriure:
Je viens de voir que l'on peut utiliser des flottants complexes avec
les fonctions réelles (non complexes). Est-ce un comportement
normalisé (utilisation du module ou de la partie réelle) ?


6.3.1.7 Real and complex
[2] When a value of complex type is converted to a real type,
the imaginary part of the complex value is discarded and the
value of the real part is converted according to the
conversion rules for the corresponding real type.


Merci de cette précision. J'avais raté ce paragraphe. C'est bizarre d'avoir
choisi de retourner la partie réelle. C'est sans doute plus simple à
implémenter.

Je parlais de cela car je me suis fait avoir. Je voulais taper :

cabsf(z);

Que j'ai malencontreusement écrit (par habitude) :

fabsf(z);

Et bien aucun warning et résultat erroné. Est-ce qu'il existe un warning
sous gcc 4 que l'on peut activer ?

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Kojak
Le Thu, 24 Jan 2008 20:11:59 +0100,

fabsf(z);

Et bien aucun warning et résultat erroné. Est-ce qu'il existe u n warning
sous gcc 4 que l'on peut activer ?


Une option du genre "-Wconversion" ?

Sinon, il est aussi possible de traiter au cas par cas avec
la directive pragma, par exemple :

#pragma GCC diagnostic warning "-Wconversion"

(à voir en fonction des contraintes de portabilité...)

--
Jacques.

Avatar
Thomas Nemeth
Kojak a tapoté :

Le Thu, 24 Jan 2008 20:11:59 +0100,
Sinon, il est aussi possible de traiter au cas par cas avec
la directive pragma, par exemple :

#pragma GCC diagnostic warning "-Wconversion"

(à voir en fonction des contraintes de portabilité...)


Voilà un autre problème intéressant : à quoi peut bien
servir #pragma dans la vraie vie ? "Le langage C - Norme
ANSI" de K&R spécifie, je cite :

"[...] #pragma [...] fait exécuter au processeur une action
dépendant de l'implémentation. Tout pragma non reconnu est
ignoré."

La section du bouquin se limite à ça ! La FAQ du groupe, quant
à elle, spécifie :

<<
C'est une indication pour le compilateur. Le préprocesseur
envoie cette directive sans la modifier. Le standard C89 ne
prévoit aucune directive standard, mais le préprocesseur
comme le compilateur sont sensés ignorer les directives
inconnues.

Le C99 définit trois #pragma qui permettent d'ajuster
le comportement du compilateur, quant au traitement des nombres
flottants et complexes.




Mais qui l'utilise et pourquoi ?


Thomas.


Avatar
Erwan David
Thomas Nemeth écrivait :

Kojak a tapoté :

Le Thu, 24 Jan 2008 20:11:59 +0100,
Sinon, il est aussi possible de traiter au cas par cas avec
la directive pragma, par exemple :

#pragma GCC diagnostic warning "-Wconversion"

(à voir en fonction des contraintes de portabilité...)


Voilà un autre problème intéressant : à quoi peut bien
servir #pragma dans la vraie vie ? "Le langage C - Norme
ANSI" de K&R spécifie, je cite :

"[...] #pragma [...] fait exécuter au processeur une action
dépendant de l'implémentation. Tout pragma non reconnu est
ignoré."

La section du bouquin se limite à ça ! La FAQ du groupe, quant
à elle, spécifie :

<<
C'est une indication pour le compilateur. Le préprocesseur
envoie cette directive sans la modifier. Le standard C89 ne
prévoit aucune directive standard, mais le préprocesseur
comme le compilateur sont sensés ignorer les directives
inconnues.

Le C99 définit trois #pragma qui permettent d'ajuster
le comportement du compilateur, quant au traitement des nombres
flottants et complexes.




Mais qui l'utilise et pourquoi ?


Je peux te donner des exemples que j'utilise :

#pragma section
définis la section du programme où se trouvera le code et/ou les
données.

J'indique ensuite au linker où doivent être placées les sections.
C'ets du complèteùent non portable, mais nécessaire dans le contexte :
le code du driver d'accès à la flash externe ne peut pas être placé dans
la flash externe...

On peut aussi avoir des #pragma pour changer le modèle de mémoire, voire
l'ABI (j'en ai un à disposition pour choisir le nombre de registres
utilisés pour le passage des arguments), pour packer les structures sur
les architectures qui supportent les accès non alignés, etc.

En fait #pragma c'est comme system() : ça existe, mais ce que ça fait
exactement dépend de la plateforme, c'est un point d'accès aux
spécificité de la plateforme.

--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé



Avatar
Eric Levenez
Le 25/01/08 14:37, dans ,
« Kojak » a écrit :

Le Thu, 24 Jan 2008 20:11:59 +0100,

fabsf(z);

Et bien aucun warning et résultat erroné. Est-ce qu'il existe un warning
sous gcc 4 que l'on peut activer ?


Une option du genre "-Wconversion" ?


Cette option m'affiche trop de warnings (à tort) dans bien des cas.

Exemple : je passe une variable float à sinf et j'ai un warning disant que
j'ai passé un double.

Sinon, il est aussi possible de traiter au cas par cas avec
la directive pragma, par exemple :

#pragma GCC diagnostic warning "-Wconversion"

(à voir en fonction des contraintes de portabilité...)


Comme le but serait d'afficher des warnings pour tous les cas où j'aurais pu
passer un complex à la place d'un float, je ne peux pas ajouter de pragma
ici et là car je ne sais justement pas où.

Je vais quand même utiliser ce -Wconversion une fois avec un "grep complex"
pour voir si il ne reste pas des cas foireux dans mon code...

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Kojak
Le Fri, 25 Jan 2008 21:03:16 +0100,

Le 25/01/08 14:37, dans ,
« Kojak » a écri t :

Une option du genre "-Wconversion" ?


Cette option m'affiche trop de warnings (à tort) dans bien des cas.

Exemple : je passe une variable float à sinf et j'ai un warning disa nt que
j'ai passé un double.


Curieux, en effet. J'ai testé rapidement avec gcc-4.2.3 et gcc-4.3.0
et, apparemment, le problème apparaît sur la 4.2.3 mais pas avec la
4.3.0. On dirait bien qu'il y a un bug quelque part avec le compilo.
Cela dit, je n'ai pas eu le temps de pousser les investigations plus
loin, donc à vérifier...

--
Jacques.


Avatar
Eric Levenez
Le 27/01/08 08:51, dans ,
« Kojak » a écrit :

Le Fri, 25 Jan 2008 21:03:16 +0100,

Le 25/01/08 14:37, dans ,
« Kojak » a écrit :

Une option du genre "-Wconversion" ?


Cette option m'affiche trop de warnings (à tort) dans bien des cas.

Exemple : je passe une variable float à sinf et j'ai un warning disant que
j'ai passé un double.


Curieux, en effet. J'ai testé rapidement avec gcc-4.2.3 et gcc-4.3.0
et, apparemment, le problème apparaît sur la 4.2.3 mais pas avec la
4.3.0. On dirait bien qu'il y a un bug quelque part avec le compilo.
Cela dit, je n'ai pas eu le temps de pousser les investigations plus
loin, donc à vérifier...


Un exemple de code :

#include <math.h>
int main(void)
{
float x = 0;
float y;
y = cosf(x);
(void)y;
return 0;
}

$ gcc -W -Wall -Wextra -stdÉ9 -O2 -Wconversion float.c -o float
float.c: In function Œmain¹:
float.c:6: warning: passing argument 1 of Œcosf¹ as Œfloat¹ rather than
Œdouble¹ due to prototype

J'ai ce warning avec gcc 4.0.1 sur Mac OS X et sur gcc 3.4.3 sur du
GNU/Linux PPC.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.



Avatar
Kojak
Le Sun, 27 Jan 2008 10:54:48 +0100,

Un exemple de code :

#include <math.h>
int main(void)
{
float x = 0;
float y;
y = cosf(x);


Juste pour vérifier, j'ai rajouté ici cette ligne :

y = cosf((double)x);

Et j'obtiens bien le bon comportement avec gcc-4.3.0

"
float.c: In function ‘main’:
float.c:7: attention : conversion to ‘float’ from ‘ double’ may alter its value
"

mais pas avec les version antérieurs. Il semble donc, que cela soit
un bug récurrent de gcc pré-4.3.0.

J'ai testé sous Mac OS X/PPC avec gcc-3.3 (qui, accessoirement, ne
reconnais pas -Wextra) et gcc-4.0.1 puis sous Linux/x86_64 avec gcc
version 4.1.3, 4.2.3 et 4.3.0.

Bref, il te reste toujours la possibilité de compiler/installer la
version 4.3.0 pour contrôler ton code, quitte à compiler au final
sous la version native. AMHA, cela devrait être plus sûr que de
hacker furieusement ton code à coup de "grep" et consorts (enfin,
tout dépend du volume de code à traiter).

Bon courage.

--
Jacques.

1 2