abs

abs - C++ - Programmation

Marsh Posté le 13-06-2005 à 14:29:51    

Bonjour à tous,  
:pt1cable: Coment faire pour calculer la valeur absolue de deux float?
Merci

Reply

Marsh Posté le 13-06-2005 à 14:29:51   

Reply

Marsh Posté le 13-06-2005 à 14:30:40    

Un cast non?

Reply

Marsh Posté le 13-06-2005 à 14:32:46    

std::abs

Reply

Marsh Posté le 13-06-2005 à 14:45:06    

float(abs(a-b)) me rend un entier,moi je cherche à garder les float et calculer leur valeurs absolue
j'ai pas compris ta réponse Taz

Reply

Marsh Posté le 13-06-2005 à 14:50:15    

::fabs(a-b);

Reply

Marsh Posté le 13-06-2005 à 14:56:24    

d_imane a écrit :

j'ai pas compris ta réponse Taz


 
Ben c'est pourtant simple ?
std::abs() fait ce que tu souhaites.

Reply

Marsh Posté le 13-06-2005 à 14:56:53    

That's it, Thanks fra0.

Reply

Marsh Posté le 13-06-2005 à 14:58:45    

Code :
  1. #include <cmath>
  2. #include <iostream>
  3. int main()
  4. {
  5.    std::cout << std::abs(1.0f - 3.14f) << '\n';
  6. }


 
fabs c'est le truc C parce que y a pas de surcharge. utilise std::abs sur n'importe quoi et ça ira.

Reply

Marsh Posté le 13-06-2005 à 15:03:42    

maintenant c'est beaucoup plus clair, je retiens ta proposition, merci

Reply

Marsh Posté le 13-06-2005 à 15:13:17    

but...il m'as sotie un message d'erreur

Code :
  1. float Region::ValRealSubdivision(float mediane,float *x, int dimx)
  2. { float *t,min;
  3.   t=new float[dimx];
  4. for(int i=0;i<dimx;i++)
  5.   //t[i]=fabs(x[i]-mediane);
  6.   t[i]=std::abs(x[i]-mediane);
  7.       min=t[0];
  8. for(i=0;i<dimx;i++)
  9. if(t[i]<min) min=t[i];
  10.   return (min+mediane);
  11. }


error C2039: 'abs' : is not a member of 'std'

Reply

Marsh Posté le 13-06-2005 à 15:13:17   

Reply

Marsh Posté le 13-06-2005 à 15:16:51    

#include <cmath>
ya une fuite dans ta fonction

Reply

Marsh Posté le 13-06-2005 à 15:21:33    

si si j'ai utilisé

Code :
  1. #include<cmath>
  2. #include<iostream>
  3. float Region::ValRealSubdivision(float mediane,float *x, int dimx)
  4. { float *t,min;
  5.   t=new float[dimx];
  6. for(int i=0;i<dimx;i++)
  7.       //t[i]=fabs(x[i]-mediane);  
  8.       t[i]=std::abs(x[i]-mediane);
  9.       min=t[0];
  10. for(i=0;i<dimx;i++)
  11.     if(t[i]<min) min=t[i];
  12.       return (min+mediane);
  13. }

Reply

Marsh Posté le 13-06-2005 à 15:23:20    

je parie que tu utilises Borland VC


Message édité par fra0 le 13-06-2005 à 16:30:09
Reply

Marsh Posté le 13-06-2005 à 15:26:17    

très simplement, tu peux encore améliorer :
 

Code :
  1. #include <algorithm>
  2. #include <cmath>
  3. #include <vector>
  4. class Region
  5. {
  6.         public:
  7.         static float ValRealSubdivision(float mediane, float *x, size_t dimx);
  8. };
  9. float Region::ValRealSubdivision(float mediane, float *x, size_t dimx)
  10. {
  11.         std::vector<float> t(dimx);
  12.         for(size_t i = 0; i < dimx; ++i)
  13.                 t[i] = std::abs(x[i] - mediane);
  14.         return mediane + *std::min_element(t.begin(), t.end());
  15. }

Reply

Marsh Posté le 13-06-2005 à 15:39:15    

quand ça marchera,
tu pourras même tout faire en évitant le stockage temporaire
et avec deux fois moins d'itérations.

Reply

Marsh Posté le 13-06-2005 à 16:05:20    

j'ai utliliser exactement ta fct Taz, et j'ai tjs le meme message d'erreur:'abs' : is not a member of 'std'
j'ulilise la biblio

