Inconsistent behavior with int() and float() [duplicate] - python

This question already has answers here:
Counterintuitive behaviour of int() in python
(4 answers)
Closed 3 years ago.
In python, when converting strings to floats, float() converts both integers or decimals representations to a number:
float('3.5') gives 3.5
float('3') gives 3
float() also converts integers to floats:
float(3) gives 3.0
Why does int() not convert a string decimal to an integer if it can convert a float to an integer? For example:
int(3.5) gives 3,
however int('3.5') raises an ValueErrorexception.
This makes one use something like int(float('3.5')) when wanting to convert a string into an integer while not knowing whether or not the number will be a decimal.
Why is there this difference between float() and int()?

I would say, why not?
This is more like a precaution of conversion. It tries to be careful and conservative as conversion can lost data precision in an unexpected way. By saying int(float("3.5")), your intention is explicit. But int("3.5") -- do you expect that is not an integer and you are ready to give up that 0.5 difference? Such issue does not exists in float("3.5").
If you want int("3.5") to give you back the integer without raising error, would it be natural to also ask for int("four"), int("3.5 # ignore this comment"), int("XLII") to be valid? That would be too much.

Related

invalid literal for int() with base 10: '2,674' [duplicate]

This question already has answers here:
How to use digit separators for Python integer literals?
(4 answers)
Closed 3 years ago.
Unable to convert a string to an integer. Getting Error:
ValueError: invalid literal for int() with base 10: '2674'
I have read many answers and most of them the reason for not working is because it is a float and people use int(), but here clearly it is an integer.
like1 = '2,674 likes'
number = int(like1.split()[0])
print('This is the numer ::',number)
I expect the code to run without an error and print out the number. My actual implementation is to compare it with an integer. For eg. number > 1000, but that throws up the error that you can't compare a string and int, therefore I wanted to modify it into an int. I did not want to post that code since it was pretty big and messy.
Please ask for clarifications, if I have missed any required details!
Your problem is the comma in 2,674. Some locations use that as a decimal point, but your location does not, and you want it to separate groups of three digits in an integer. Python does not use it in that way.
So either remove the comma or change it to an underscore, _, which recent versions of Python allow in an integer. Since I do not know your version of Python I recommend removing the comma. Use this:
number = int(like1.split()[0].replace(',', ''))
By the way, the error message you show at the top of your question is not the actual error message. The actual message shows the comma in the string:
ValueError: invalid literal for int() with base 10: '2,674'
If you continue asking questions on this site, be sure to show the actual errors. In fact, you should copy and paste the entire traceback, not just the final line. That will help us to correctly understand your problem and help you.

Python - why can `int(x, 2)` only be used on strings, but not on integers?

I have this example code:
test = 1011
test2 = int(test, 2)
print(test2)
which will throw an error saying
int() can't convert non-string with explicit base
The code works when i wrap test into str(), since the int-conversion needs a string as an input.
My question: Why is that so, and is there no easy way to convert on bases while accepting int? I find it rather counter-intuitive that an interger conversion method requires a string as an input.
Because applying it to integers makes no sense
In your example test is a number. It has no base. All numbers are like this: binary 0x1011, decimal 11 and hexadecimal 0x0B are the exact same number. The three ways of writing it are just different ways of writing down the same thing, just as using the Chinese character for 3, δΈ‰, would be. Internally, of course, in computers numbers represented in binary - e.g. 0b1111110011 - but can be displayed in any base you like. Bases are only relevant when converting a number to, or from, a string.
However, if you wanted to set test using a binary representation you could simply write:
test = 0b1011
This function only works on strings because the base is only relevant if you have a string representation of the number.
If you have an integer, there is no associated base, it's a number. And then, you can represent it as a string in base 2, 16 or 10 (or any other you want).

python Decimal() with extreme precision acting funky [duplicate]

