Hey i'm a little noob still but i'm playing around with python and i want to round D to it's nearest decimal, C and H are fixed and D is the rawinput, the whole answer should be rounded but i keep getting decimals,i want this formula :
Q = Square root of [(2 * C * D)/H]
her's my code:*
import math
C=50
H=30
D=int(raw_input())
a=int(round(D))
Q= math.sqrt(2*C*a/H)
print Q
if i enter 100 i get 18.24
i just want it to be 18
i would really appreciate your help, thanks
import math
C = 50
H = 30
a = int(raw_input())
# prints as a float
# Q = round(math.sqrt(2 * C * a / H), 0)
# prints as an int
Q = int(round(math.sqrt(2 * C * a / H), 0))
print Q
Your code appears to be rounding in the wrong place. You're rounding the input a, which was already the integer D. You're not rounding the result of the square root Q, which is a float.
Note that you're code actually has an extra rounding step you may not intend in it. When you divide two integers in Python 2, you'll get another integer, even if the computation should have had a remainder. You get floor division, always rounding towards negative infinity, not to the nearest integer (so e.g. 9/10 is 0). In your code, 2*C*a is an integer, since all values you're multiplying are, and so when you divide by h (another integer), it's going to round the division off. In the case you gave where you entered 100 as the user input, you'll get 333 as the result of the division instead of the more precise 333.3333333333333. This in turn makes your square root calculation give a different value (18.24828759089466 instead of 18.257418583505537).
Anyway, you probably want to use floating point values everywhere except maybe at the end when you round off the value before printing it. You almost certainly don't want to be using integer math by accident as your current code does. One way to do that is to turn one of your constant values into a float, and move the rounding to the end:
C=50.0 # make the calculations use floats, rather than ints
H=30
D=int(raw_input()) # no need for `a` anymore, we're rounding later instead
Q= int(round(math.sqrt(2*C*D/H))) # round after taking the square root, not before
An alternative to using C=50.0 is to put from __future__ import division at the top of your file, which tells Python that you want division between integers to return a float. That's the default behavior in Python 3, and it's much nicer most of the time. If you specifically want "floor" division, you can explicitly ask for it with the // operator. You might also consider actually using Python 3, rather than making do with Python 2's forwards compatibility features.
Related
Let's say I have an arbitrary integer 874,623,123 how do I round it down to 800,000,000 and up to 900,000,000? Another example is 759 round up to 800 or down to 700. The size of the integer is unknown.
Is there a built-in method to do it? If not, what's the best way to work it out? Sorry not a math expert here.
EDIT:
So far I have looked at
Rounding down integers to nearest multiple
Python round up integer to next hundred
Both use a predefined divider
You can use the math module:
import math
n = 874623123
# c contains the same number of digits as n
c = 10 ** int(math.log10(n))
print(math.floor(n/c) * c) # 800000000
print(math.ceil(n/c) * c) # 900000000
I have some number 0.0000002345E^-60. I want to print the floating point value as it is.
What is the way to do it?
print %f truncates it to 6 digits. Also %n.nf gives fixed numbers. What is the way to print without truncation.
Like this?
>>> print('{:.100f}'.format(0.0000002345E-60))
0.0000000000000000000000000000000000000000000000000000000000000000002344999999999999860343602938602754
As you might notice from the output, it’s not really that clear how you want to do it. Due to the float representation you lose precision and can’t really represent the number precisely. As such it’s not really clear where you want the number to stop displaying.
Also note that the exponential representation is often used to more explicitly show the number of significant digits the number has.
You could also use decimal to not lose the precision due to binary float truncation:
>>> from decimal import Decimal
>>> d = Decimal('0.0000002345E-60')
>>> p = abs(d.as_tuple().exponent)
>>> print(('{:.%df}' % p).format(d))
0.0000000000000000000000000000000000000000000000000000000000000000002345
You can use decimal.Decimal:
>>> from decimal import Decimal
>>> str(Decimal(0.0000002345e-60))
'2.344999999999999860343602938602754401109865640550232148836753621775217856801120686600683401464097113374472942165409862789978024748827516129306833728589548440037314681709534891496105046826414763927459716796875E-67'
This is the actual value of float created by literal 0.0000002345e-60. Its value is a number representable as python float which is closest to actual 0.0000002345 * 10**-60.
float should be generally used for approximate calculations. If you want accurate results you should use something else, like mentioned Decimal.
If I understand, you want to print a float?
The problem is, you cannot print a float.
You can only print a string representation of a float. So, in short, you cannot print a float, that is your answer.
If you accept that you need to print a string representation of a float, and your question is how specify your preferred format for the string representations of your floats, then judging by the comments you have been very unclear in your question.
If you would like to print the string representations of your floats in exponent notation, then the format specification language allows this:
{:g} or {:G}, depending whether or not you want the E in the output to be capitalized). This gets around the default precision for e and E types, which leads to unwanted trailing 0s in the part before the exponent symbol.
Assuming your value is my_float, "{:G}".format(my_float) would print the output the way that the Python interpreter prints it. You could probably just print the number without any formatting and get the same exact result.
If your goal is to print the string representation of the float with its current precision, in non-exponentiated form, User poke describes a good way to do this by casting the float to a Decimal object.
If, for some reason, you do not want to do this, you can do something like is mentioned in this answer. However, you should set 'max_digits' to sys.float_info.max_10_exp, instead of 14 used in the answer. This requires you to import sys at some point prior in the code.
A full example of this would be:
import math
import sys
def precision_and_scale(x):
max_digits = sys.float_info.max_10_exp
int_part = int(abs(x))
magnitude = 1 if int_part == 0 else int(math.log10(int_part)) + 1
if magnitude >= max_digits:
return (magnitude, 0)
frac_part = abs(x) - int_part
multiplier = 10 ** (max_digits - magnitude)
frac_digits = multiplier + int(multiplier * frac_part + 0.5)
while frac_digits % 10 == 0:
frac_digits /= 10
scale = int(math.log10(frac_digits))
return (magnitude + scale, scale)
f = 0.0000002345E^-60
p, s = precision_and_scale(f)
print "{:.{p}f}".format(f, p=p)
But I think the method involving casting to Decimal is probably better, overall.
I know that questions about rounding in python have been asked multiple times already, but the answers did not help me. I'm looking for a method that is rounding a float number half up and returns a float number. The method should also accept a parameter that defines the decimal place to round to. I wrote a method that implements this kind of rounding. However, I think it does not look elegant at all.
def round_half_up(number, dec_places):
s = str(number)
d = decimal.Decimal(s).quantize(
decimal.Decimal(10) ** -dec_places,
rounding=decimal.ROUND_HALF_UP)
return float(d)
I don't like it, that I have to convert float to a string (to avoid floating point inaccuracy) and then work with the decimal module.
Do you have any better solutions?
Edit: As pointed out in the answers below, the solution to my problem is not that obvious as correct rounding requires correct representation of numbers in the first place and this is not the case with float. So I would expect that the following code
def round_half_up(number, dec_places):
d = decimal.Decimal(number).quantize(
decimal.Decimal(10) ** -dec_places,
rounding=decimal.ROUND_HALF_UP)
return float(d)
(that differs from the code above just by the fact that the float number is directly converted into a decimal number and not to a string first) to return 2.18 when used like this: round_half_up(2.175, 2) But it doesn't because Decimal(2.175) will return Decimal('2.17499999999999982236431605997495353221893310546875'), the way the float number is represented by the computer.
Suprisingly, the first code returns 2.18 because the float number is converted to string first. It seems that the str() function conducts an implicit rounding to the number that was initially meant to be rounded. So there are two roundings taking place. Even though this is the result that I would expect, it is technically wrong.
Rounding is surprisingly hard to do right, because you have to handle floating-point calculations very carefully. If you are looking for an elegant solution (short, easy to understand), what you have like like a good starting point. To be correct, you should replace decimal.Decimal(str(number)) with creating the decimal from the number itself, which will give you a decimal version of its exact representation:
d = Decimal(number).quantize(...)...
Decimal(str(number)) effectively rounds twice, as formatting the float into the string representation performs its own rounding. This is because str(float value) won't try to print the full decimal representation of the float, it will only print enough digits to ensure that you get the same float back if you pass those exact digits to the float constructor.
If you want to retain correct rounding, but avoid depending on the big and complex decimal module, you can certainly do it, but you'll still need some way to implement the exact arithmetics needed for correct rounding. For example, you can use fractions:
import fractions, math
def round_half_up(number, dec_places=0):
sign = math.copysign(1, number)
number_exact = abs(fractions.Fraction(number))
shifted = number_exact * 10**dec_places
shifted_trunc = int(shifted)
if shifted - shifted_trunc >= fractions.Fraction(1, 2):
result = (shifted_trunc + 1) / 10**dec_places
else:
result = shifted_trunc / 10**dec_places
return sign * float(result)
assert round_half_up(1.49) == 1
assert round_half_up(1.5) == 2
assert round_half_up(1.51) == 2
assert round_half_up(2.49) == 2
assert round_half_up(2.5) == 3
assert round_half_up(2.51) == 3
Note that the only tricky part in the above code is the precise conversion of a floating-point to a fraction, and that can be off-loaded to the as_integer_ratio() float method, which is what both decimals and fractions do internally. So if you really want to remove the dependency on fractions, you can reduce the fractional arithmetic to pure integer arithmetic; you stay within the same line count at the expense of some legibility:
def round_half_up(number, dec_places=0):
sign = math.copysign(1, number)
exact = abs(number).as_integer_ratio()
shifted = (exact[0] * 10**dec_places), exact[1]
shifted_trunc = shifted[0] // shifted[1]
difference = (shifted[0] - shifted_trunc * shifted[1]), shifted[1]
if difference[0] * 2 >= difference[1]: # difference >= 1/2
shifted_trunc += 1
return sign * (shifted_trunc / 10**dec_places)
Note that testing these functions brings to spotlight the approximations performed when creating floating-point numbers. For example, print(round_half_up(2.175, 2)) prints 2.17 because the decimal number 2.175 cannot be represented exactly in binary, so it is replaced by an approximation that happens to be slightly smaller than the 2.175 decimal. The function receives that value, finds it smaller than the actual fraction corresponding to the 2.175 decimal, and decides to round it down. This is not a quirk of the implementation; the behavior derives from properties of floating-point numbers and is also present in the round built-in of Python 3 and 2.
I don't like it, that I have to convert float to a string (to avoid
floating point inaccuracy) and then work with the decimal module. Do
you have any better solutions?
Yes; use Decimal to represent your numbers throughout your whole program, if you need to represent numbers such as 2.675 exactly and have them round to 2.68 instead of 2.67.
There is no other way. The floating point number which is shown on your screen as 2.675 is not the real number 2.675; in fact, it is very slightly less than 2.675, which is why it gets rounded down to 2.67:
>>> 2.675 - 2
0.6749999999999998
It only shows in string form as '2.675' because that happens to be the shortest string such that float(s) == 2.6749999999999998. Note that this longer representation (with lots of 9s) isn't exact either.
However you write your rounding function, it is not possible for my_round(2.675, 2) to round up to 2.68 and also for my_round(2 + 0.6749999999999998, 2) to round down to 2.67; because the inputs are actually the same floating point number.
So if your number 2.675 ever gets converted to a float and back again, you have already lost the information about whether it should round up or down. The solution is not to make it float in the first place.
After trying for a very long time to produce an elegant one-line function, I ended up getting something that is comparable to a dictionary in size.
I would say the simplest way to do this is just to
def round_half_up(inp,dec_places):
return round(inp+0.0000001,dec_places)
i would acknowledge that this is not accurate in every cases, but should work if you just want a simple quick workaround.
This question already has answers here:
How can I force division to be floating point? Division keeps rounding down to 0?
(11 answers)
Closed 8 years ago.
I am trying to make a BMI calculator function. I am learning python at pyschools.
This is my code:
# Note: Return a string of 1 decimal place.
def BMI(weight, height):
x = weight /(height*height)
g = round(x,1)
return g
And pyschools shows me that these are the right answers:
With 110 = weight and 2 = height I am supposed to get a BMI of 27,5.
But I instead get 27.
Then it does a second check to make sure I wrote the code right and tells me 24,2 is the right answer but my program did return 24,2. But it still marks my answer in red and says "my" 24,2 is wrong and the website's is right.
If someone has a better site or anything to learn python it would also be appreciated since this website seems to be kind of wrong sometimes. And I am looking for free online resources. No books please.
To fix it for all cases, add this line to the top:
from __future__ import division # Make division work like in Python 3.
in Python 2, / means integer division.
With this in mind, in Python 2 if you pass intgers into division, it will give you an integer back. Anything that would have been a float is floored*. Therefore another option to get the desired result is to pass a float in, so instead of:
weight / (height*height)
do:
float(weight) / (height*height) # float in means float out.
*This means that only full times that the divisor goes in are counted. So 1/2 will get 0 because 2 goes fully into 1 0 times.
def BMI(weight, height):
x = float(weight) /(height*height)
g = round(x,1)
return g
see Python division
and Binary arithmetic operations
The issue lies with your division.
Division as we intrinsically know it is floating point division, or division where 1 / 2 evaluates to a fraction, 0.5. In standard programatic division, the 1, 2 are ints() and therefore cant be fractions, or floats() as the type is called in python. The expression, 1 / 2 therefore evaluates as 0, as 2 as a whole integer cant go into one entirely any times.
Ex:
In [1]: 1 / 2
Out[1]: 0
# Explicitly what is going on, since 1 and 2 are ints.
In [2]: int(1) / int(2)
Out[2]: 0
#fixed with floating division
In [3]: float(1) / float(2)
Out[3]: 0.5
# protip: only one of the divisors needs to be a float for python to divide correctly.
In [4]: 1 / float(2)
Out[4]: 0.5
Use x = weight / float((height*height)) to get the results you expect.
# Note: Return a string of 1 decimal place.
def BMI(weight, height):
x = weight / float((height*height))
g = round(x,1)
return g
This question already has answers here:
Using integer division in Python
(2 answers)
Closed 8 years ago.
Basically i made this program to practice python ( i am a complete noob at it), i am quite enjoying python, as my first programming langauge ever learnt or in the process of i feel very accomplished when completeing a program that works ( even if it is hello world). So anyways, i made a small program using techniques i had learnt from books and stuff from the internet and i have an issue, the program works fine, without problems but at the end there is a division where it justr goes wrong, it cannot divide anything unless it makes a whole number (eg. 100/20=5 but if i did 20/100 it would equel 0 and not 0.2), this also effects it if the number is going to be negative it just panics. i tried 15/20 to see if it was rounding but it still said 0.Any help would be fantastic ^_^
here is the code:
a=100
b=50
c=10
z=110
o=5
zoo=z+o+o
print "What is the value of zoo if:"
print "z=110"
print "o=5"
print "zoo=z+o+o"
import time
time.sleep(5)
print zoo,"of course!"
import time
time.sleep(1)
print "Wait..",a+b-(c)*3,"is the same as zoo except we just did it there using other code!"
import time
time.sleep(3)
print "We did it using 100+50-(10)*3 which then adds to zoo or 120!"
import time
time.sleep(3)
print "were gonna try something fun now!"
import time
time.sleep(2)
print "Please pick a number:"
number=int(raw_input())
print "and another:"
another=int(raw_input())
print "the two numbers you chose multiplied together makes",number*another
import time
time.sleep(2)
print "ok now were going to take your two numbers and divide them"
print "Your two numbers divided=",number/another
import time
time.sleep(1)
print "Ok im bored now, im going to go, have a nice day ^_^"
and here is the awnser with a problem:
What is the value of zoo if:
z=110
o=5
zoo=z+o+o
120 of course!
Wait.. 120 is the same as zoo except we just did it there using other code!
We did it using 100+50-(10)*3 which then adds to zoo or 120!
were gonna try something fun now!
Please pick a number:
15
and another:
20
the two numbers you chose multiplied together makes 300
ok now were going to take your two numbers and divide them
Your two numbers divided= 0
Ok im bored now, im going to go, have a nice day ^_^
oh and im on python 2.7.6
Add above this line:
print "Your two numbers divided=",number/another
this code:
number, another = number + .0, another + .0
The reason your code doesn't work is because you're using int's. When you divide with integers, they return an integer or a whole number. You need to convert the numbers to floats by adding .0 to the numbers. This will allow you to get absolute division results.
You can add
from __future__ import division
at the top of your file. Then the default division strategy will be what you expect, i.e. floating point division. Python 2.7 does integer division by default.
The / quotient of two int's, in Python 2.x, is an int.
The / quotient of one int and one float, in Python 2.x, is a float.
The / quotient of two floats, in Python 2.x, is a float.
The / quotient of two int's, in Python 3.x, is a float.
The / quotient of one int and one float, in Python 3.x, is a float.
The / quotient of two floats in Python 3.x, is a float.
The // quotient of two int's, in Python 3.x, is an int.
The // quotient of one int and one float, in Python 3.x, is a whole-number float.
The // quotient of two floats in Python 3.x, is a whole-number float.
In Python 2.x, you can "from __future__ import division" at the top of your module, to get the 3.x behavior.
So since you're using 2.x, you probably should either "from __future__ import division" at the top of your module, or convert one or both of your int's to float with float(int_var) prior to / division.
To add to all answers. In some languages (including python) division operator result depends on value types being used e.g.:
>>> 1 / 2 # integer divided by integer
0
>>> 1.0 / 2 # float divided by integer
0.5
15/20 = 0 when performing an integer division since the result is less than 1. Therefore it truncates to 0.
// is used for dividing integers and / for floats- you are using the wrong operator so you get an incorrect result:
>>> 15 / 20
0
>>> 15 // 20
0.75
You can fix this by adding from from __future__ import division to your script. This will always perform a float division when using the / operator and use // for integer division- so just do what you are doing and it will return the expected result:
>>> from __future__ import division
>>> 15 / 20
0.75
I would use the above solution, with the import; but there are other ways. Another option would be making at least one of the operands a float, e.g. float(number) / another.
>>> number = 15
>>> another = 20
>>> float(number) / another
0.75
The above works because the result of the division depends on value types being used, in Python.