Is Safe to compare integers using ==? - python

I read that comparing two floats using == in python can lead to errors. But what about using that operator in integers ?
Thanks
Because I never found anything against the use of the operator I believe that is okay to use.

Its safe to use == operator for integers.

Yes, it's fine. The int type in Python doesn't have the representational problems that float has.
But an interesting bit of trivia is that float types with an integer value are safe to compare too, as long as they're less than 2**53 (9007199254740992).

Related

Getting error in python: Value Error: invalid literal for int() with base 10: '470.21'

i want adding and subtracting this type of data: $12,587.30.which returns answer in same format.how can do this ?
Here is my code example:
print(int(col_ammount2.lstrip('$'))-int(col_ammount.lstrip('$')))
I removed $ sign and convert it to int but it gives me base 10 error.
You mentioned you want to do arithmetic operations to the numbers (addition/subtraction) so you probably want them in float instead. The difference between an integer (int) and float is that integers do not carry decimal points.
Additionally, as #officialaimm mentioned you need to remove the commas too, for example
float('$3,333.33'.replace('$', '').replace(',', ''))
will give you
3333.33
So putting it into your code
print(float(col_ammount2.lstrip('$').replace(',', ''))
- float(col_ammount.lstrip('$').replace(',', '')))
An additional note for when you parse a floating point number (same applies to integers too), you may want to watch out for empty values, i.e.
float('')
is bad. One of the things u can do in case col_amount and col_amount2 may be empty at some point is default them to 0 if that happens
float(col_amount.lstrip(...).replace(...) or 0)
You also want to read this to know about workaround to problems you may face with floating point arithmetic https://docs.python.org/3/tutorial/floatingpoint.html
There are two things you are missing here. Firstly python int(...) cannot parse numbers with commas so you will need to remove commas as well by using .replace(',',''). Secondly int() cannot parse floating point values you will have to use float(...) first and after that maybe typecast it to int using int or math.ceil, math.floor appropriately as per your choice and needs.
Maybe something like this will solve your problem:
col_ammount2='$1,587.30'
col_ammount = '$2,567.67'
print(int(float(col_ammount2.lstrip('$').replace(',','')))-int(float(col_ammount.lstrip('$').replace(',',''))))
If you are doing these sorts of things quite often in your code, making a function as such might be handy:
integerify_currency = lambda x:int(float(x.lstrip('$').replace(',','')))

Python : arbitrary precision with floats

