Formatting a string to microseconds - python

Looking to format a output to show a very small number..
a= 6500
b= 3600
c=.000900
d= int((b/a)-c)
print d
Answer comes out to be zero, but looking for the .###### numbers after the .
sorry try this

Looks like you got bitten by integer division in python 2.x.
>>> a= 6500
>>> b= 3600
>>> c=.000900
>>> from __future__ import division
>>> print b/a - c
0.552946153846

There may be two issues with your calculation:
If you're using Python 2, division using / between two integers will always be an integer also. This will discard the fractional part of the calculation, which can be unexpected. One fix for this is to force one of the values to be a float value (e.g. float(b)/a). An alternative is to put at the top of your file from __future__ import division, which tells Python to use the Python 3 semantics for division (you'll only get an integer from integer division if the result is an exact integer).
The second issue seems to be about formatting a floating point value. First you seem to want only the fractional part of the value (not the integer part). Usually the best option is to simply subtract the integer part of the value:
d = someFloatingPointValue()
d_frac = d - int(d)
Next, to get a string to output (where you want several decimal places, but not a huge number of them), you probably want to explore Python's string formatting operations:
d = someFloatingPointValue()
d_to4decimalPlaces = "{:.4f}".format(d)

Related

Dynamic decimal point Python float

I'm looking for a way to neatly show rounded floats of varying decimal lengh.
Example of what I'm looking for:
In: 0.0000000071234%
Out: 0.0000000071%
In: 0.00061231999999%
Out: 0.0061%
In: 0.149999999%
Out: 0.15%
One way to do it would be:
def dynamic_round(num):
zeros = 2
original = num
while num< 0.1:
num*= 10
zeros += 1
return round(original, zeros)
I'm sure however there is a much cleaner way to do the same thing.
Here's a way to do it without a loop:
a = 0.003123
log10 = -int(math.log10(a))
res = round(a, log10+2)
==> 0.0031
This post answers your question with a similar logic
How can I format a decimal to always show 2 decimal places?
but just to clarify
One way would be to use round() function also mentioned in the documentation
built-in functions: round()
>>> round(number[,digits])
here digit refers to the precision after decimal point and is optional as well.
Alternatively, you can also use new format specifications
>>> from math import pi # pi ~ 3.141592653589793
>>> '{0:.2f}'.format(pi)
'3.14'
here the number next to f tells the precision and f refers to float.
Another way to go here is to import numpy
>>>import numpy
>>>a=0.0000327123
>>>res=-int(numpy.log10(a))
>>>round(a,res+2)
>>>0.000033
numpy.log() also, takes an array as an argument, so if you have multiple values you can iterate through the array.

Why is math.sqrt() incorrect for large numbers?

