truncar redondear quitar numeros notacion imprimir entera declarar decimales cientifica python string decimal

quitar - redondear a dos decimales python



Forma fácil de encontrar decimales (8)

¿Hay una manera fácil o función integrada para averiguar los decimales de un número de punto flotante?

El número se analiza a partir de una cadena, por lo que una forma es contar los dígitos después del ''.'' firmar, pero eso se ve bastante torpe para mí. ¿Existe la posibilidad de obtener la información necesaria de un objeto Decimal u Decimal ?

SOLUCIÓN (uno de ellos, por supuesto :))

Elegí usar la clase python decimal.Decimal para ayudarme con mi problema:

e = abs(Decimal(string_value).as_tuple().exponent)

NOTA: esto solo funciona cuando el parámetro a partir del cual se construye el decimal es una cadena y no un flotador (lo que daría lugar a inexactitudes de coma flotante).

Muchas gracias por todas las otras contribuciones.


"el número de lugares decimales" no es realmente una propiedad que tenga un número de coma flotante, debido a la forma en que se almacenan y manejan internamente. Puede obtener tantos decimales como desee de un número de coma flotante. La pregunta es cuánta precisión quieres. Al convertir un número de punto flotante en una cadena, parte del proceso es decidir sobre la precisión.

Prueba por ejemplo:

1.1 - int(1.1)

Y verá que la respuesta es:

0.10000000000000009

Entonces, para este caso, el número de decimales es 17. ¿Es este el número que quieres?

Probablemente no.

Sin embargo, puede redondear el número a una cierta cantidad de decimales con "redondo":

round(3.1415 - int(3.1415), 3)

Para este caso, el número de decimales se reduce a 3.

No puede obtener "el número de decimales de un flotador", pero puede decidir la precisión y el número que desea. La conversión de un flotador a una cadena es una forma de tomar esa decisión.


Como los números de coma flotante de Python se representan internamente como binarios en lugar de como decimales, en realidad no hay atajos que no sean convertir a decimales. La única forma incorporada de hacerlo es convirtiendo a una cadena. Podría escribir su propio código para hacer una conversión decimal y contar los dígitos, pero sería una duplicación de esfuerzo.


La biblioteca decimal es para trabajar con números decimales, como en Contabilidad. No tiene una función inherente para devolver el número de decimales. Esto es especialmente un problema cuando te das cuenta de que el contexto en el que se ejecuta lo establece en lo que el usuario desee.

Si obtienes una cadena, puedes convertirla a decimal, pero esto te dará azotes para llegar a tu precisión, o usar la configuración de redondeo para truncarla.

Su mejor apuesta probablemente apostaría a dividir el punto en su cadena y contar el número de caracteres en la subcadena resultante.


La forma más rápida que encontré para los dígitos de calc después del punto decimal y redondeando el número es

Calcular dígitos:

a=decimal.Decimal(''56.9554362669143476''); lenstr = len(str(a).split(".")[1])

Calc, control y redondeo:

a=decimal.Decimal(''56.9554362669143476''); a = round(float(a),5) if len(str(a).split(".")[1]) > 5 else float(a)

Comparación:

$ python2 -mtimeit ''import decimal; a=decimal.Decimal(''56.9554362669143476''); round(float(a),5) if a.as_tuple().exponent < -5 else float(a)'' 10000 loops, best of 3: 32.4 usec per loop $ python -mtimeit ''import decimal; a=decimal.Decimal(''56.9554362669143476''); a = round(float(a),5) if len(str(a).split(".")[1]) > 5 else float(a)'' 100000 loops, best of 3: 16.7 usec per loop


Necesitaba algo como esto y probé algunos de estos, el más rápido que descubrí fue:

str(number)[::-1].find(''.'')

Debido al problema del punto flotante, todos los módulos me dieron resultados falsos incluso con Decimal (número) (nótese que necesitaba esto en un script para fijar los precios de un db completo)

len(str(Decimal(str(number))) % Decimal(1))) - 2

La necesidad de poner una cuerda en Decimal es bastante incómoda cuando tenemos flotadores o algo así.

Aquí está mi "banco": https://repl.it/FM8m/17


Para repetir lo que otros han dicho (¡porque ya lo había tipeado!), Ni siquiera estoy seguro de que ese valor sea significativo en el caso de un número de coma flotante, debido a la diferencia entre la representación decimal y binaria; a menudo un número representable por un número finito de dígitos decimales tendrá solo una representación de dígitos infinitos en binario.

En el caso de un objeto decimal.Decimal , puede recuperar el exponente mediante el método as_tuple , que devuelve una tilde nombrada con sign , digits y atributos de exponent :

>>> d = decimal.Decimal(''56.4325'') >>> d.as_tuple().exponent -4 >>> d = decimal.Decimal(''56.43256436'') >>> d.as_tuple().exponent -8

La negación del exponente es el número de dígitos después del punto decimal, a menos que el exponente sea mayor que 0 .


Si sabes que no vas a tener problemas de análisis (o si dejas que python mismo o alguna otra biblioteca maneje eso para ti, con suerte manejando problemas de localización) ... solo modf y usa modf . El valor de retorno es un par de valores, uno de los cuales es la parte integral, el otro es la parte fraccionaria.


Una forma ingenua (vulnerable al uso localizado mencionado por @jglouie) es

len(foo.split(''.'')[1])

donde foo es una cadena como "23.512999238".

EDITAR

Como mencionaron @Thomas Jung y @Mark Ransom, esto es bastante ingenuo para algunos casos de esquina, que deben manejarse como ...

import re from locale import localeconv dec_pt = localeconv()[''decimal_point''] decrgx = re.compile("/d+(%s/d+)?e(-|/+)(/d+)" % dec_pt) if decrgx.search(foo): # still figuring this out raise NotImplementedError, "e notation not implemented" else: digits = len(foo.split(dec_pt)[-1])