I tried to compute math.exp(9500) but encountered an OverflowError: math range error (it's roughly 6.3e4125). From this question it seems like it's due to a too large float, the accepted answer says "(...) is slightly outside of the range of a double, so it causes an overflow".
I know that Python can deal with arbitrarily large integers (long type), is there a way to deal with arbitrarily large floats in the same manner ?
Edit : my original question was about using integers for calculating exp(n) but as Eric Duminil said, the simplest way to do that would be 3**n which doesn't provide any useful result. I know realize this question might be similar to this one.
I don't think it's possible to approximate exp() with integers. If you use 3**n instead of 2.71828182845905**n, your calculations will be completely useless.
One possible solution would be to use Sympy. According to the documentation:
There is essentially no upper precision limit
>>> from sympy import *
>>> exp(9500)
exp(9500)
>>> exp(9500).evalf()
6.27448493490172e+4125
You can also specify the desired precision:
>>> exp(9500).evalf(1000)
6.274484934901720177929867046175406311474380389941415760684209191232450360090766458256588885184199320756050569665785657269735313171886975309933254563488343491718198237894473901620914303565550450204805537225888529509352754121292701357622411614860860409639719786022989336837263283678476008817556351031696366815467221836948040042378034720460820127399855873232167818091083005170669482845098735176209372328114732133251096196535355946589133977397512846130629857604295369747597459602137604440011394793443041829253598478244189078131130488653468669559814695095974271938947640276013215753183113041899037415404445478806695965167014404297848725756879184380559837391976534521522360723388582608454995349380217499779247330557664230806254642768796486899322646423713763772064068933790640394967085887914192401473425799354391464743910233873602389444180426155866237536459654917521713769608318128404177877383203786348495822099924812081683286880293701785567962687838594752986160305764297117036426951203418854463404773701882e+4125
With exp(9500).evalf(5000), you even get the integer closest to exp(9500).
Here's another way to calculate the result with Python:
exp(9500)
is too big.
But log10(exp(9500)) isn't. You cannot calculate it this way in Python, but log10(exp(9500)) is log(exp(9500))/ln(10), which is 9500/ln(10):
>>> from math import log
>>> 9500/log(10)
4125.797578080892
>>> int(9500/log(10))
4125
>>> 10**(9500/log(10) % 1)
6.274484934896202
This way, you can calculate that exp(9500) is 6.27448493 * 10**4125 in plain Python, without any library!
try long type.
int type has been remove from python since 3.0 version.

How does Python know which number type to use in order to Multiply arbitrary two numbers?

In C, I have to set proper type, such as int, float, long for a simple arithmetic for multiplying two numbers. Otherwise, it will give me an incorrect answer.
But in Python, basically it can automatically give me the correct answer.
I have tried debug a simple 987*456 calculation to see the source code.
I set a break point at that line in PyCharm, but I cannot step into the source code, it just finished right away.
How can I see the source code? Is it possible? Or how does Python do that multiplication?
I mean, how does Python carry out the different of number type in the result of
98*76 or 987654321*123457789, does Python detect some out of range error and try another number type?
I mean, how does Python carry out the different of number type in the result of 98*76 or 987654321*123457789, does Python detect some out of range error and try another number type?
Pretty much. The source code for integer multiplication can be found in intobject.c. It multiplies the integers as C longs, then casts the longs to doubles and multiplies those. If the results are close, the long multiplication didn't overflow. If the results are very different, it switches to Python longs, which use a bignum representation.
The type promotion for mixed arithmetic is:
integer -> long -> float
The narrower type is converted to the wider type, and the multiplication is carried out.
https://docs.python.org/2/library/stdtypes.html#numeric-types-int-float-long-complex
Some examples to see what happens:
987*456 = 450072
987*456L = 450072L
987*456.0 = 450072.0
I hope I understood your question.
Variables are nothing but reserved memory locations to store values. This means that when you create a variable you reserve some space in memory.
Based on the data type of a variable, the interpreter allocates memory and decides what can be stored in the reserved memory. Therefore, by assigning different data types to variables, you can store integers, decimals or characters in these variables.
Python variables do not have to be explicitly declared to reserve memory space. The declaration happens automatically when you assign a value to a variable. The equal sign (=) is used to assign values to variables.
The operand to the left of the = operator is the name of the variable and the operand to the right of the = operator is the value stored in the variable.

floats inside tuples changing values when accessed

So I have a list of tuples of two floats each. Each tuple represents a range. I am going through another list of floats which represent values to be fit into the ranges. All of these floats are < 1 but positive, so precision matter. One of my tests to determine if a value fits into a range is failing when it should pass. If I print the value and the range that is causing problems I can tell this much:
curValue = 0.00145000000671
range = (0.0014500000067055225, 0.0020968749796738849)
The conditional that is failing is:
if curValue > range[0] and ... blah :
# do some stuff
From the values given by curValue and range, the test should clearly pass (don't worry about what is in the conditional). Now, if I print explicitly what the value of range[0] is I get:
range[0] = 0.00145000000671
Which would explain why the test is failing. So my question then, is why is the float changing when it is accessed. It has decimal values available up to a certain precision when part of a tuple, and a different precision when accessed. Why would this be? What can I do to ensure my data maintains a consistent amount of precision across my calculations?
The float doesn't change. The built-in numberic types are all immutable. The cause for what you're observing is that:
print range[0] uses str on the float, which (up until very recent versions of Python) printed less digits of a float.
Printing a tuple (be it with repr or str) uses repr on the individual items, which gives a much more accurate representation (again, this isn't true anymore in recent releases which use a better algorithm for both).
As for why the condition doesn't work out the way you expect, it's propably the usual culprit, the limited precision of floats. Try print repr(curVal), repr(range[0]) to see if what Python decided was the closest representation of your float literal possible.
In modern day PC's floats aren't that precise. So even if you enter pi as a constant to 100 decimals, it's only getting a few of them accurate. The same is happening to you. This is because in 32-bit floats you only get 24 bits of mantissa, which limits your precision (and in unexpected ways because it's in base2).
Please note, 0.00145000000671 isn't the exact value as stored by Python. Python only diplays a few decimals of the complete stored float if you use print. If you want to see exactly how python stores the float use repr.
If you want better precision use the decimal module.
It isn't changing per se. Python is doing its best to store the data as a float, but that number is too precise for float, so Python modifies it before it is even accessed (in the very process of storing it). Funny how something so small is such a big pain.
You need to use a arbitrary fixed point module like Simple Python Fixed Point or the decimal module.
Not sure it would work in this case, because I don't know if Python's limiting in the output or in the storage itself, but you could try doing:
if curValue - range[0] > 0 and...

Python float - str - float weirdness

>>> float(str(0.65000000000000002))
0.65000000000000002
>>> float(str(0.47000000000000003))
0.46999999999999997 ???
What is going on here?
How do I convert 0.47000000000000003 to string and the resultant value back to float?
I am using Python 2.5.4 on Windows.
str(0.47000000000000003) give '0.47' and float('0.47') can be 0.46999999999999997.
This is due to the way floating point number are represented (see this wikipedia article)
Note: float(repr(0.47000000000000003)) or eval(repr(0.47000000000000003)) will give you the expected result, but you should use Decimal if you need precision.
float (and double) do not have infinite precision. Naturally, rounding errors occur when you operate on them.
This is a Python FAQ
The same question comes up quite regularly in comp.lang.python also.
I think reason it is a FAQ is that because python is perfect in all other respects ;-), we expect it to perform arithmetic perfectly - just like we were taught at school. However, as anyone who has done a numerical methods course will tell you, floating point numbers are a very long way from perfect.
Decimal is a good alternative and if you want more speed and more options gmpy is great too.
by this example
I think this is an error in Python when you devide
>>> print(int(((48/5.0)-9)*5))
2
the easy way, I solve this problem by this
>>> print(int(round(((48/5.0)-9)*5,2)))
3

Categories