rendre un float positif (de la maniere la plus tordue)

rendre un float positif (de la maniere la plus tordue) - C - Programmation

Marsh Posté le 14-12-2006 à 14:59:19    

Salut a tous

 

J'ai un

Code :
  1. float a=rndf();

que je veux rendre positif si il est negatif.

 

Alors il y a plein de facons habituelles, notamment celle-ci:

 
Code :
  1. a=a<0.0f?-a:a;
 

Moi j'ai voulu reduire un maximum le nombre d'operations a faire pour arriver a un truc aussi simple alors je me suis dit "Ben y a qu'a tripoter le bit de signe et pis voila" et ca donne ca:

 
Code :
  1. (u32)(*(u32*)&a) &= ~(1<<31);
 

Mais je me demande si finalement ca vaut le coup niveau operations... (surtout qu'il doit y avoir moyen de reduire l'operation sur un u8 plutot qu'un u32)

 

Vous en pensez quoi?

Message cité 2 fois
Message édité par taoa le 14-12-2006 à 15:17:31
Reply

Marsh Posté le 14-12-2006 à 14:59:19   

Reply

Marsh Posté le 14-12-2006 à 15:03:55    

taoa a écrit :

Salut a tous
 
J'ai un

Code :
  1. float a=rndf();

que je veux rendre positif si il est negatif.
 
Alors il y a plein de facons habituelles, notamment celle-ci:
 

Code :
  1. a*=a<0.0f?-1.0f:1.0f;


 
Moi j'ai voulu reduire un maximum le nombre d'operations a faire pour arriver a un truc aussi simple alors je me suis dit "Ben y a qu'a tripoter le bit de signe et pis voila" et ca donne ca:
 

Code :
  1. (u32)(*(u32*)&a) &= ~(1<<31);


 
Mais je me demande si finalement ca vaut le coup niveau operations... (surtout qu'il doit y avoir moyen de reduire l'operation sur un u8 plutot qu'un u32)
 
Vous en pensez quoi?


 
que tu es tordu. Ta méthode habituelle  est en fait de l'ignorance :) Surtout que déclencher une multiplication pour un simple changement de signe, c'est démesuré. Un simple

Code :
  1. a = a < 0.0 ? -a : a;

suffit.
 
MAIS UTILISE DONC fabs
c'est ANSI donc portable, lisible et performant (certains processeurs ont une instruction pour faire ça).

Reply

Marsh Posté le 14-12-2006 à 15:05:20    

j'aurais tendence à utiliser les fonctions standard (genre fabs() dans ce cas là) en me disant que s'il y a des optimisations à faire, les gens qui programment les bibliothèques sont plus qualifiés que moi pour le faire.
 
EDIT :  [:benou_grilled]


Message édité par franceso le 14-12-2006 à 15:06:22
Reply

Marsh Posté le 14-12-2006 à 15:16:49    

Taz a écrit :

certains processeurs ont une instruction pour faire ça


 
Soit plus clair. C'est genre quasi tous les processeurs, ou deux ou trois dans le monde? i.e. les intel/amd actuels le font-ils?

Reply

Marsh Posté le 14-12-2006 à 15:19:11    

C'est, genre, quasi tous les processeurs.

 

Et j'ajouterais qu'à moins que chaque cycle ne compte, ce genre de micro-optimisation est une pratique nuisible.


Message édité par Elmoricq le 14-12-2006 à 15:19:53
Reply

Marsh Posté le 14-12-2006 à 15:37:39    

Eh ben... les programmeurs sont super ouverts aux experimentations dites-donc.
 
Ma question est bien: quel est le cout en matiere d'operations?

Reply

Marsh Posté le 14-12-2006 à 15:38:41    

Pose-toi plutôt la question suivante : quel est le coût de maintenance à utiliser une méthode abscons et inattendue ?

Reply

Marsh Posté le 14-12-2006 à 18:41:30    

Votre question n'a pas grand sens, parce que vous ignorez le contexte d'execution.
 
Sur un x86, le flottant a de grande chance d'etre soit sur la pile fpu soit dans un registre SSE et il va vraisemblablement falloir au compilateur l'écrire en mémoire pour ensuite faire un 'et' avec un GPR; tout celà pour, vraisemblablement, le re-charger sur la pile ou un registre SSE. Lamentable.
 
Votre code, de plus, est une horreur question aliasing: les unions c'est pas fait pour les chiens.
 
Enfin des compilateur comme gcc savent parfaitement faire ce genre de bit twiddling, mais contrairement à vous ils le font à bon escient (par exemple de registre SSE à registre SSE).
 
Si vous êtes certain qu'a tout moment vos flottants restent du coté des GPR, alors il est envisageable de faire le changement de signe à la main; mais au travers d'une union (aliasing) et sur 32bits en simple précision pour eviter les problèmes de 'store-load forward'.
Avant que de vous lancer dans de tels micro-optimisations, je ne saurais trop vous conseillez de maitriser le langage machine.

Reply

Marsh Posté le 14-12-2006 à 19:06:05    

Code :
  1. ufloat a = 0f;
  2. while(a == 0f)
  3. {
  4.   try { a = rndf(); } catch {}
  5. }


 
ou même mieu pour bien avoir un float en sortie :D
 

Code :
  1. float a = 0f;
  2. while(a == 0f)
  3. {
  4.   try { a = (float)(ufloat)rndf(); } catch {}
  5. }


 
:whistle:
 
En théorie, ça marche non ?
 
(bon d'accord, je retourne à mon C# [:spamafote])


Message édité par MagicBuzz le 14-12-2006 à 19:09:32
Reply

Marsh Posté le 15-12-2006 à 11:50:38    

ouais MagicBuzz mais la tu perds la valeur d'origine de a. J'avais mis rndf histoire d'avoir un float quelconque, mais en fait je tiens a avoir une valeur particuliere, en la changeant en positive si elle ne l'est pas.
 
Pour les autres, je sais pas, j'ai du me tromper, j'ai mis ce message dans la categorie 'C', j'aurais du le mettre dans 'faites vous humilier'. Vous avez des annees d'experience en prog, vous connaissez tous les langages machines et les architectures par coeur, tant mieux pour vous. Mais plutot que d'ecraser tout le monde avec vos connaissances, ce serait sans doute mieux de les partager sans faire preuve d'une telle suffisance. La ca donne vraiment pas envie de poser des questions un peu techniques. Ya plein de chose interessantes dans ce que vous avez dit, mais cette facon de le faire degouterait n'importe qui.

Reply

Marsh Posté le 15-12-2006 à 11:50:38   

Reply

Marsh Posté le 15-12-2006 à 12:04:43    

sinon, y'a pas une fonction "sign()" en C ?
 
a = a * sign(a);
 
au moins c'est clair et simple.

Reply

Marsh Posté le 15-12-2006 à 12:08:41    

Tu as demandé ce qu'on en pensait. On te l'a dit.  
Comme l'échange de variables avec un xor, le fabsf rustique est re-découvert environ 48756 fois par jours en moyenne, selon une étude récente.
Ou alors c'était la compression absolue?

Reply

Marsh Posté le 15-12-2006 à 12:12:50    

tbp a écrit :

Comme l'échange de variables avec un xor

particulièrement contre-performant d'ailleurs.

Reply

Marsh Posté le 15-12-2006 à 12:13:13    

Ouais ben j'espere que y a pas de profs parmi vous sinon bonjour la pedagogie.

Reply

Marsh Posté le 15-12-2006 à 12:13:48    

MagicBuzz a écrit :

sinon, y'a pas une fonction "sign()" en C ?
 
a = a * sign(a);
 
au moins c'est clair et simple.


plus clair que fabs(a) ?

Reply

Marsh Posté le 15-12-2006 à 12:17:29    

"fabs()" chais pas ce que c'est.
 
float absolute ? dans ce cas, ouais, d'accord, j'ai rien dit ;)
 
à cause du rndf() du post original, je pensais que c'était un générateur de random positif, du coup j'ai pas fait le rapprochement ;)

Message cité 1 fois
Message édité par MagicBuzz le 15-12-2006 à 12:18:16
Reply

Marsh Posté le 15-12-2006 à 12:20:04    

ce qui nous amène tout simplement à "change de générateur de nombre pour renvoyer du positifi ou nul", sinon, ton 0 a une probabilité deux fois plus élevé de sortir.

Reply

Marsh Posté le 15-12-2006 à 12:37:26    

taoa a écrit :

Ouais ben j'espere que y a pas de profs parmi vous sinon bonjour la pedagogie.


 
[:el g]

Reply

Marsh Posté le 15-12-2006 à 12:40:28    

tbp a écrit :

Tu as demandé ce qu'on en pensait. On te l'a dit.  
Comme l'échange de variables avec un xor, le fabsf rustique est re-découvert environ 48756 fois par jours en moyenne, selon une étude récente.
Ou alors c'était la compression absolue?


 
La compression absolue a une fréquence d'apparition proche de Ackermann(4,2) fois par mois :/
Sinon pour en revenir au topic, TOUT les processeur fournisse une instruction spécfifique pour ça depuis
au moins les PII et les PPCG3 ... La dernière fois ou j'ai eu à ecrire cette cochonnerie, c'etais sur un micro-controlleur à la con ...

Reply

Marsh Posté le 15-12-2006 à 14:48:48    

Sinon, on l'a toujours pas explicite:
 
Ca coute quoi en instructions une application de masque sur 32 bits (probablement un registre quoi)?

Reply

Marsh Posté le 15-12-2006 à 14:51:25    

taoa a écrit :

Ca coute quoi en instructions une application de masque sur 32 bits (probablement un registre quoi)?


cette phrase ne veut rien dire.

Reply

Marsh Posté le 15-12-2006 à 14:54:06    

ça devient relou là...
 
si t'as envie de faire un abs() sur un float en un seul cycle, ouvre un topic ASM, appelle Harko, y va te causer en hexa et gtu te démerde pour foutre le code ASM dans ton programme.
 
tu vas pas nous faire une pendule à 52 coups juste pour ça...
 
on t'as déjà dit qu'il y a au bas mot, une cinquantaine de processeurs avec des instructions différentes sur le macher actuellement.
 
parmis toutes ces processeurs, nombre supportent les mêmes instructions, mais les décomposent en micro instructions différentes.
 
ensuite, il doit y avoir une 20 aines de compilos communs rien pour chaque OS, qui font générer du code différent pour chaque instruction.
 
sans parler ensuite des modules complémentaires diffusés par intel, amd et ibm qui se greffent aux compilos afin de forcer le compilo à faire un code plus optimisé pour leurs cpu.
 
alors à moins d'appeler les instructions cpu à la main, en espérant que chaque cpu connaîtra les instructions appelées, t'as aucune chance d'avoir une réponse réaliste à ta question.
 
 
 
à noter que si tu passes en mode réel au milieu de ton programme juste pour faire deux instructions, c'et carrément con, parceque le compilo va ajouter des centaines d'instructions avant et après afin de préparer l'environnement en mode réel.


Message édité par MagicBuzz le 15-12-2006 à 14:56:20
Reply

Marsh Posté le 15-12-2006 à 14:59:47    

genre sur powerpc, t'as même la négation de la valeur absolue comme instruction

Reply

Marsh Posté le 16-12-2006 à 14:18:18    

MagicBuzz a écrit :

"fabs()" chais pas ce que c'est.


Alors commence par ouvrir ton livre de C...
 
K&R2 Page 256 <math.h>
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-12-2006 à 00:23:53    

Emmanuel Delahaye a écrit :

Alors commence par ouvrir ton livre de C...
 
K&R2 Page 256 <math.h>


/me told : "je retourne à mon C#".
 
j'excècre le C au plus haut point, et je n'ai aucune envie d'apprendre ce langage.
j'ai suffisament de notions pour prendre plaisir à mettre mon grain de sel dans ce topic, mais absolument aucune envie d'en apprendre la moindre instruction [:spamafote]

Message cité 1 fois
Message édité par MagicBuzz le 18-12-2006 à 00:24:12
Reply

Marsh Posté le 18-12-2006 à 09:14:14    

- bonjour je m'appelle magicbuzz
<en coeur : bonjour magicbuzz>
- alors voila, je viens sur la catégorie langage C parce que je déteste ce langage et que je ne le connais pas
<ohhhhh :(>
- En effet MagicBuzz, c'est plutôt grave. Nous allons nous revoir à la séance suivante, hmm ?

 
MagicBuzz a écrit :


j'ai suffisament de notions pour prendre plaisir à mettre mon grain de sel dans ce topic

 

Pas vraiment, non.


Message édité par Elmoricq le 18-12-2006 à 09:14:54
Reply

Marsh Posté le 18-12-2006 à 10:17:47    

t'es vraiment trop... fermé comme gars.
 
y'a pas de contrat utilisateur qui m'oblige à être un killer en C pour participer aux topics C.
 
si je devais suivre ton raisonnement sur la cat SGBD par exemple, je serais bien seul... à part 4 ou 5 autres habitués de la cats, personne ne sait même ce qu'est un SGBD "ah bon, c'est pas un soft pour faire des sites web ?"
 
relis mes interventions sur ce topic. mise à part mon ignorance quand à la significations de fabs() dis-moi ce que j'ai dit comme ineptie.
plus marrant, le gars demande une "manière" (donc un algo), pas une syntaxe au caractère près.
 
ensuite, relis la phrase que tu cites. je parles des autres ? non, je parle de moi. "j'ai suffisament de notions pour prendre plaisir à mettre mon grain de sel dans ce topic". je parle de mon plaisir, pas du tiens. t'es dans ma tête pour dire que je suis incapable de prendre du plaisir à intervenir dans ce topic ?
 
bref, je dis ça, je dis rien... en tout cas, je vois que le C est un langage qui continue à être pratiqué par des abrutis qui s'imaginent que seuls eux sont capable de comprendre ce langage car ça ne fait bander qu'eux. ça c'est clair, c'est loin de me faire bander ce langage. par contre tu ferais bien de te méfier de ce que tu dis des autres, contrairement à toi, on n'a pas forcément besoin de maîtriser un langage sur le bout des ongles pour en comprendre le fonctionnement. et l'ouverture d'esprit est quelque chose qui manque visiblement aux programmeurs C, mais une qualité plutôt répendues pour ceux qui ne s'enlisent pas dans ce langage puriste.

Reply

Marsh Posté le 18-12-2006 à 14:22:42    

MagicBuzz a écrit :

t'es vraiment trop... fermé comme gars.
 
y'a pas de contrat utilisateur qui m'oblige à être un killer en C pour participer aux topics C.


 
Entre être un 'killer' et totalement incompétent, il y a de la marge. Et si on fait dans la caricature, avec d'un coté les abrutis fermés du C, il a quoi du coté de C# et Java? Des eunuques?


Message édité par tbp le 18-12-2006 à 14:23:31
Reply

Marsh Posté le 18-12-2006 à 15:19:58    

Je ne tiens pas à troller, on est lundi, et je suis trop vieux pour ces enfantillages.
 
Ne pas maîtriser chaque nom de fonction sur le bout des doigts ne fait pas d'une personne un incompétent. Désolé.
 
C'est d'autant plus vrai avec les langages plus évolués tels que le C# ou Java, où le périmètre des librairies "standard" est bien plus important, et de facto, impossible à maîtriser de A à Z.
 
Le C à été inventé à l'époque où "programmeur" et "codeur" étaient deux métiers différents. Le "programmeur" écrivait des troncs à partir d'algos conçus par l'analyste, puis le codeur pissait le code afin de boucher les trous, sans même en connaître le fonctionnement.
 
Pour cette raison, le C nécessite depuis toujours d'être extrêment pointu en ce qui concerne la syntaxe. Pourtant, le "programmeur" (qui n'avait que faire de la syntaxe) restait spécialisé C, et il ne faut pas l'oublier.
 
Maintenant, les métiers d'informatique ont largement évolués, et il est commun de trouver la même personne effectuer les tâches de chef de projet, d'analyste, de programmeur et de codeur. L'analyse d'un programme ou sa conception logique est totalement dépendante du langage choisi, et pourtant ne requiert pas du tout des connaissances "bas niveau" dans le langage. Il serait temps d'ouvrir les yeux et accepter de voir participer aux dialogues C des personnes qui n'ont pas 5 ans d'expérience sur ce langage.
 
Très franchement, je te renvoie à ce que j'ai demandé à Elmoricq : mise à part le coup de fabs() (et très franchement, c'est pas pour ce qu'on l'utilise cette fonction que c'est un requis de la connaître) où ai-je dit une connerie avant de me faire agresser de la sorte ?

Reply

Marsh Posté le 18-12-2006 à 15:26:07    

Non mais plus simplement, c'est comme si je venais répondre avec un machin Transac-SQL dans un topic Oracle, tu vois.  
Ca ne va pas plus loin que ça, et il n'est pas question d'élitisme ou autre ; c'est juste inutile et polluant pour l'initiateur du topic.

Reply

Marsh Posté le 18-12-2006 à 15:33:21    

Très franchement, tu viens poster du T-SQL dans un topic Oracle, je ne vois pas où est le problème (c'est justement là que je parle d'ouverture d'esprit).
 
Mise à part en C, on met toujours en avant l'algo, la façon de procéder. La syntaxe, ensuite, c'est que dale : n'importe quel nain est capable de lire et comprendre un programme écrit dans n'importe quel langage (mise à part l'ASM ou le C écrit comme un goret, parceque ça peut devenir rapidement imbittable -genre un while() qui fait le traitement avec déclaration d'une fonction statique dans les parenthèses, puis qui n'uilise pas le bloc car y'a plus rien à faire, comme j'ai pu trouver une fois).
 
Entre T-SQL et PL/SQL, mise à part un problème de syntaxe qui diffère très clairement, on retrouve à 95% les mêmes fonctions et les mêmes principes d'algo. Il n'est pas rare que dans la cat SGBD, des personnes répondent à un gars qui demande un coup de pouce pour une requête MySQL, une syntaxe Oracle en indiquant que la fonction appelée risque d'utiliser une syntaxe différente.
Ca n'empêche pas la personne d'avoir une réponse qui lui convient, et la débloquer.
 
Evidement, chaque langage ayant ses propres spécificités, la meilleure solution dans un langage n'est pas forcément la meilleur dans un autre. Mais dans ce topic "rendre un float positif (de la maniere la plus tordue)", à la base, moi ça ne me dérange pas de venir poster des "conneries" qui marchent. A la base, le gars y veut un truc à coucher dehors, au moins, avec mes méthodes de bourrins qu'on trouve dans les langages évolués, je suis sûr de lui en apporter pour son argent.
 
Je ne vois pas ce qu'il y a de mal à ça...

Message cité 1 fois
Message édité par MagicBuzz le 18-12-2006 à 15:33:37
Reply

Marsh Posté le 18-12-2006 à 16:47:58    

Je vais vous proposer 3 réponses :
- une pomme
- touche à ton cul
- sens ton doigt

Reply

Marsh Posté le 18-12-2006 à 17:32:52    

Célebrons donc la mort du bas niveau, qui par définition est bas et donc indigne,avec cette solution au problème qui satisfera tout le monde j'en suis sur.
 


a = sqrtf(a*a);

Reply

Marsh Posté le 18-12-2006 à 17:46:57    

c'est effectivement la définition mathématique de la valeur absolue dans R

Reply

Marsh Posté le 18-12-2006 à 18:03:04    

taoa a écrit :


Vous en pensez quoi?


 
T'as profilé ton programme pour être certain d'avoir besoin d'une telle micro-optimisation ?

Reply

Marsh Posté le 18-12-2006 à 19:10:59    

plustôt contre-optimisation :D

Reply

Marsh Posté le 18-12-2006 à 19:25:59    

bjone a écrit :

plustôt contre-optimisation :D


 
Pas forcément, dans le bon contexte.  
Mais déjà si on veut écrire du code efficace il faut éviter de facher le compilo d'entrée; l'aliasing c'est laid.
J'suis un peu rouillé en C, mais ça doit passer

Code :
  1. float foo(const float val) {
  2. union {
  3.  float f;
  4.  struct { unsigned int mantissa:23, exp:8, sign:1; };
  5. } a = { val };
  6. a.sign = 0;
  7. return a.f;
  8. }

Reply

Marsh Posté le 18-12-2006 à 19:37:54    

tbp a écrit :

Code :
  1. union {
  2.  float f;
  3.  struct { unsigned int mantissa:23, exp:8, sign:1; };
  4. }



Horriblement pas portable... Qu'est-ce qui ne va pas avec fabs() ? C'est fait pour et c'est portable...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-12-2006 à 19:45:24    

Emmanuel Delahaye a écrit :

Horriblement pas portable... Qu'est-ce qui ne va pas avec fabs() ? C'est fait pour et c'est portable...


C'est exactement aussi portable que

Code :
  1. (u32)(*(u32*)&a) &= ~(1<<31);

mais au moins ça ne chie pas dans les bottes du compilateur.
 
Maintenant parlons du contexte. Disons que je suis en plein radix sort sur des flottants et qu'explicitement je ne veux pas que ces saletés de flottants touchent la fpu...
 
Il est bien évident que cette approche est bien moins adéquate que ne le pensait l'initiateur.

Reply

Marsh Posté le 18-12-2006 à 21:00:31    

MagicBuzz a écrit :

où ai-je dit une connerie


peut-être quand tu as mis du try/catch dans un topic C...
 

MagicBuzz a écrit :

...avant de me faire agresser de la sorte ?


Il t'a pas agressé, il s'est juste un peu foutu de ta tronche avec beaucoup d'à propos. C'est pour le moins bizarre qu'un gars qui rode sur le topic C dise qu'il n'aime pas le C. Moi je n'aime pas Java et je n'y vais jamais et je reste cohérent avec moi-même.
 

MagicBuzz a écrit :

je parle de mon plaisir, pas du tiens. t'es dans ma tête pour dire que je suis incapable de prendre du plaisir à intervenir dans ce topic ?


On ne te reprochera absolument jamais de prendre plaisir à délirer en C. Tu auras donc la même politesse de ne pas reprocher aux autres de te vanner sur tes délires. Ainsi t'as tendu le baton et tu t'es fait fesser. C'est pas bien grave ni bien méchant et si t'as un peu d'humour tu acceptes, sinon de toute façon tout le monde se bat les balloches de tes jérémiades...

Message cité 2 fois
Message édité par Sve@r le 18-12-2006 à 21:55:25

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed