Cómo redondear un número a cifras significativas en Python

Resuelto Peter Graham asked hace 14 años • 27 respuestas

Necesito redondear un flotador para que se muestre en una interfaz de usuario. por ejemplo, a una cifra significativa:

1234 -> 1000

0.12 -> 0.1

0.012 -> 0.01

0.062 -> 0.06

6253 -> 6000

1999 -> 2000

¿Existe una buena manera de hacer esto usando la biblioteca de Python o tengo que escribirla yo mismo?

Peter Graham avatar Aug 05 '10 07:08 Peter Graham
Aceptado

Puedes usar números negativos para redondear números enteros:

>>> round(1234, -3)
1000.0

Por lo tanto, si sólo necesita el dígito más significativo:

>>> from math import log10, floor
>>> def round_to_1(x):
...   return round(x, -int(floor(log10(abs(x)))))
... 
>>> round_to_1(0.0232)
0.02
>>> round_to_1(1234243)
1000000.0
>>> round_to_1(13)
10.0
>>> round_to_1(4)
4.0
>>> round_to_1(19)
20.0

Probablemente tendrás que encargarte de convertir el flotante en un número entero si es mayor que 1.

Evgeny avatar Aug 05 '2010 02:08 Evgeny

%g en el formato de cadena formateará un flotante redondeado a una cierta cantidad de cifras significativas. A veces utilizará la notación científica 'e', ​​así que convierta la cadena redondeada nuevamente a flotante y luego utilice el formato de cadena %s.

>>> '%s' % float('%.1g' % 1234)
'1000'
>>> '%s' % float('%.1g' % 0.12)
'0.1'
>>> '%s' % float('%.1g' % 0.012)
'0.01'
>>> '%s' % float('%.1g' % 0.062)
'0.06'
>>> '%s' % float('%.1g' % 6253)
'6000.0'
>>> '%s' % float('%.1g' % 1999)
'2000.0'
Peter Graham avatar Aug 05 '2010 04:08 Peter Graham
f'{float(f"{i:.1g}"):g}'
# Or with Python <3.6,
'{:g}'.format(float('{:.1g}'.format(i)))

Esta solución es diferente de todas las demás porque:

  1. resuelve exactamente la pregunta OP
  2. no necesita ningún paquete extra
  3. no necesita ninguna función auxiliar definida por el usuario ni operación matemática

Para un número arbitrario nde cifras significativas, puede utilizar:

print('{:g}'.format(float('{:.{p}g}'.format(i, p=n))))

Prueba:

a = [1234, 0.12, 0.012, 0.062, 6253, 1999, -3.14, 0., -48.01, 0.75]
b = ['{:g}'.format(float('{:.1g}'.format(i))) for i in a]
# b == ['1000', '0.1', '0.01', '0.06', '6000', '2000', '-3', '0', '-50', '0.8']

Nota : con esta solución, no es posible adaptar dinámicamente el número de cifras significativas a partir de la entrada porque no existe una forma estándar de distinguir números con diferentes números de ceros finales ( 3.14 == 3.1400). Si necesita hacerlo, entonces necesitará funciones no estándar como las proporcionadas en el paquete to-precision .

Falken avatar Feb 15 '2018 17:02 Falken

Si desea tener más de 1 decimal significativo (de lo contrario, lo mismo que Evgeny):

>>> from math import log10, floor
>>> def round_sig(x, sig=2):
...   return round(x, sig-int(floor(log10(abs(x))))-1)
... 
>>> round_sig(0.0232)
0.023
>>> round_sig(0.0232, 1)
0.02
>>> round_sig(1234243, 3)
1230000.0
indgar avatar Aug 05 '2010 09:08 indgar