How do I get 1324343032.324?
As you can see below, the following do not work:
>>1324343032.324325235 * 1000 / 1000
1324343032.3243253
>>i
>>> float(1324343032.324325235) * float(1000) / float(1000)
1324343032.3243253
>>> round(float(1324343032.324325235) * float(1000) / float(1000), 3)
1324343032.324
'%.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.
You can use the following function to truncate a number to a set number of decimals:
import math
def truncate(number, digits) -> float:
stepper = 10.0 ** digits
return math.trunc(stepper * number) / stepper
Usage:
>>> truncate(1324343032.324325235, 3)
1324343032.324
I'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
About decimals module
About rounding settings
I 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'
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