J'essaye d'écrire une fonction dans le langage de programmation D pour remplacer les appels au strtold de C. (Justification: Pour utiliser strtold à partir de D, vous devez convertir les chaînes D en chaînes C, ce qui est inefficace.) Strtold ne peut pas être exécuté au moment de la compilation.) J'ai mis au point une implémentation qui fonctionne principalement, mais je semblent perdre de la précision dans les bits les moins significatifs.Comment convertir les chaînes en flotteurs avec une précision parfaite?
Le code de la partie intéressante de l'algorithme est ci-dessous et je peux voir d'où vient la perte de précision, mais je ne sais pas comment m'en débarrasser. (J'ai omis beaucoup de parties du code qui n'étaient pas pertinentes pour l'algorithme de base pour sauver les gens qui lisent.) Quel algorithme de chaîne à flotteur garantira que le résultat sera le plus proche possible du numéro IEEE ligne à la valeur représentée par la chaîne.
real currentPlace = 10.0L ^^ (pointPos - ePos + 1 + expon);
real ans = 0;
for(int index = ePos - 1; index > -1; index--) {
if(str[index] == '.') {
continue;
}
if(str[index] < '0' || str[index] > '9') {
err();
}
auto digit = cast(int) str[index] - cast(int) '0';
ans += digit * currentPlace;
currentPlace *= 10;
}
return ans * sign;
Aussi, j'utilise les tests unitaires pour l'ancienne version, qui a fait des choses comme:
assert(to!(real)("0.456") == 0.456L);
Est-il possible que les réponses étant produites par ma fonction sont en fait plus précis que la représentation que le compilateur produit lors de l'analyse d'un littéral en virgule flottante, mais le compilateur (écrit en C++) est toujours en accord avec strtold car il utilise strtold en interne pour analyser les littéraux en virgule flottante?
veuillez indiquer d'où vous pensez que provient la perte de précision. –
@John: La perte de précision vient de deux endroits: 1. Nous arrondissons chaque fois que nous exécutons la ligne 'ans + = digit * currentPlace', et 10^je ne peux pas être représenté exactement dans IEEE 754 pour la plupart des entiers i. – dsimcha
Pour référence, consultez les implémentations de strtod: http://www.google.com/codesearch?hl=fr&lr=&q=double+strtod+const+char+str%2C+char+endptr&sbtn=Recherche – outis