2012-09-13 19 views
5

Estoy construyendo una calculadora con BSP. Cuando lo probé con varios números, me encontré con el problema de que los números decimales no se muestran correctamente.58.85 muestra como 58.84999999999

Por ejemplo. 58.85 -> 58.849999. Pero 58.84 o 58.86 funcionan bien. 58.8471 -> 54.84710000000001. Al final, el último dígito mecanografiado se guardará de la nada.

Mi código siguiente.

method GENERATE_NUM. 

    DATA: lv_digi type I. * number of digits after the decimal point 


    call METHOD me->get_decimal 
    RECEIVING 
     getdigits = lv_digi. 

    *if it is a natural number 
    IF lv_digi = 0. 
    IF thisnum < 0. 
     result = thisnum * 10 - newdigit. 
    ELSE. 
     result = thisnum * 10 + newdigit. 
    ENDIF. 

    *if it is a float number 
    Else. 
    IF thisnum < 0. 
     result = thisnum - (newdigit/10 ** lv_digi). 
    ELSE. 
     result = thisnum + (newdigit/10 ** lv_digi). 
    ENDIF. 

    *increase the number of decimal point by 1 
    call method me->set_decimal. 
    ENDif. 

endmethod. 

Lo que yo hago es básicamente cada vez que se hace clic en un número, se llama al método "generate_num". Toma THISNUM, NEWDIGIT, RESULT como parámetros.
thisnum = número actual (por ejemplo: 58,8)
newdigit = número hecho clic (por ejemplo: 5)
resultado = número generado (esperado: 58,85 pero devuelve 58.849999).

+1

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Mysticial

+0

¿Sería útil si ilustra dónde y cómo resolver este problema? –

+0

Es una de esas preguntas frecuentes que necesita una explicación muy larga. Dejaré que alguien más intervenga o encuentre un duplicado adecuado para cerrar. – Mysticial

Respuesta

7

Cuando desee números decimales con precisión fija, debe usar el tipo P (número empaquetado) en lugar de flotar.

Ejemplo:

DATA lv_fixed_point TYPE p LENGTH 16 DECIMALS 2. 

Esto crea una variable de punto fijo con dos dígitos después del punto. El significado exacto del parámetro "longitud" no es tan directo. Desde el documentation:

números de pic - Tipo P

Tipo de datos P permite dígitos después del punto decimal. La cantidad de decimales es genérica y se determina en el programa. El rango de valores de tipo P depende de su tamaño y el número de dígitos después del punto decimal. El tamaño válido puede ser cualquier valor de 1 a 16 bytes. Dos dígitos decimales se empaquetan en un byte, mientras que el último byte contiene un dígito y el signo. Se permiten hasta 14 dígitos después del punto decimal. El valor inicial es cero. Cuando se trabaja con datos de tipo P, es una buena idea establecer el atributo de programa Aritmética de punto fija. De lo contrario, los números de tipo P se tratan como enteros.

Puede usar datos de tipo P para valores tales como distancias, pesos, cantidades de dinero, y más.

+0

simplemente cambiando el tipo a p resolvió mi problema. Muchas gracias. –

0

O puede llamar al CALL FUNCTION 'FLOATINGPOINT_COMPARE_ABSOLUTE' para tener en cuenta IEEE float epsilons. Trabajar con punto flotante en realidad se debe evitar el uso de comparaciones directamente, y escribir su propio con Epsilons incorporadas:

IS_EQUAL 
IS_GREATER 
IS_GREATER_EQUAL 
IS_LESS 
IS_LESS_EQUAL 

son el mínimo.

Más información about floating point here.

Obténgalo. Vívelo. Quiéralo.

Como ejercicio no trivial también se puede leer en NaN+Inf y -Inf (también SNAN si se trabaja con otros tipos DECFLOAT en lugar de f).

+0

Pero empaquetar puede ser la solución óptima (pero no tan rápido ya que todavía se interpretan como CHAR-un poco) con la menor cantidad de obstáculos. – Marius

Cuestiones relacionadas