est-il possible de stocker zéro négatif dans une partie imaginaire du float complexe C99?
Comment je devrais initialiser statiquement des constantes complexes avec une partie imaginaire signée? p>
J'ai un petit exemple, mais je peux ' T Comprendre, pourquoi A code> et
C code> sont identiques et pourquoi
-std = c99 code> change les résultats. p>
$ cat zero1.c
int main() {
float _Complex a;a = 0.0 + (__extension__ 0.0iF);
float _Complex b;b = 0.0 + (__extension__ -0.0iF);
float _Complex c;c = -0.0 + (__extension__ 0.0iF);
float _Complex d;d = -0.0 + (__extension__ -0.0iF);
printf("a= 0x%016llx\n", *(long long*)(&a));
printf("b= 0x%016llx\n", *(long long*)(&b));
printf("c= 0x%016llx\n", *(long long*)(&c));
printf("d= 0x%016llx\n", *(long long*)(&d));
}
$ gcc-4.5.2 -w -std=c99 zero1.c ; ./a.out
a= 0x0000000000000000
b= 0x0000000000000000
c= 0x0000000000000000
d= 0x0000000080000000
$ gcc-4.5.2 -w zero1.c ; ./a.out
a= 0x0000000000000000
b= 0x8000000000000000
c= 0x0000000000000000
d= 0x8000000080000000
5 Réponses :
Cela concerne le comportement de point flottant IEEE tel que spécifié par la norme ISO C, qui est plus strict sur les zéros négatifs. La compilation d'une forme plus native permet au compilateur d'optimiser et de ne pas tenir compte des règles plus strictes, de telles choses. P>
Je ne me souviens pas des détails, mais cela est discuté en profondeur à l'annexe F de la norme ISO C99. PDF disponible à: http: //www.open-std .org / jtc1 / sc22 / wg14 / www / docs / n1124.pdf . p>
rétracté fort> p>
Désolé, je me suis souvenu de mal. La norme ISO C ne dicte apparemment rien des zéros négatifs. Il est probablement à voir avec la manière dont les opérations IEEE FP sont strictes. P>
L'annexe F de N1256 ne dit rien sur zéro négatif dans une partie imaginaire du complexe.
Désolé, je pensais que je me suis souvenu de ça. Il s'agit probablement d'une opération de comportement IEEE strict, puis.
LoadMaster, existe-t-il un PDF IEEE754 gratuitement disponible (E.G. Draft)?
Désolé, je ne peux pas localiser un. Quelqu'un avec Google-Fu plus puissant que moi peut probablement.
IEEE 754 n'aide pas, car il ne couvre pas les valeurs complexes ni l'arithmétique complexe.
Correct; IEEE-754 ne couvre pas l'arithmétique complexe (ni la norme d'origine de 1985 ni la norme révisée 2008). C99 Annexe G (surtout le signe de zéro) repose principalement autour des idées énoncées dans le papier de Kahan: "Branchez les coupures dans le plan complexe; ou: beaucoup d'ADO à propos de la signification de rien" (non disponible en ligne aussi loin que je suis conscient, malheureusement). L'annexe G n'est toutefois pas normative.
Voir << a href = "http://754r.ucbebest.org/" rel = "nOfollow noreferrer"> 754r.ucbbebest.org > pour le texte du 754-1985 et un brouillon (version 1.2.5 ) de 754-2008; Certaines changements importants ont été modifiés avant la version finale (1.9.0).
Utilisation de
GCC version 4.7.0 20110504 (expérimental) (GCC) (GCC) p>
sur Avec et sans donc je suppose que ceci est un bug de 4.5.2 qui a depuis été corrigé. Peut-être une recherche dans les listes de bugzilla et / ou de courrier gcc p> AS -0,0 + 0,0 est 0,0, sauf si le mode arrondi est rond vers une infinité négative. P> Par conséquent, pour générer le littéral (-0, 0), vous avez besoin de quelque chose comme p> Voir aussi PR 24581 p> p> cible: x86_64-inconnu-linux-gnu code> p>
-std = c99 code> impression p>
Non, Mystère principal I> est de trouver des documents normatifs sur la droite ( Standard B>) Comportement B>. De plus, les liens vers des bus / maillistes de GCC sont les bienvenus, à la fois pour les changements de 4.7.0 et à ~ 4,5 (GCC <4.4 n'a pas enregistré le signe de la partie imaginaire, il doit donc y avoir plusieurs correctifs). J'ai fait des recherches (peu) dans Maillist, mais ne trouvez rien.
Selon C99 (N1256 ANNEXE G) Les valeurs complexes ont la même sémantique pour les zéros signés que les parties constitutives réelles isolément. Ainsi, il semble clair que c'est un bogue dans la GCC.
... c'est-à-dire que l'annexe G ne contient rien qui suggérerait que la mise en œuvre est autorisée à gérer les zéros signés différemment dans des variables complexes que dans de véritables variables.
Après une creuse supplémentaire, il n'y a pas de bogue dans la GCC actuelle. J'ai édité mon post en conséquence.
Quelle est la bonne façon d'initialiser la variable _complex avec (+ 0 -0.0i) code>?
Si une mise en œuvre est conforme à l'annexe G et implémente les types est évaluée comme si la mise en œuvre ne fournit pas de parce que morale de l'histoire: si vous vous souciez du signe de zéro, n'utilisez pas d'arithmétique dans des initialiseurs complexes. Puisque vous utilisez GCC, vous pouvez le faire à la place: P> _imaginy code>, l'expression
(double) 0,0 + (double _Imaginaire) (- 0.0i) code> en fonction des règles de G.5.2 et des rendements
0,0 - 0.0i code>. P>
_Imaginary code> type (qui est autorisé) ou ne correspond pas à l'annexe G (également autorisée), cette expression est généralement évaluée comme suit: p>
0.0 - 0.0 code> est zéro em> zéro dans l'arrondi par défaut IEEE-754, la signature est perdue. P>
__real__ c = 0.0f;
__imag__ c = -0.0f;
fait La norme C1X à venir inclura le voir N1570 , §7.3. 9.3. P> _imaginy_i * -0.0 code> fonctionne mieux que
(__ extension__ -0.0if) code>? P>
CMLLX code> macros, qui "agissent comme si les types imaginaires pris en charge et les définitions étaient:
#define cmplx (x, y) ((double complexe) ((double) (x) + _imaginy_i * (double) (y) (Y)))) code>. " P>
Si c'est défini, ce sera dans
Oui, complexes.h a été inclus, mais c'est de très vieux glibc.
de l'annexe J (problèmes de portabilité): p>
J.1 Comportement non spécifié H2>
- Les éléments suivants sont non spécifiés:
[...]
- si [...] un zéro négatif devient un zéro normal lorsqu'il est stocké dans un objet (6.2.6.2). Li> ol> blockQuote>Cela va faire ce que vous voulez juste que plus compliqué. P>
J'ai testé mes compilateurs (5+) et chaque compilateur est capable de stocker une plaine de +0 ou -0 dans n'importe quelle partie du complexe, à la fois imaginaire et réel. Donc, le 6.2.6.2 est pour le soutien optionnel de zéro signé et ce support est ici dans chaque compilateur testé.
Il est potentiellement pertinent que sans ASTD = option GCC fonctionnera comme si vous aviez spécifié -STD = GNU89 ou -STD = GNU90 (ils sont identiques) afin que cela puisse être pertinent ici puisque les types _complex et _imaginaires sont de C99
Spudd86, non, le
gcc -std = gnu99 code> était identique que juste
gcc code>, comme je me souviens