Code :
  1. #include "stdafx.h"
  2. #include "base.h"
  3. //#include "coder.h"
  4. #include "Region.h"
  5. #include<cstdio>
  6. #include<cmath>
  7. #include <windows.h>
  8. #include<iostream>
  9. #include<ctime>
  10. #include<conio.h>
  11. #include<cstring>
  12. #include<stdlib.h>
  13. #include <fstream>
  14. #include <algorithm>
  15. #include <vector>
  16. using namespace std;

Reply

Marsh Posté le 13-06-2005 à 17:36:47    

Code :
  1. #include <algorithm>
  2. #include <cmath>
  3. #include <vector>
  4. #include <iterator>
  5. class Region
  6. {
  7. class ValRealSubdivisionIterator : public std::iterator<std::input_iterator_tag, float>
  8. {
  9.  const float *x;
  10.  float mediane;
  11.  public:
  12.  ValRealSubdivisionIterator(const float *px, float pmediane = float())
  13.   : x(px), mediane(pmediane)
  14.   { }
  15.  ValRealSubdivisionIterator& operator++()
  16.  {
  17.   this->x++;
  18.   return *this;
  19.  }
  20.  ValRealSubdivisionIterator operator++(int)
  21.  {
  22.   const ValRealSubdivisionIterator last(*this);
  23.   ++*this;
  24.   return last;
  25.  }
  26.  float operator*() const
  27.  {
  28.   return std::abs(*this->x - this->mediane);
  29.  }
  30.  bool operator==(const ValRealSubdivisionIterator &other) const
  31.  {
  32.   return this->x == other.x;
  33.  }
  34.  bool operator!=(const ValRealSubdivisionIterator &other) const
  35.  {
  36.   return not (*this == other);
  37.  }
  38. };
  39. public:
  40. static float ValRealSubdivision(float mediane, float *x, size_t dimx);
  41. static float ValRealSubdivision2(float mediane, const float *x, size_t dimx);
  42. };
  43. float Region::ValRealSubdivision(float mediane, float *x, size_t dimx)
  44. {
  45. std::vector<float> t(dimx);
  46. for(size_t i = 0; i < dimx; ++i)
  47.  t[i] = std::abs(x[i] - mediane);
  48. return mediane + *std::min_element(t.begin(), t.end());
  49. }
  50. float Region::ValRealSubdivision2(float mediane, const float *x, size_t dimx)
  51. {
  52. ValRealSubdivisionIterator first(x, mediane), last(x + dimx);
  53. return mediane + *std::min_element(first, last);
  54. }

pour faire joli

Reply

Marsh Posté le 13-06-2005 à 18:21:26    

std::not ?

Reply

Marsh Posté le 13-06-2005 à 18:33:23    

non, not le mot clef

Reply

Marsh Posté le 13-06-2005 à 18:53:00    

ok (...)

Code :
  1. // pr le fun,
  2.      float Region::ValRealSubdivision3(float mediane, const float *x, size_t dimx)
  3.      {
  4.          std::priority_queue<float, std::deque<float>, std::greater<float> > pq;
  5.          while(dimx--) pq.push(mediane+std::abs(x[dimx]-mediane));
  6.          return pq.top();
  7.      }

Reply

Marsh Posté le 13-06-2005 à 18:57:53    

c'est très très lent ton truc : tu maintiens un ordre pour rien.
 
edit : et tu as un recopies inutile. Seul avantage par rapport à la méthode initiale : ça ne fuit pas

Message cité 1 fois
Message édité par Taz le 13-06-2005 à 18:58:58
Reply

Marsh Posté le 13-06-2005 à 19:01:06    

mais qu'il est lourd celui là....
c'est pour le fun j'ai dit.
 
la solution la plus efficace est évidente

Reply

Marsh Posté le 13-06-2005 à 19:10:32    

pour le fun aussi  :D, histoire d'user le pauvre valarray

Code :
  1. float Region::ValRealSubdivision3(float mediane, const float *x, size_t dimx)
  2. {
  3.     std::valarray<float> t(x, dimx);
  4.     t -= mediane;
  5.     return mediane + t.min();
  6. }


 
edit: c'est quand meme une meilleur soltution ?


Message édité par skelter le 13-06-2005 à 19:12:09
Reply

Marsh Posté le 13-06-2005 à 19:15:11    

c toujours bon les solutions en 3 lignes
 
pour info, dans le files de priorité*, c'est le popage des éléments qui est lent plutôt que leur pushage (facteur 3 avec un vector, 10 avec une deque (dans des tailles cahemissables))
 

Reply

Marsh Posté le 13-06-2005 à 19:23:28    

