1 pièce(s) jointe(s)
Convertir double en char* avec une precision full range
Bonjour,
dans le but de m'exercer à travailler avec des doubles, j'ai décidé de refaire la fonction modf.
Mon modf fonctionne impeccablement quand je travaille avec des petits nombre style 3.25, 15.258, etc.
Cependant, lorsque je travaille avec des grands nombres, mon résultat diffère du modf original.
Je vous envoie un screen pour que vous compreniez bien.
Pièce jointe 430261
Je ne comprends pas comment cela se fait-il.
Je vous mets le code ci-dessous. Le principe est assez simple, je convertis uniquement la partie entière du nombre en chaine de caractère. Lorsque j'ai cela, je le reconvertis en double afin de ne plus avoir de chiffres après la virgule. Grâce à cela, je possède déjà la partie entière que je pourrais renvoyer. Ensuite pour la partie fractionnaire, je fais "nombre reçu - partie entière".
Mais je pense qu'il y a quelque chose que je fais mal au moment de la transformation de double a char*. Peut-être n'ai-je pas encore tout compris a la façon dont on peut travailler avec des doubles ?
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#include <float.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
/*
** Fonction exposant
*/
static long double my_exp(double n, int exp)
{
long double value_exp;
int i;
value_exp = n;
i = 0;
if (exp == 0)
return (1.0);
while (i < exp - 1)
{
value_exp *= n;
i++;
}
return (value_exp);
}
/*
** Fonction permettant de compter le nombre de chiffres avant la virgule
** afin de creer une bonne taille de tableau avec malloc()
*/
static int set_before_comma(double n)
{
int nb_before_comma;
double a;
nb_before_comma = 0;
a = 1.0;
if (n < a)
return (1);
while (n >= a && a <= DBL_MAX)
{
nb_before_comma++;
a *= 10.0;
}
return (nb_before_comma);
}
/*
** Fonction permettant de diviser et stocker dans des doubles la partie entiere et la partie fractionnaire
** du nombre "double x"
*/
static int exploder(double x, double *ipart, double *fpart, char *stringx)
{
int i;
*ipart = 0;
i = 0;
if (x < 0)
x *= -1;
if (!isdigit(stringx[0]))
i++;
while (stringx[i])
{
*ipart *= 10;
*ipart += stringx[i] - 48;
i++;
}
*fpart = x - *ipart;
if (stringx[0] == '-')
{
*ipart *= -1;
*fpart *= -1;
}
return (1);
}
/*
** Fonction qui convertit la partie entière du nombre x en chaine de caractère
*/
static int intdtoa(double x, int is_neg, double *ipart, double *fpart)
{
int size_array;
char *stringx;
double nb;
int i;
i = 0;
nb = x;
if (is_neg)
nb *= -1;
size_array = set_before_comma(nb);
if (!(stringx = (char*)malloc(sizeof(char) * (size_array + is_neg + 1))))
return (0);
stringx[size_array + is_neg] = '\0';
if (is_neg)
stringx[i++] = '-';
nb /= my_exp(10, size_array - 1);
while (i < size_array)
{
stringx[i] = ((int)nb) + 48;
nb *= 10;
nb -= ((stringx[i] - 48) * 10);
i++;
}
exploder(x, ipart, fpart, stringx);
return (1);
}
double my_modf(double x, double *intpart)
{
double fractpart;
int is_neg;
is_neg = 0;
if (x < 0)
is_neg = 1;
if (x == DBL_MAX)
{
*intpart = DBL_MAX;
fractpart = 0.000000;
}
else if (x == -DBL_MAX)
{
*intpart = -DBL_MAX;
fractpart = -0.000000;
}
else
{
fractpart = 0;
intdtoa(x, is_neg, intpart, &fractpart);
}
return (fractpart);
} |
Voila, j'espère avoir été le plus clair, si vous avez des questions, n'hésitez pas !
Bien à vous,
Boris