How do I get 1324343032.324?
As you can see below, the following do not work:
>>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' 621 Answers
You can use an additional float() around it if you want to preserve it as a float.
%.3f'%(1324343032.324325235) 12You can use the following function to truncate a number to a set number of decimals:
import math def truncate(number, digits) -> float: # Improve accuracy with floating point operations, to avoid truncate(16.4, 2) = 16.39 or truncate(-1.13, 2) = -1.12 nbDecimals = len(str(number).split('.')[1]) if nbDecimals <= digits: return number stepper = 10.0 ** digits return math.trunc(stepper * number) / stepper Usage:
>>> truncate(1324343032.324325235, 3) 1324343032.324 5I've found another solution (it must be more efficient than "string witchcraft" workarounds):
>>> 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 2How about this:
In [1]: '%.3f' % round(1324343032.324325235 * 1000 / 1000,3) Out[1]: '1324343032.324' Possible duplicate of round() in Python doesn't seem to be rounding properly
[EDIT]
Given the additional comments I believe you'll want to do:
In : Decimal('%.3f' % (1324343032.324325235 * 1000 / 1000)) Out: Decimal('1324343032.324') The floating point accuracy isn't going to be what you want:
In : 3.324 Out: 3.3239999999999998 (all examples are with Python 2.6.5)
'%.3f'%(1324343032.324325235)
It's OK just in this particular case.
Simply change the number a little bit:
1324343032.324725235
And then:
'%.3f'%(1324343032.324725235) gives you 1324343032.325
Try this instead:
def trun_n_d(n,d): s=repr(n).split('.') if (len(s)==1): return int(s[0]) return float(s[0]+'.'+s[1][:d]) Another option for trun_n_d:
def trun_n_d(n,d): dp = repr(n).find('.') #dot position if dp == -1: return int(n) return float(repr(n)[:dp+d+1]) Yet another option ( a oneliner one) for trun_n_d [this, assumes 'n' is a str and 'd' is an int]:
def trun_n_d(n,d): return ( n if not n.find('.')+1 else n[:n.find('.')+d+1] ) trun_n_d gives you the desired output in both, Python 2.7 and Python 3.6
trun_n_d(1324343032.324325235,3) returns 1324343032.324
Likewise, trun_n_d(1324343032.324725235,3) returns 1324343032.324
Note 1 In Python 3.6 (and, probably, in Python 3.x) something like this, works just fine:
def trun_n_d(n,d): return int(n*10**d)/10**d But, this way, the rounding ghost is always lurking around.
Note 2 In situations like this, due to python's number internals, like rounding and lack of precision, working with n as a str is way much better than using its int counterpart; you can always cast your number to a float at the end.
Use the decimal module. But if you must use floats and still somehow coerce them into a given number of decimal points converting to string an back provides a (rather clumsy, I'm afraid) method of doing it.
>>> q = 1324343032.324325235 * 1000 / 1000 >>> a = "%.3f" % q >>> a '1324343032.324' >>> b = float(a) >>> b 1324343032.324 So:
float("%3.f" % q) 1I believe using the format function is a bad idea. Please see the below. It rounds the value. I use Python 3.6.
>>> '%.3f'%(1.9999999) '2.000' Use a regular expression instead:
>>> re.match(r'\d+.\d{3}', str(1.999999)).group(0) '1.999' Almo's link explains why this happens. To solve the problem, use the decimal library.
Maybe this way:
def myTrunc(theNumber, theDigits): myDigits = 10 ** theDigits return (int(theNumber * myDigits) / myDigits) 1Okay, this is just another approach to solve this working on the number as a string and performing a simple slice of it. This gives you a truncated output of the number instead of a rounded one.
num = str(1324343032.324325235) i = num.index(".") truncated = num[:i + 4] print(truncated) Output:
'1324343032.324' Of course then you can parse:
float(truncated) Function
def truncate(number: float, digits: int) -> float: pow10 = 10 ** digits return number * pow10 // 1 / pow10 Test code
f1 = 1.2666666 f2 = truncate(f1, 3) print(f1, f2) Output
1.2666666 1.266 Explain
It shifts f1 numbers digits times to the left, then cuts all decimals and finally shifts back the numbers digits times to the right.
Example in a sequence:
1.2666666 # number 1266.6666 # number * pow10 1266.0 # number * pow10 // 1 1.266 # number * pow10 // 1 / pow10 After looking for a way to solve this problem, without loading any Python 3 module or extra mathematical operations, I solved the problem using only str.format() e .float(). I think this way is faster than using other mathematical operations, like in the most commom solution. I needed a fast solution because I work with a very very large dataset and so for its working very well here.
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)] It returns the following output:
[(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)] I think the best and proper way is to use decimal module.
import decimal a = 1324343032.324325235 decimal_val = decimal.Decimal(str(a)).quantize( decimal.Decimal('.001'), rounding=decimal.ROUND_DOWN ) float_val = float(decimal_val) print(decimal_val) >>>1324343032.324 print(float_val) >>>1324343032.324 You can use different values for rounding=decimal.ROUND_DOWN, available options are ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_UP, and ROUND_05UP. You can find explanation of each option here in docs.
I suggest next solution:
def my_floor(num, precision): return f'{num:.{precision+1}f}'[:-1] my_floor(1.026456,2) # 1.02 1You can also use:
import math nValeur = format(float(input('Quelle valeur ? ')), '.3f') In Python 3.6 it would work.
a = 1.0123456789 dec = 3 # keep this many decimals p = 10 # raise 10 to this power a * 10 ** p // 10 ** (p - dec) / 10 ** dec >>> 1.012 Maybe python changed since this question, all of the below seem to work well
Python2.7
int(1324343032.324325235 * 1000) / 1000.0 float(int(1324343032.324325235 * 1000)) / 1000 round(int(1324343032.324325235 * 1000) / 1000.0,3) # result for all of the above is 1324343032.324 I am trying to generate a random number between 5 to 7 and want to limit it to 3 decimal places.
import random num = float('%.3f' % random.uniform(5, 7)) print (num) I develop a good solution, I know there is much If statements, but It works! (Its only for <1 numbers)
def truncate(number, digits) -> float: startCounting = False if number < 1: number_str = str('{:.20f}'.format(number)) resp = '' count_digits = 0 for i in range(0, len(number_str)): if number_str[i] != '0' and number_str[i] != '.' and number_str[i] != ',': startCounting = True if startCounting: count_digits = count_digits + 1 resp = resp + number_str[i] if count_digits == digits: break return resp else: return number Based on @solveMe asnwer () which I think is one of the most correct ways by utilising decimal context, I created following method which does the job exactly as needed:
import decimal def truncate_decimal(dec: Decimal, digits: int) -> decimal.Decimal: round_down_ctx = decimal.getcontext() round_down_ctx.rounding = decimal.ROUND_DOWN new_dec = round_down_ctx.create_decimal(dec) return round(new_dec, digits) >>> float(1324343032.324325235) * float(1000) / float(1000) 1324343032.3243253 >>> round(float(1324343032.324325235) * float(1000) / float(1000), 3) 1324343032.324 1