This question already has answers here:
Why python decimal.Decimal precision differs with equable args?
(2 answers)
Closed 5 years ago.
I know this has been asked numerous times and I've come across many blogs and SO answers but this one's making me pull my hair out. I just want to multiply a two decimal number by 100 so I get rid of its decimals:
>>> 4321.90 * 100
432189.99999999994
>>> Decimal(4321.90) * Decimal(100)
Decimal('432189.9999999999636202119291')
I'm scared to use rounding for such seemingly trivial operation. Would it be safe? What if the precision problem plays tricks on me and the result is close to xxx.5? Can that happen? I do understand the problem at the binary level, but I come from C# and I don't have that problem with .Net's decimal type:
decimal x = 4321.90m;
decimal y = 100m;
Console.WriteLine(x * y);
432190,00
I thought Python's decimal module was supposed to fix that. I'm about to convert the initial value to string and do the math with string manipulations, and I feel bad about it...
The main reason it fails with Python is because 4321.90 is interpreted as float (you lose precision at that point) and then casted to Decimal at runtime. With C# 4321.90m is interpreted as decimal to begin with. Python simply doesn't support decimals as a built-in structure.
But there's an easy way to fix that with Python. Simply use strings:
>>> Decimal('4321.90') * Decimal('100')
Decimal('432190.00')
I'm about to convert the initial value to string
Yes! (but don't do it by calling str - use a string literal)
and do the math with string manipulations
No!
When hardcoding a decimal value into your source code, you should initialize it from a string literal, not a float literal. With 4321.90, floating-point rounding has already occurred, and building a Decimal won't undo that. With "4321.90", Decimal has the original text you wrote available to perform an exact initialization:
Decimal('4321.90')
Floating point inaccuracy again.
Decimal(number) doesn't change a thing: the value is modified before it hits Decimal.
You can avoid that by passing strings to Decimal, though:
Decimal("4321.90") * Decimal("100")
result:
Decimal('432190.00')
(so Decimal handles the floating point numbers without using the floating point registers & operations at all)

Inaccuracy in decimals [duplicate]

This question already has answers here:
Why python decimal.Decimal precision differs with equable args?
(2 answers)
Closed 8 years ago.
I'm in the process of converting a programme I've made from using floats to decimals.
Obviously the main reason I'm doing this is for accuracy.
I haven't used decimal before so thought I'd have a play first. The first thing I did was this:
>>> x = Decimal(7.2)
>>> x
Decimal('7.20000000000000017763568394002504646778106689453125')
Now considering decimals meant to be accurate and avoid long trailing numbers like floats, I was pretty surprised to see that happen. It's also gone to 50 D.P. despite the standard preset of 28 (and doesn't matter what you set the preset too.
Is this a bug (|feature)? And why is it happening?
Decimal(7.2) will create a decimal from the exact value of the float 7.2. Since the float is not precise, while Decimal is, creating the decimal will carry over the inaccuracies from the float into the decimal, yielding the result you see there.
To create the exact decimal of 7.2, you need to specify it as a string:
Decimal('7.2')
This happens, because you feed a float literal, that cannot be represented accurately in binary. You should provide a string:
Decimal('7.2')
or use integers:
Decimal(72) / 10

How to compare float value in in Django [duplicate]

This question already has an answer here:
How to compare a variable value to an array
(1 answer)
Closed 10 years ago.
Hi i need to compare the float value in my project i am using the folowing code
if style_score.style_quiz_score ==float(17.40):
but it not works for this but when i change the value from 17.40 to 17 it works fine, please tell me how can i compare the float value
Comparing floats in python(or any language that relies on the underlying hardware representation of floats) is always going to be a tricky business. The best way to do it, is to define a tolerance within which you would consider two numbers to be equal(say, 10^-6) and then check if the absolute difference between the numbers is less than your tolerance.
Code:
TOLERANCE=10**-6
def are_floats_equal(a,b):
return abs(a-b) <= TOLERANCE
PS: if you really really want exact, arbitrary-precision, calculations with your floating point numbers, use the decimal module. Incidentally that page has some good examples of the failure points of regular floats. However, be aware that this is incredibly slower than using regular floats so don't do this unless you really really need it.
That's because of rounding errors. Never compare floats with ==, always use this template:
def floats_are_the_same(a,b): return abs(a-b) < 1e-6
if floats_are_the_same(value, 17.4):
....
i.e. check that the value is close to some desired value. This is because float arithmetic almost always has rounding errors:
>>> 17.1 + 0.3
17.400000000000002
See also: What is the best way to compare floats for almost-equality in Python?

Categories

Resources