Je gère des grandeurs 'double'. Certaines sont déjà calculées, d'autres pas encore. Je cherche une solution élégante pour pouvoir les distinguées.
J'ai pensée à :
- associer un bool 'estElaboree' à chaque grandeur. Fonctionnellement c'est parfait, mais un peu lourd à gérer. Je double mon nombre de variables. Et puis il faut gérer la cohérence entre les grandeurs et les booléen à chaque ajout ou suppression de grandeurs.
-initialiser toutes mes grandeurs à une valeur spécifique constante (connue dès la compilation DOUBLE_NON_ELABOREE. Mais quelle valeur choisir ? :
. J'ai pensé à
const Double DOUBLE_NON_DEFINI = 1.0e31;
Ca marche, mais pas très élégant. Et si un jour un calcul donne pile poile 1.0e31 ?
. J'ai essayé
const Double DOUBLE_NON_DEFINI = numeric_limits::max();
Mais ça ne compile pas. Je pense que numeric_limits::max() n'est pas connu à la compilation, mais à l'exécution.
La solution doit fonctionner sous gcc, mais aussi être portable.
Vous avez des idées ?
(Nan?, inf?, définir la valeur comme n'étant pas constante peut-être ?).
Merci
# Nan, peut-être
Posté par Jean Bréfort (site web personnel) . Évalué à 3.
http://cvs.gnome.org/viewcvs/goffice/goffice/utils/go-math.c(...)
Autrement, il est bien sûr possible d'utiliser un bool, mais c'est plus élégant si c'est encapsulé dans une classe et encore mieux (question de goût ?) avec un template.
# Fais une classe
Posté par JoeBar . Évalué à 3.
Ce que tu cherches à représenter n'est pas un double, mais un objet à deux propriétés : une valeur et un caractère élaboré ou pas. Fais donc une classe doubleElaborable ou ce que tu veux qui contient un booléen et un double.
C'est très simple, et c'est propre (à mon avis).
PS : pour pouvoir les distinguer (mordre) ;)
[^] # utilise Nan du standart IEEE
Posté par EraZerg . Évalué à 4.
main() {
double d=NAN;
if(isnan(d)) {
printf("d est non défini\n");
}
d=-1;
d=sqrt(d);
if (isnan(d)) {
printf("d est non défini\n");
}
}
tu compiles avec gcc -D_ISOC99_SOURCE /tmp/essai.c -o /tmp/essai -lm
[^] # Re: utilise Nan du standart IEEE
Posté par pini . Évalué à 2.
Ça me paraît être une solution élégante.
# Double et C++
Posté par Obsidian . Évalué à 3.
En C++, tu peux définir une classe dérivant immédiatement de double pour éviter les transtypages et autres.
class ElaboratedDouble : public double
{
public:
bool defined;
}
Tu peux également redéfinir l'opérateur de casting (double) (même si redéfinir les opérateurs de casting pose toujours plus de problème que cela n'en résoud) et tenter de lancer une exception si la valeur n'est pas définie.
[^] # Re: Double et C++
Posté par dguihal . Évalué à 1.
ex :
class ElaboratedDoubleManager
{
char* double_defined_bitfield;
double* double_list;
ElaboratedDoubleManager(int size)
{
int taille_bitfield;
double_list=new double[size];
if (size % (sizeof char) == 0)
taille_bitfield = size / (sizeof (char));
else
taille_bitfield = size / (sizeof (char)) + 1;
double_defined_bitfield=new char[taille_bitfield];
}
...
}
# Merci à tous
Posté par locnet . Évalué à 1.
Des idées originales , des exemples compilables.
Je serais bien parti sur le NaN, car il implique de ne modifier que 2 lignes dans mon code. Mais il semble que ça ne soit pas compatible avec l'option -ansi que l'on m'impose. Et j'ai un peu peur de la portabilite.
Je pourrais faire une classe ou un template. Mais ça implique pas mal de changements.
Une variante :
typedef double* elaboredDouble;
ou
typedef boost::shared_ptr<double> elaboredDouble;
Cela me ramenne à la solution java.
C'est portable sans risque (au moins la première forme).
C'est transposable à tous les types de base.
Mais ça me demande pas mal de changement.
A suivre.
Encore merci.
[^] # Re: Merci à tous
Posté par EraZerg . Évalué à 2.
la norme ANSI est au niveau de ton code source,
la norme qu'on exploite est la norme des flottants IEEE
Autrement dit, tu recopie le code source de isnan et tu défini toi-même la constante NAN.
Ou alors si ça t'amuse tu les recode.
Je me suis amusé à ça l'autre jour. En gros pour qu'un double soit NaN il suffit de mettre 0x7ff dans les 12 premiers bits et n'importe quoi de non nul dans les autres. (cf norme)
Pareil pour faire isnan, il faut mettre deux trois Xor bien placés.
conclusion
La norme IEEE est implémentée au niveau des processeurs, ANSI c'est juste de la portabilité au niveau code source, rien ne t'empêche donc de recopier ou de reécrire la constante et la routine. :-)
[^] # Nan...
Posté par locnet . Évalué à 1.
avec un "union" ?
L'exemple de 'nan.h' n'est pas encouragant.
# define NAN (__builtin_nanf(""))
#elif defined__GNUC__
# define NAN \
(__extension__ \
((union { unsigned __l __attribute__((__mode__(__SI__))); float __d; }) \
{ __l: 0x7fc00000UL }).__d)
#else
# include <endian.h>
# if __BYTE_ORDER == __BIG_ENDIAN
# define __nan_bytes { 0x7f, 0xc0, 0, 0 }
# endif
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define __nan_bytes { 0, 0, 0xc0, 0x7f }
# endif
static union { unsigned char __c[4]; float __d; } __nan_union
__attribute_used__ = { __nan_bytes };
# define NAN (__nan_union.__d)
#endif
[^] # Re: Nan...
Posté par EraZerg . Évalué à 1.
main()
{
double a=1;
unsigned long long *b;
b=(unsigned long long *)&a;
*b=0x7ff0000000000001;
if (isnan(a)) {
printf("la valeur de a est %lf \n",a);
}
}
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.