2011-12-21 11 views
16

explica por sí misma, que quieren conseguir 1324343032,324truncado a 3 decimales en el pitón

Como se puede ver a continuación, los siguientes no funcionan:

>>1324343032.324325235 * 1000/1000 
1324343032.3243253 
>>int(1324343032.324325235 * 1000)/1000.0 
1324343032.3239999 
>>round(int(1324343032.324325235 * 1000)/1000.0,3) 
1324343032.3239999 
>>str(1324343032.3239999) 
'1324343032.32' 
+4

No hay tal valor en el conjunto que están representados por números en coma flotante. –

+2

En caso de que el comentario de Karl no sea lo suficientemente claro: * no hay un número * como 1324343032.324 en coma flotante binario. Si cambia a una versión superior de Python (2.7 o 3.1 o posterior), el intérprete * le mostrará * 1324343032.324. Pero en realidad, el número con el que está computando no es ni 1324343032.324 ni 1324343032.3239999 independientemente de la versión de Python. La única manera de obtener * exactamente * 1324343032.324 es usar el módulo 'decimal' o alguna otra biblioteca matemática de precisión arbitraria, como' gmpy'. –

+0

La respuesta aceptada a continuación es correcta, si desea redondear (subir) a una cantidad determinada de decimales. Sin embargo, lo que la pregunta está haciendo y lo que quería saber es cómo truncar a un número particular de decimales. Para mí, ''% .3f'% (1324343032.3243)' y ''% .3f'% (1324343032.3245)' dan resultados diferentes. (Estoy usando Python 2.7.8). – nullstellensatz

Respuesta

31

'%.3f'%(1324343032.324325235)

Uso adicionales float() alrededor si quieres conservarlo como un flotador.

+0

No quiero imprimirlo ... Quiero guardarlo – SuperString

+2

Esta es básicamente la respuesta correcta, solo use 'val = '% .3f'% (1324343032.324325235)' en lugar de 'print'. –

+0

Editado. Puedes imprimirlo, guardarlo, lo que sea. –

7

¿Qué tal esto:

In [1]: '%.3f' % round(1324343032.324325235 * 1000/1000,3) 
Out[1]: '1324343032.324' 

duplicado Posible de round() in Python doesn't seem to be rounding properly

[EDIT]

Teniendo en cuenta los comentarios adicionales que creo que querrá hacer:

In : Decimal('%.3f' % (1324343032.324325235 * 1000/1000)) 
Out: Decimal('1324343032.324') 

La flóvera precisión de punto ting no va a ser lo que quieres:

In : 3.324 
Out: 3.3239999999999998 

(todos los ejemplos son con Python 2.6.5)

3

enlace de Almo explica por qué esto sucede. Para resolver el problema, use decimal library.

6

Utilice el módulo decimal. Pero si debe usar flotadores y todavía de alguna manera forzarlos a un número dado de puntos decimales convirtiendo a cadena un respaldo proporciona un método (algo torpe, me temo) de hacerlo.

>>> q = 1324343032.324325235 * 1000/1000 
>>> a = "%.3f" % q 
>>> a 
'1324343032.324' 
>>> b = float(a) 
>>> b 
1324343032.324 

Así:

float("%3.f" % q) 
+1

Es bueno que mencione primero el módulo decimal, porque esa es la única respuesta totalmente correcta. Una cosa para tener un poco de cuidado con el resto es que 'b' en su ejemplo se mostrará como 1324343032.3239999 en versiones de Python anteriores a 2.7. Y de hecho, este es el valor que OP está viendo cuando lo intenta. Por supuesto, ambos valores son indistinguibles, en términos de punto flotante binario. –

3

Puede utilizar la siguiente función para truncar un número a un número determinado de decimales:

import math 
def truncate(number, digits) -> float: 
    stepper = pow(10.0, digits) 
    return math.trunc(stepper * number)/stepper 

Uso:

>> truncate(1324343032.324325235, 3) 
>> 1324343032.324 
+1

Esto realmente debería ser la respuesta aceptada. El código es simple, elegante y tiene más sentido. Utilice la función de truncado estándar, sin embargo, primero cambie el lugar decimal, desplazando el lugar decimal una vez que se haya realizado el truncamiento. – CatalystNZ

5

I He encontrado otra solución (debe ser más eficiente ciente de "brujería cadena" soluciones):

>>> import decimal 
# By default rounding setting in python is decimal.ROUND_HALF_EVEN 
>>> decimal.getcontext().rounding = decimal.ROUND_DOWN 
>>> c = decimal.Decimal(34.1499123) 
# By default it should return 34.15 due to '99' after '34.14' 
>>> round(c,2) 
Decimal('34.14') 
>>> float(round(c,2)) 
34.14 
>>> print(round(c,2)) 
34.14 

About decimals module

About rounding settings

-1
>>> float(1324343032.324325235) * float(1000)/float(1000) 

1324343032.3243253 

>>> round(float(1324343032.324325235) * float(1000)/float(1000), 3) 

1324343032.324 
+1

Si bien este fragmento de código puede resolver la pregunta, [incluyendo una explicación] (http: //meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) realmente ayuda a mejorar la calidad de su publicación. Recuerde que usted está respondiendo la pregunta a los lectores en el futuro, y es posible que esas personas no sepan los motivos de su sugerencia de código. – DimaSan

-1

también se puede utilizar:

import math 

nValeur = format(float(input('Quelle valeur ? ')), '.3f') 

en Python 3.6 que funcionaría

0

Después de buscar una manera de resolver este problema, sin cargar ningún módulo de Python 3 ni operaciones matemáticas adicionales, resolví el problema usando solo str.format() e .float().Creo que de esta manera es más rápido que usar otras operaciones matemáticas, como en la solución más común. Necesitaba una solución rápida porque trabajo con un conjunto de datos muy grande y por eso funciona muy bien aquí.

def truncate_number(f_number, n_decimals): 
     strFormNum = "{0:." + str(n_decimals+5) + "f}" 
     trunc_num = float(strFormNum.format(f_number)[:-5]) 
     return(trunc_num) 

# Testing the 'trunc_num()' function 
test_num = 1150/252 
[(idx, truncate_number(test_num, idx)) for idx in range(0, 20)] 

devuelve el siguiente resultado:

[(0, 4.0), 
(1, 4.5), 
(2, 4.56), 
(3, 4.563), 
(4, 4.5634), 
(5, 4.56349), 
(6, 4.563492), 
(7, 4.563492), 
(8, 4.56349206), 
(9, 4.563492063), 
(10, 4.5634920634), 
(11, 4.56349206349), 
(12, 4.563492063492), 
(13, 4.563492063492), 
(14, 4.56349206349206), 
(15, 4.563492063492063), 
(16, 4.563492063492063), 
(17, 4.563492063492063), 
(18, 4.563492063492063), 
(19, 4.563492063492063)] 
1

Creo con función de formato es una mala idea. Por favor mira abajo Redondea el valor. Yo uso Python3.6.

>>> '%.3f'%(1.9999999) 
'2.000' 

uso de expresiones regulares en su lugar:

>>> re.match(r'\d+.\d{3}', str(1.999999)).group(0) 
'1.999'