0 Usuarios y 1 Visitante están viendo este tema.
Hola MarcLa razón imagino que será por que un Double es un coma flotante. Cámbialo a Currency y no tendrás esos problemas (probado )Nos leemos
FloatToStrF converts the floating-point value given by Value to its string representation. The Value parameter is the value to convert. The Precision parameter specifies the precision of the given value. It should be 7 or less for values of type Single, 15 or less for values of type Double, and 18 or less for values of type Extended. The Digits and Format parameters together control how the value is formatted into a string. For details, see the description of TFloatFormat.For all formats, the actual characters used as decimal and thousand separators are obtained from the DecimalSeparator and ThousandSeparator global variables.If the given value is a NAN (not-a-number), the resulting string is 'NAN'. If the given value is positive infinity, the resulting string is 'INF'. If the given value is negative infinity, the resulting string is '-INF'.
If the section for positive values is empty, or if the entire format string is empty, the value is formatted using general floating-point formatting with 15 significant digits, corresponding to a call to FloatToStrF with the ffGeneral format. General floating-point formatting is also used if the value has more than 18 digits to the left of the decimal point and the format string does not specify scientific notation.
Además, tu error Marc no está en el Double sino en la cantidad de decimales que estás mostrando. Double no puede ofrecerte más hallá de 16 decimales (15 normalmente). Tu estás mostrando 18 que es justamente esos 2 decimales ocultos que se reserva la máquina para ofrecer la aritemética exacta a fin de cumplir con el estándar IEEE y le permite hacer los corrimientos de coma. Si deseas ir a esos 18 decimales, emplea Extended.
Yo como regla "de oro" cuando comparo dos reales a ver si son o no exatamente iguales, siempre miro que ABS(r1-r2)<nano, donde nano lo defino como 10^-10 por ejemplo, aunque tienes una constante en delphi para esto (NAN creo que era).... bueno, uso esto cuando detecto "rarezas" como la tuya, otras veces no soy tan cuidadoso, la verdad.
No tienes otra si trabajas con reales, excepto que usases "aritmetica de precisión arbitraria" o tipos currency.
Ufa... quería ser yo quien les aclare las dudas. No se vale Como te ha dicho Sergio, no es que Double falle sino la cantidad de dígitos que tu has puesto; que excede a lo que Double es capaz de registrar. Si te fijas bien amigo, tu número si ha podido ser calculado con precisión exacta a 15 decimales. Los decimales que le siguen corresponden a esos decimales basuras que llama Sergio.Como bien dices, en aritmética de punto flotante los números son expresados como mantisa y exponente. La FPU para facilitar algunas operaciones matemáticas normaliza la mantisa cuando lo considere oportuno y mantiene a la mantisa intacta, como sigue siendo matemática el cálculo será exacto como si nunca se hubiera hecho alguna normalización (es decir, asumir un x 100).Como yo he dicho, la precisión de los puntos flotantes está en la cantidad de dígitos decimales, está establecido por el estándar IEEE que Double tenga 15/16 decimales (normalmente tiene 15 decimales, sólo para ciertos números especiales es que Double llega a tener 16).Pero como este espacio es finito sólo puede asumir ciertos valores, y resulta ser que no todos los números pueden ser expresados en forma exacta en el sistema binario.Por ejemplo, 0,333... o hasta incluso 0,01 no es posible. Es por ello que debido a la cantidad de decimales es que no se puede tener mejor precisión para representar al número real.Además, la FPU para ofrecer garantías de que los cálculos se realicen exactamente redondeados y sean lo más exactos mantiene 2 decimales ocultos, de forma interna, uno que está destinado para llevar acarreo y el otro a modo de guarda o guardían para los números desnormalizados por lo que internamente Double tiene capacidad para 2 decimales más. Así hay garantías de que va a funcionar la operatoria. Luego cuando se regresa el valor estos decimales ocultos se quitan.Lo que tu ves al pedirle que te muestre más decimales de lo que puede es justamente esos decimales. El compilador interpretó al Double como Extended y eso es lo que te devolvió... cuando hizo el paso de un tipo al otro fue necesario llevarlo a la precisión del segundo. Llevándose consigo esos decimales basuras que superaron su precisión.Debido a que se quita ese decimal interno, es que podemos afirmar que el número obtenido es lo más aproximado posible más un 0,5 ulps.Cambia el tipo Double por un Extended en el código de ejemplo y observa Ahora vuelve a ponerlo como Double y pidele que te muestre 15 decimales. ¿Ves algo fuera de lo normal? Claro que no. Sergio, NaN no significa lo que estás pensando... NaN es eso: ¡Not is a Number!. Es uno de los números especiales, junto a +/-INF y el CERO. De hecho en realidad tenemos dos tipos de NAN, QNAN y SNAN.Creo que al número que tu estás buscando es el valor por defecto, establecido como constante para el valor de epsilon o tolerancia:Código DELPHIconst FuzzFactor = 1000; ExtendedResolution = 1E-19 * FuzzFactor; DoubleResolution = 1E-15 * FuzzFactor; SingleResolution = 1E-7 * FuzzFactor; O lo que es lo mismo 1E-12 Justamente lo que comenté antes. La precisión estándar que asume la mayoría para sus cálculos dejando los 2/3 decimales como "peligrosos".Lo que quiero decirles a todos es que no teman a los puntos flotantes, si hay que respetarlos y aprender a usarlos. Les pido a todos que lean las fuentes que he dejado en mi hilo cuando me surgieron todas estas dudas. En especial y de sobre manera el artículo "Lo que todo informático debe saber sobre aritmética de punto flotante".Y no está demás amigarse con el Cálculo Numérico y la teoría del error relativo y absoluto; aprender a medir con que precisión se han de tomar los números, y a calcular el error que se comete cuando se suma, resta, multiplica, divide o se calculan raíces. Esto nos puede ayudar a establecer las pautas necesarias y hacer un mejor seguimiento de lo que pasa dentro de nuestros algoritmos y prepararnos para controlar las situaciones.No es nada fácil ni hay un único método en como hacer un seguimiento y control a un algoritmo o ecuación pero con algunas guías uno se puede dar mañas.Saludos,