Code :
  1. float Region::ValRealSubdivision3(float mediane, const float *x, size_t dimx)
  2. {
  3.         float min;
  4.         min = x[0];
  5.         for(size_t i = 1; i < dimx; ++i)
  6.         {
  7.                 const float v = std::abs(x[i] - mediane);
  8.                 if(v < min)
  9.                         min = v;
  10.         }
  11.         return mediane + min;
  12. }


 
 
quant à ton histoire de pop plus lent que push, elle ne veut rien dire, vu que ça dépend très largement de l'implémentation.
 
edit : avec un tas, on a d'ailleurs o(log(n)) en insertion et suppression
edit2 : encore heureux que top() est o(1)


Message édité par Taz le 13-06-2005 à 19:31:14
Reply

Marsh Posté le 14-06-2005 à 01:19:37    

Fais une macro qui fait (fVal<0.0f)?-fVal:fVal

Reply

Marsh Posté le 14-06-2005 à 09:34:46    

non mais là c'est plus rigolo :o

Reply

Marsh Posté le 14-06-2005 à 10:01:24    

Kyle_Katarn a écrit :

Fais une macro qui fait (fVal<0.0f)?-fVal:fVal


[:pingouino]

Reply

Marsh Posté le 14-06-2005 à 11:07:38    

Taz a écrit :


quant à ton histoire de pop plus lent que push, elle ne veut rien dire, vu que ça dépend très largement de l'implémentation.


 
teste avant d'être trop péremptoire....
 
quand à ton dernier code j'ai bien peur qu'il soir complètement faux.

Reply

Marsh Posté le 14-06-2005 à 11:10:51    

je comprends pas de quoi tu parles : vu que tu fais n push() et 1 top(), et que top() est o(1), tu te mouilles pas trop en disant que c'est les push() qui prennent du temps.
 
après on s'en fout que ça soit juste ou pas, c'est son algo après tout.

Reply

Marsh Posté le 14-06-2005 à 11:21:21    

justement,
je suis peut être pas très clair,
mais (chez moi, sur ma machine....)
aussi bizarre que cela puisse paraître
ce sont les pop qui prennent du temps

Reply

Marsh Posté le 14-06-2005 à 11:31:26    

mais tu ne fais pas de pop() :o

Reply

Marsh Posté le 14-06-2005 à 11:50:40    

donc la méthode "fun" est efficace
cqfd

Reply

Marsh Posté le 14-06-2005 à 11:59:36    

ben non.
 
utilisation mémoire : n
complexité : n x log(n)
 
alors que l'opération est clairement o(n). C'est la pire des solutions proposées ici.

Reply

Marsh Posté le 14-06-2005 à 12:06:28    

:pt1cable:  
 
que fais ton ValRealSubdivision3 quand x[0]==-1e9f ?

Reply

Marsh Posté le 14-06-2005 à 12:39:27    

je vois pas le problème

Reply

Marsh Posté le 14-06-2005 à 13:26:41    

d'après ton code :  
v : n'est jamais (strictement) négatif
si x[0] est négatif,
v<min : est toujours faux,
 
ta boucle ne sert à rien.
 
pour *x==-1e9f, ton code renvoit mediane - 1 millard quelles que soient les valeurs du tableau (et y'a un autre petit problème)
 
edit 'f','t','a'


Message édité par fra0 le 14-06-2005 à 13:42:12
Reply

Marsh Posté le 14-06-2005 à 13:53:36    

encore une fois on s'en bat de son algo à la con, je sais pas ce que tu cherches à prouver.

Reply

Marsh Posté le 14-06-2005 à 14:54:40    

Si on revenait au pb de départ ??? Calculer une valeur absolue d'un type float
 
Question à 15€ et un mars : "Quelle est la différence entre -3.14f et 3.14f ?"
Alors...
 
Réponse : le bit de poid fort.
 
Comme une variable de type float est codée sur 4 octets, on peut donc créer sa propre fonction fabs qui remet à zéro ce bit.
 

Code :
  1. float myfabs(float p_fValue)
  2. {
  3. unsigned long l_nInt32 = *((unsigned long *)((void*)&p_fValue));
  4. l_nInt32 = l_nInt32 & 0x7fffffff;
  5. p_fValue =  *((float *)((void*)&l_nInt32));
  6. return p_fValue;
  7. }


---------------
[ XtremDev ] ~> http://membres.lycos.fr/photozit/
Reply

Marsh Posté le 14-06-2005 à 14:54:49    

fra0 a écrit :


edit 'f','t','a'


 
consonne

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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