I want to calculate additions of a very large number (type, float) and a very small number using Python 2.7.
For example:
>> x = 1546439400046560970.
>> y = 1.
>> print(int(x + y))
1546439400046561024
This is not right. Correct answer is 1546439400046560971.
I realize that the problem is due to type cast from float to int. How could I solve this problem, if I want to get the correct answer?
I realize that the problem is due to type cast from float to int.
Not really. The float itself does not store your value precisely. You can prove that this is the case by converting to a type that has more precision than a float, for example decimal.
>>> import decimal
>>> decimal.decimal(1546439400046560971.)
Decimal('1546439400046561024')
So any solution that initially stores x as a float is doomed to fail, even if you never use the int type.
One possible solution is to store your values as decimals to begin with. Remember to initialize them using strings and not floats, or else the precision will be lost.
>>> from decimal import Decimal
>>> x = Decimal("1546439400046560971")
>>> y = Decimal("1")
>>> x+y
Decimal('1546439400046560972')
Related
wondering if someone came across this issue before
I'm trying to cast a float column in a dataframe to integer , and i'm getting strange results, this is my code :
proj_id['test2'] = proj_id['campaign_id'].astype('int64')
proj_id[proj_id['campaign_id']==23847591030830034][['campaign_id','test2']]
so my campaign_id which was
23847591030830034
becomes 23847591030830032
i have tried to suppress scientific expression, rounding, ... but it seems like the conversion truncates a byte off my integer
thank you for your help
This seems like it is a matter of representation.
When you do indexing you are casting 23847591030830034 to float which then gets compared with another float that is more accurately represented as 23847591030830032.0 but it is a difference so small that it gets rounded to the same float:
>>> floated = float(23847591030830034)
>>> inted = 23847591030830032
>>> floated == float(inted)
True
So it seems that the float representation for both integers is the same hence the discrepancy.
I'm a beginner trying to learn Python and decided to try an exercise where I would take an input, and distinguish its type; whether its an integer, floating point or a string.
As I understand it, Python treats all inputs as strings, so even when I enter a number/decimal point, the input is considered a string. I have overcome the first step in differentiating whether the input is a string or otherwise via this:
def get():
prompt = 'Give a number or a word.\n'
x = input(prompt)
try:
float(x)
print('You entered a number.')
except:
print('You entered a string.')
I take advantage of 'try' and 'except', as float(x) will return an error if x is a string and not a number/floating point. Next, I deduce that I can use a similar method to distinguish between integers and floating point numbers, but I don't know what can cause an error for an integer that wouldn't for a floating point, vice versa. (since float(x) where x is an integer works fine)
Is there such a thing so that I can use a similar method to distinguish between decimal number inputs and integers?
There are two questions within your question.
To handle the string > int/float, you could take advantage of ast.literal_eval first:
>>> import ast
>>> print(type(ast.literal_eval("2"))
int
>>> print(type(ast.literal_eval("3.4"))
float
>>> print(ast.literal_eval("3e2"))
300.0
To check for type, you're looking for isinstance I think.
>>> x = 2
>>> print(isinstance(x, int))
True
>>> y = 3.4
>>> print(isinstance(y, int))
False
>>> print(isinstance(y, float))
True
So, putting these two together you could use an if statement like that:
if isinstance(ast.literal_eval(x), int):
# do whatever you want if it's an int
elif isinstance(ast.literal_eval(x), float):
# do whatever you want if it's a float
It depends on what your definition of an integer is. Is "3.0" an integer? Or just "3"? The former is most commonly represented as a floating point number whose value happens to be a mathematical integer (but not of int type).
If you mean to include "3.0", then you can do a test which catches both "3.0" and "3":
f = float(x)
if f==int(f):
print("really an integer value")
Otherwise you can use isinstance(f, int).
(Caveat: this is easier in Python3. In Python2 there are two kinds of integers -- int and long which you have to test for separately).
The input is alway a string.
You just want to know if that string can be converted to an int or a float value. You can easily convince yourself that most(*) integer representation can be converted to float values while the symetric is not true.
So you should
try to convert to an int
if it failed try to convert to a float
if it still failed process input as a string
The rationale is that if the user typed 3.0 they probably intended that it should be a float value, else they would have typed 3.
Python integers are only limited by the available memory while float are 64 bits iEEE-754 floating point numbers. But Python is kind enough to convert integers greater to the max float values to inf. So even an integer that cannot be represented as a float would be converted with no exception
Can someone explain me why x and y give completely different results?
>>> x=int(5) * 1e50
>>> x
5e+50
>>> y=int(5e50)
>>> y
499999999999999996610474337180813988230854220972032
The python manual says that integer can be of arbitrary length regardless the available memory, x and y as I known are integers but the result is completely different but are equivalent expressions, is 5e50 interpreted as float before int conversion? If so, why?
int(5) is an int, 1e50 is a float. If you multiply them, the int(5) will be converted to the larger type (which is a float) and then multiplied with 1e50. The result is of type float, not int.
int(5e50) converts the float to an int and is therefore printed as an integer of, as you say, arbitrary length.
I have a string in the format: 'nn.nnnnn' in Python, and I'd like to convert it to an integer.
Direct conversion fails:
>>> s = '23.45678'
>>> i = int(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '23.45678'
I can convert it to a decimal by using:
>>> from decimal import *
>>> d = Decimal(s)
>>> print d
23.45678
I could also split on '.', then subtract the decimal from zero, then add that to the whole number ... yuck.
But I'd prefer to have it as an int, without unnecessary type conversions or maneuvering.
How about this?
>>> s = '23.45678'
>>> int(float(s))
23
Or...
>>> int(Decimal(s))
23
Or...
>>> int(s.split('.')[0])
23
I doubt it's going to get much simpler than that, I'm afraid. Just accept it and move on.
What sort of rounding behavior do you want? Do you 2.67 to turn into 3, or 2. If you want to use rounding, try this:
s = '234.67'
i = int(round(float(s)))
Otherwise, just do:
s = '234.67'
i = int(float(s))
>>> s = '23.45678'
>>> int(float(s))
23
>>> int(round(float(s)))
23
>>> s = '23.54678'
>>> int(float(s))
23
>>> int(round(float(s)))
24
You don't specify if you want rounding or not...
You could use:
s = '23.245678'
i = int(float(s))
"Convert" only makes sense when you change from one data type to another without loss of fidelity. The number represented by the string is a float and will lose precision upon being forced into an int.
You want to round instead, probably (I hope that the numbers don't represent currency because then rounding gets a whole lot more complicated).
round(float('23.45678'))
The expression int(float(s)) mentioned by others is the best if you want to truncate the value. If you want rounding, using int(round(float(s)) if the round algorithm matches what you want (see the round documentation), otherwise you should use Decimal and one if its rounding algorithms.
round(float("123.789"))
will give you an integer value, but a float type. With Python's duck typing, however, the actual type is usually not very relevant. This will also round the value, which you might not want. Replace 'round' with 'int' and you'll have it just truncated and an actual int. Like this:
int(float("123.789"))
But, again, actual 'type' is usually not that important.
I believe this is a useless bug that should be corrected in Python.
int('2') --> 2 That converts the string '2' into an the integer 2.
int(2.7) --> 2 Converts a float to an int.
int('2.7') SHOULD convert to 2. This is how Perl works, for example. Yes, this does two things at once. It converts the string and when it finds it is in a representation that is a float, it should convert to int.
Otherwise, why insist that float('2') should work? It is an integer string, because there is no decimal point. So it has to convert from string which is an integer, directly to float.
I don't know but perhaps someone can answer whether the python interpreter, if the required int(float(x)) is used, if it actually goes through the process of first converting to float and then converting to int. That would make this bug even more critical to correct.
I am looking for a way to perform a digit divided by larger value(2/5000000) and then store that value in table, but the problem is when i save that value, only 0 is stored , instead of correct value.I tried with float, double precision, but still only 0 is stored, is there any other way .
Thank you
Remember to operate on floating numbers, and not convert it after the operation. E.g. 2/5000000.
Also, use the Decimal library, if you are looking for more accurate decimals.
You need to use floating point division. To be explicit, you can cast ints to float:
>>> a = 2
>>> b = 5000000
>>> c = a/float(b)
>>> c
4e-07
You can cast either a or b to float.