Estoy tratando de escribir una función en el lenguaje de programación D para reemplazar las llamadas al strtold de C. (Justificación: Para usar strtold desde D, debe convertir cadenas D en cadenas C, lo cual es ineficiente. Además, strtold no se puede ejecutar en tiempo de compilación). He encontrado una implementación que funciona principalmente, pero parece perder cierta precisión en los bits menos significativos.¿Cómo convertir cuerdas a flotadores con una precisión perfecta?
El código de la parte interesante del algoritmo está debajo y puedo ver de dónde proviene la pérdida de precisión, pero no sé cómo deshacerme de ella. (He omitido muchas partes del código que no eran relevantes para el algoritmo central para salvar a las personas que leen). ¿Qué algoritmo de cadena a flotación garantizará que el resultado sea lo más parecido posible al número IEEE? línea al valor representado por la cadena.
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;
Además, estoy usando las pruebas de unidad para la versión antigua, que hizo cosas como:
assert(to!(real)("0.456") == 0.456L);
¿Es posible que las respuestas que se producen por mis funciones son en realidad más precisa que la representación que produce el compilador al analizar un literal en coma flotante, pero el compilador (que está escrito en C++) siempre concuerda exactamente con strtold porque usa strtold internamente para analizar literales en coma flotante.
indique de dónde proviene la pérdida de precisión. –
@John: la pérdida de precisión proviene de dos lugares: 1. Rondamos cada vez que ejecutamos la línea 'ans + = digit * currentPlace', y 10^i no se puede representar exactamente en IEEE 754 para la mayoría de los enteros i. – dsimcha
Como referencia, revise las implementaciones de strtod: http://www.google.com/codesearch?hl=es&lr=&q=double+strtod+const+char+str%2C+char+endptr&sbtn=Search – outis