Why does the math module return the wrong result?
First test
A = 12345678917
print 'A =',A
B = sqrt(A**2)
print 'B =',int(B)
Result
A = 12345678917
B = 12345678917
Here, the result is correct.
Second test
A = 123456758365483459347856
print 'A =',A
B = sqrt(A**2)
print 'B =',int(B)
Result
A = 123456758365483459347856
B = 123456758365483467538432
Here the result is incorrect.
Why is that the case?
Because math.sqrt(..) first casts the number to a floating point and floating points have a limited mantissa: it can only represent part of the number correctly. So float(A**2) is not equal to A**2. Next it calculates the math.sqrt which is also approximately correct.
Most functions working with floating points will never be fully correct to their integer counterparts. Floating point calculations are almost inherently approximative.
If one calculates A**2 one gets:
>>> 12345678917**2
152415787921658292889L
Now if one converts it to a float(..), one gets:
>>> float(12345678917**2)
1.5241578792165828e+20
But if you now ask whether the two are equal:
>>> float(12345678917**2) == 12345678917**2
False
So information has been lost while converting it to a float.
You can read more about how floats work and why these are approximative in the Wikipedia article about IEEE-754, the formal definition on how floating points work.
The documentation for the math module states "It provides access to the mathematical functions defined by the C standard." It also states "Except when explicitly noted otherwise, all return values are floats."
Those together mean that the parameter to the square root function is a float value. In most systems that means a floating point value that fits into 8 bytes, which is called "double" in the C language. Your code converts your integer value into such a value before calculating the square root, then returns such a value.
However, the 8-byte floating point value can store at most 15 to 17 significant decimal digits. That is what you are getting in your results.
If you want better precision in your square roots, use a function that is guaranteed to give full precision for an integer argument. Just do a web search and you will find several. Those usually do a variation of the Newton-Raphson method to iterate and eventually end at the correct answer. Be aware that this is significantly slower that the math module's sqrt function.
Here is a routine that I modified from the internet. I can't cite the source right now. This version also works for non-integer arguments but just returns the integer part of the square root.
def isqrt(x):
"""Return the integer part of the square root of x, even for very
large values."""
if x < 0:
raise ValueError('square root not defined for negative numbers')
n = int(x)
if n == 0:
return 0
a, b = divmod(n.bit_length(), 2)
x = (1 << (a+b)) - 1
while True:
y = (x + n//x) // 2
if y >= x:
return x
x = y
If you want to calculate sqrt of really large numbers and you need exact results, you can use sympy:
import sympy
num = sympy.Integer(123456758365483459347856)
print(int(num) == int(sympy.sqrt(num**2)))
The way floating-point numbers are stored in memory makes calculations with them prone to slight errors that can nevertheless be significant when exact results are needed. As mentioned in one of the comments, the decimal library can help you here:
>>> A = Decimal(12345678917)
>>> A
Decimal('123456758365483459347856')
>>> B = A.sqrt()**2
>>> B
Decimal('123456758365483459347856.0000')
>>> A == B
True
>>> int(B)
123456758365483459347856
I use version 3.6, which has no hardcoded limit on the size of integers. I don't know if, in 2.7, casting B as an int would cause overflow, but decimal is incredibly useful regardless.

I'm making mistakes dividing large numbers

I am trying to write a program in python 2.7 that will first see if a number divides the other evenly, and if it does get the result of the division.
However, I am getting some interesting results when I use large numbers.
Currently I am using:
from __future__ import division
import math
a=82348972389472433334783
b=2
if a/b==math.trunc(a/b):
answer=a/b
print 'True' #to quickly see if the if loop was invoked
When I run this I get:
True
But 82348972389472433334783 is clearly not even.
Any help would be appreciated.
That's a crazy way to do it. Just use the remainder operator.
if a % b == 0:
# then b divides a evenly
quotient = a // b
The true division implicitly converts the input to floats which don't provide the precision to store the value of a accurately. E.g. on my machine
>>> int(1E15+1)
1000000000000001
>>> int(1E16+1)
10000000000000000
hence you loose precision. A similar thing happens with your big number (compare int(float(a))-a).
Now, if you check your division, you see the result "is" actually found to be an integer
>>> (a/b).is_integer()
True
which is again not really expected beforehand.
The math.trunc function does something similar (from the docs):
Return the Real value x truncated to an Integral (usually a long integer).
The duck typing nature of python allows a comparison of the long integer and float, see
Checking if float is equivalent to an integer value in python and
Comparing a float and an int in Python.
Why don't you use the modulus operator instead to check if a number can be divided evenly?
n % x == 0

It is possible to round up integers using format?

I'm trying to take a large integer, ie: 123123123 and format it with 3-digits of precision and commas. Format can add the commas using:
'{:,}'.format(123123123) # '123,123,123'
And specify precision for floating points:
'{0:.2f}'.format(3.141592) # '3.14'
But what if I want to do both?
ie:
'{:,3d}'.format(123123123) # ValueError
I would like to have it return: 123,000,000
There is no way to do this directly. The whole point of Python integers is that they're infinite-precision; if you want to round them, you have to do it explicitly. In fact, when you attempted the obvious, the message in the exception told you this:
>>> '{:,.3d}'.format(123123123)
ValueError: Precision not allowed in integer format specifier
So, your attempt at this is in the right directly… but it's more than a little funky:
'{:,.0f}'.format(round(123123123,-6))
There's no reason to explicitly force the int to a float just so you can print it without any fractional values. Just let it stay an int:
'{:,}'.format(round(123123123, -6))
Besides being simpler, this also means that when you try to one day print a giant integer, it won't give you an OverflowError or lose more digits than you wanted…
In earlier versions of Python (that is, 2.x), where round always returns float no matter what type you give it, you can't do that; you will probably want to write a trivial intround function instead. For example:
def intround(number, ndigits):
return (number + 5 * 10**(-ndigits-1)) // 10**-ndigits * 10**-ndigits
If you know for a fact that you will never have an integer too large to fit losslessly into a float, you can just use int(round(*args)) instead—but really, if you can avoid converting integers to floats, you should.
And, while we're at it, there's no reason to build up a {} string to call the format method on when you can just call the free function:
format(round(123123123, -6), ',')
The 'right' way to do this that is Python version independent (well -- it has to have with so 2.5+) is use the Decimal module:
from __future__ import print_function
import decimal
import sys
if sys.version_info.major<3:
ic=long
else:
ic=int
def ri(i, places=6):
with decimal.localcontext() as lct:
lct.prec=places
n=ic(decimal.Decimal(i,)+decimal.Decimal('0'))
return format(n,',')
print(ri(2**99, 4))
# 633,800,000,000,000,000,000,000,000,000
print(ri(12349159111, 7))
# 12,349,160,000
print(ri(12349111111, 3))
# 12,300,000,000
If you use the round method it is fairly fragile on Python 2:
Python 2:
>>> format(round(12349999999999999,-6),',')
'1.235e+16' # wrong....
It works on Python 3, but this is the way to do it so the rounding is left to right:
def rir(i, places=6):
return format(round(i, places-len(str(i))), ',')
print(rir(2**99, 4))
# 633,800,000,000,000,000,000,000,000,000
print(rir(12349159111, 7))
# 12,349,160,000
With a negative offset for ndigits, round(number[, ndigits]) will round the mantissa of the floating point right to left:
>>> round(123456789,-4)
123456789123460000
Works great on Python 3 with larger numbers:
>>> round(123456789123456789,-8)
123456789100000000
On Python 2, the functionality breaks with larger numbers:
>>> round(123456789,-4)
123460000.0
>>> round(123456789123456789,-4)
1.2345678912346e+17
With the decimal module, it works as expected on Python 2 and Python 3.

an error in taking an input in python

111111111111111111111111111111111111111111111111111111111111
when i take this as input , it appends an L at the end like this
111111111111111111111111111111111111111111111111111111111111L
thus affecting my calculations on it .. how can i remove it?
import math
t=raw_input()
l1=[]
a=0
while (str(t)!="" and int(t)!= 0):
l=1
k=int(t)
while(k!= 1):
l=l+1
a=(0.5 + 2.5*(k %2))*k + k % 2
k=a
l1.append(l)
t=raw_input()
a=a+1
for i in range(0,int(a)):
print l1[i]
this is my code and it works for every test case except 111111111111111111111111111111111111111111111111111111111111
so i guess something is wrong when python considers such a huge number
It looks like there are two distinct things happening here. First, as the other posters have noted, the L suffix simply indicates that Python has converted the input value to a long integer. The second issue is on this line:
a=(0.5 + 2.5*(k %2))*k + k % 2
This implicitly results in a floating point number for the value of (0.5 + 2.5*(k %2))*k. Since floats only have 53 bits of precision the result is incorrect due to rounding. Try refactoring the line to avoid floating point math, like this:
a=(1 + 5*(k %2))*k//2 + k % 2
It's being input as a Long Integer, which should behave just like any other number in terms of doing calculations. It's only when you display it using repr (or something that invokes repr, like printing a list) that it gets the 'L'.
What exactly is going wrong?
Edit: Thanks for the code. As far as I can see, giving it a long or short number makes no difference, but it's not really clear what it's supposed to do.
As RichieHindle noticed in his answer, it is being represented as a Long Integer. You can read about the different ways that numbers can be represented in Python at the following page.
When I use numbers that large in Python, I see the L at the end of the number as well. It shouldn't affect any of the computations done on the number. For example:
>>> a = 111111111111111111111111111111111111111
>>> a + 1
111111111111111111111111111111111111112L
>>> str(a)
'111111111111111111111111111111111111111'
>>> int(a)
111111111111111111111111111111111111111L
I did that on the python command line. When you output the number, it will have the internal representation for the number, but it shouldn't affect any of your computations. The link I reference above specifies that long integers have unlimited precision. So cool!
Another way to avoid numerical errors in python is to use Decimal type instead of standard float.
Please refer to official docs
Are you sure that L is really part of it? When you print such large numbers, Python will append an L to indicate it's a long integer object.

Categories