Why does math.modf return floats? - python

from http://docs.python.org/2/library/math.html:
math.frexp(x)
Return the mantissa and exponent of x as the pair (m, e). m is a float and e is an integer such that x == m * 2**e exactly. If x is zero, returns (0.0, 0), otherwise 0.5 <= abs(m) < 1. This is used to “pick apart” the internal representation of a float in a portable way.
math.modf(x)
Return the fractional and integer parts of x. Both results carry the sign of x and are floats.
In this related question, it's pointed out that returning floats doesn't really make sense for ceil and floor, so in Python 3, they were changed to return integers. Is there some reason why the integer result of modf isn't returned as an integer, too? In Python 2.7:
In [2]: math.floor(5.5)
Out[2]: 5.0
In [3]: math.modf(5.5)
Out[3]: (0.5, 5.0)
In [4]: math.frexp(5.5)
Out[4]: (0.6875, 3)
In Python 3:
In [2]: math.floor(5.5)
Out[2]: 5
In [3]: math.modf(5.5)
Out[3]: (0.5, 5.0)
In [4]: math.frexp(5.5)
Out[4]: (0.6875, 3)

Most of the math module functions are thin wrappers around functions of the same name defined by the C language standard. frexp() and modf() are two such, and return the same things the C functions of the same names return.
So part of this is ease of inter-language operation.
But another part is practicality:
>>> from math import modf
>>> modf(1e100)
(0.0, 1e+100)
Would you really want to get 10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104 back as "the integer part"?
C can't possibly do so, because it doesn't have unbounded integers. Python simply doesn't want to do so ;-) Note that all floating-point values of sufficient magnitude are exact integers - although they may require hundreds of decimal digits to express.

Related

How do I calculate square root in Python?

I need to calculate the square root of some numbers, for example √9 = 3 and √2 = 1.4142. How can I do it in Python?
The inputs will probably be all positive integers, and relatively small (say less than a billion), but just in case they're not, is there anything that might break?
Related
Integer square root in python
How to find integer nth roots?
Is there a short-hand for nth root of x in Python?
Difference between **(1/2), math.sqrt and cmath.sqrt?
Why is math.sqrt() incorrect for large numbers?
Python sqrt limit for very large numbers?
Which is faster in Python: x**.5 or math.sqrt(x)?
Why does Python give the "wrong" answer for square root? (specific to Python 2)
calculating n-th roots using Python 3's decimal module
How can I take the square root of -1 using python? (focused on NumPy)
Arbitrary precision of square roots
Note: This is an attempt at a canonical question after a discussion on Meta about an existing question with the same title.
Option 1: math.sqrt()
The math module from the standard library has a sqrt function to calculate the square root of a number. It takes any type that can be converted to float (which includes int) as an argument and returns a float.
>>> import math
>>> math.sqrt(9)
3.0
Option 2: Fractional exponent
The power operator (**) or the built-in pow() function can also be used to calculate a square root. Mathematically speaking, the square root of a equals a to the power of 1/2.
The power operator requires numeric types and matches the conversion rules for binary arithmetic operators, so in this case it will return either a float or a complex number.
>>> 9 ** (1/2)
3.0
>>> 9 ** .5 # Same thing
3.0
>>> 2 ** .5
1.4142135623730951
(Note: in Python 2, 1/2 is truncated to 0, so you have to force floating point arithmetic with 1.0/2 or similar. See Why does Python give the "wrong" answer for square root?)
This method can be generalized to nth root, though fractions that can't be exactly represented as a float (like 1/3 or any denominator that's not a power of 2) may cause some inaccuracy:
>>> 8 ** (1/3)
2.0
>>> 125 ** (1/3)
4.999999999999999
Edge cases
Negative and complex
Exponentiation works with negative numbers and complex numbers, though the results have some slight inaccuracy:
>>> (-25) ** .5 # Should be 5j
(3.061616997868383e-16+5j)
>>> 8j ** .5 # Should be 2+2j
(2.0000000000000004+2j)
Note the parentheses on -25! Otherwise it's parsed as -(25**.5) because exponentiation is more tightly binding than unary negation.
Meanwhile, math is only built for floats, so for x<0, math.sqrt(x) will raise ValueError: math domain error and for complex x, it'll raise TypeError: can't convert complex to float. Instead, you can use cmath.sqrt(x), which is more more accurate than exponentiation (and will likely be faster too):
>>> import cmath
>>> cmath.sqrt(-25)
5j
>>> cmath.sqrt(8j)
(2+2j)
Precision
Both options involve an implicit conversion to float, so floating point precision is a factor. For example:
>>> n = 10**30
>>> x = n**2
>>> root = x**.5
>>> n == root
False
>>> n - root # how far off are they?
0.0
>>> int(root) - n # how far off is the float from the int?
19884624838656
Very large numbers might not even fit in a float and you'll get OverflowError: int too large to convert to float. See Python sqrt limit for very large numbers?
Other types
Let's look at Decimal for example:
Exponentiation fails unless the exponent is also Decimal:
>>> decimal.Decimal('9') ** .5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for ** or pow(): 'decimal.Decimal' and 'float'
>>> decimal.Decimal('9') ** decimal.Decimal('.5')
Decimal('3.000000000000000000000000000')
Meanwhile, math and cmath will silently convert their arguments to float and complex respectively, which could mean loss of precision.
decimal also has its own .sqrt(). See also calculating n-th roots using Python 3's decimal module
SymPy
Depending on your goal, it might be a good idea to delay the calculation of square roots for as long as possible. SymPy might help.
SymPy is a Python library for symbolic mathematics.
import sympy
sympy.sqrt(2)
# => sqrt(2)
This doesn't seem very useful at first.
But sympy can give more information than floats or Decimals:
sympy.sqrt(8) / sympy.sqrt(27)
# => 2*sqrt(6)/9
Also, no precision is lost. (√2)² is still an integer:
s = sympy.sqrt(2)
s**2
# => 2
type(s**2)
#=> <class 'sympy.core.numbers.Integer'>
In comparison, floats and Decimals would return a number which is very close to 2 but not equal to 2:
(2**0.5)**2
# => 2.0000000000000004
from decimal import Decimal
(Decimal('2')**Decimal('0.5'))**Decimal('2')
# => Decimal('1.999999999999999999999999999')
Sympy also understands more complex examples like the Gaussian integral:
from sympy import Symbol, integrate, pi, sqrt, exp, oo
x = Symbol('x')
integrate(exp(-x**2), (x, -oo, oo))
# => sqrt(pi)
integrate(exp(-x**2), (x, -oo, oo)) == sqrt(pi)
# => True
Finally, if a decimal representation is desired, it's possible to ask for more digits than will ever be needed:
sympy.N(sympy.sqrt(2), 1_000_000)
# => 1.4142135623730950488016...........2044193016904841204
NumPy
>>> import numpy as np
>>> np.sqrt(25)
5.0
>>> np.sqrt([2, 3, 4])
array([1.41421356, 1.73205081, 2. ])
docs
Negative
For negative reals, it'll return nan, so np.emath.sqrt() is available for that case.
>>> a = np.array([4, -1, np.inf])
>>> np.sqrt(a)
<stdin>:1: RuntimeWarning: invalid value encountered in sqrt
array([ 2., nan, inf])
>>> np.emath.sqrt(a)
array([ 2.+0.j, 0.+1.j, inf+0.j])
Another option, of course, is to convert to complex first:
>>> a = a.astype(complex)
>>> np.sqrt(a)
array([ 2.+0.j, 0.+1.j, inf+0.j])
Newton's method
Most simple and accurate way to compute square root is Newton's method.
You have a number which you want to compute its square root (num) and you have a guess of its square root (estimate). Estimate can be any number bigger than 0, but a number that makes sense shortens the recursive call depth significantly.
new_estimate = (estimate + num/estimate) / 2
This line computes a more accurate estimate with those 2 parameters. You can pass new_estimate value to the function and compute another new_estimate which is more accurate than the previous one or you can make a recursive function definition like this.
def newtons_method(num, estimate):
# Computing a new_estimate
new_estimate = (estimate + num/estimate) / 2
print(new_estimate)
# Base Case: Comparing our estimate with built-in functions value
if new_estimate == math.sqrt(num):
return True
else:
return newtons_method(num, new_estimate)
For example we need to find 30's square root. We know that the result is between 5 and 6.
newtons_method(30,5)
number is 30 and estimate is 5. The result from each recursive calls are:
5.5
5.477272727272727
5.4772255752546215
5.477225575051661
The last result is the most accurate computation of the square root of number. It is the same value as the built-in function math.sqrt().
This answer was originally posted by gunesevitan, but is now deleted.
Python's fractions module and its class, Fraction, implement arithmetic with rational numbers. The Fraction class doesn't implement a square root operation, because most square roots are irrational numbers. However, it can be used to approximate a square root with arbitrary accuracy, because a Fraction's numerator and denominator are arbitrary-precision integers.
The following method takes a positive number x and a number of iterations, and returns upper and lower bounds for the square root of x.
from fractions import Fraction
def sqrt(x, n):
x = x if isinstance(x, Fraction) else Fraction(x)
upper = x + 1
for i in range(0, n):
upper = (upper + x/upper) / 2
lower = x / upper
if lower > upper:
raise ValueError("Sanity check failed")
return (lower, upper)
See the reference below for details on this operation's implementation. It also shows how to implement other operations with upper and lower bounds (although there is apparently at least one error with the log operation there).
Daumas, M., Lester, D., Muñoz, C., "Verified Real Number Calculations: A Library for Interval Arithmetic", arXiv:0708.3721 [cs.MS], 2007.
Alternatively, using Python's math.isqrt, we can calculate a square root to arbitrary precision:
Square root of i within 1/2n of the correct value, where i is an integer:Fraction(math.isqrt(i * 2**(n*2)), 2**n).
Square root of i within 1/10n of the correct value, where i is an integer:Fraction(math.isqrt(i * 10**(n*2)), 10**n).
Square root of x within 1/2n of the correct value, where x is a multiple of 1/2n:Fraction(math.isqrt(x * 2**(n)), 2**n).
Square root of x within 1/10n of the correct value, where x is a multiple of 1/10n:Fraction(math.isqrt(x * 10**(n)), 10**n).
In the foregoing, i or x must be 0 or greater.
Binary search
Disclaimer: this is for a more specialised use-case. This method might not be practical in all circumstances.
Benefits:
can find integer values (i.e. which integer is the root?)
no need to convert to float, so better precision (can be done that well too)
I personally implemented this one for a crypto CTF challenge (RSA cube root attack),where I needed a precise integer value.
The general idea can be extended to any other root.
def int_squareroot(d: int) -> tuple[int, bool]:
"""Try calculating integer squareroot and return if it's exact"""
left, right = 1, (d+1)//2
while left<right-1:
x = (left+right)//2
if x**2 > d:
left, right = left, x
else:
left, right = x, right
return left, left**2==d
EDIT:
As #wjandrea have also pointed out, **this example code can NOT compute **. This is a side-effect of the fact that it does not convert anything into floats, so no precision is lost. If the root is an integer, you get that back. If it's not, you get the biggest number whose square is smaller than your number. I updated the code so that it also returns a bool indicating if the value is correct or not, and also fixed an issue causing it to loop infinitely (also pointed out by #wjandrea). This implementation of the general method still works kindof weird for smaller numbers, but above 10 I had no problems with.
Overcoming the issues and limits of this method/implementation:
For smaller numbers, you can just use all the other methods from other answers. They generally use floats, which might be a loss of precision, but for small integers that should mean no problem at all. All of those methods that use floats have the same (or nearly the same) limit from this.
If you still want to use this method and get float results, it should be trivial to convert this to use floats too. Note that that will reintroduce precision loss, this method's unique benefit over the others, and in that case you can also just use any of the other answers. I think the newton's method version converges a bit faster, but I'm not sure.
For larger numbers, where loss of precision with floats come into play, this method can give results closer to the actual answer (depending on how big is the input). If you want to work with non-integers in this range, you can use other types, for example fixed precision numbers in this method too.
Edit 2, on other answers:
Currently, and afaik, the only other answer that has similar or better precision for large numbers than this implementation is the one that suggest SymPy, by Eric Duminil. That version is also easier to use, and work for any kind of number, the only downside is that it requires SymPy. My implementation is free from any huge dependencies if that is what you are looking for.
Arbitrary precision square root
This variation uses string manipulations to convert a string which represents a decimal floating-point number to an int, calls math.isqrt to do the actual square root extraction, and then formats the result as a decimal string. math.isqrt rounds down, so all produced digits are correct.
The input string, num, must use plain float format: 'e' notation is not supported. The num string can be a plain integer, and leading zeroes are ignored.
The digits argument specifies the number of decimal places in the result string, i.e., the number of digits after the decimal point.
from math import isqrt
def str_sqrt(num, digits):
""" Arbitrary precision square root
num arg must be a string
Return a string with `digits` after
the decimal point
Written by PM 2Ring 2022.01.26
"""
int_part , _, frac_part = num.partition('.')
num = int_part + frac_part
# Determine the required precision
width = 2 * digits - len(frac_part)
# Truncate or pad with zeroes
num = num[:width] if width < 0 else num + '0' * width
s = str(isqrt(int(num)))
if digits:
# Pad, if necessary
s = '0' * (1 + digits - len(s)) + s
s = f"{s[:-digits]}.{s[-digits:]}"
return s
Test
print(str_sqrt("2.0", 30))
Output
1.414213562373095048801688724209
For small numbers of digits, it's faster to use decimal.Decimal.sqrt. Around 32 digits or so, str_sqrt is roughly the same speed as Decimal.sqrt. But at 128 digits, str_sqrt is 2.2× faster than Decimal.sqrt, at 512 digits, it's 4.3× faster, at 8192 digits, it's 7.4× faster.
Here's a live version running on the SageMathCell server.
find square-root of a number
while True:
num = int(input("Enter a number:\n>>"))
for i in range(2, num):
if num % i == 0:
if i*i == num:
print("Square root of", num, "==>", i)
break
else:
kd = (num**0.5) # (num**(1/2))
print("Square root of", num, "==>", kd)
OUTPUT:-
Enter a number: 24
Square root of 24 ==> 4.898979485566356
Enter a number: 36
Square root of 36 ==> 6
Enter a number: 49
Square root of 49 ==> 7
✔ Output 💡 CLICK BELOW & SEE ✔

Decimal fixed precision

I would like to use decimal in currency calculations, so I would like to work on exactly two numbers after comma. Initially I thought that prec of decimal's context refers to that property, but after a few experiments I feel a bit confused.
Experiment #1:
In [1]: import decimal
In [2]: decimal.getcontext().prec = 2
In [3]: a = decimal.Decimal('159.9')
In [4]: a
Out[4]: Decimal('159.9')
In [5]: b = decimal.Decimal('200')
In [6]: b
Out[6]: Decimal('200')
In [7]: b - a
Out[7]: Decimal('40')
Experiment #2:
In [8]: decimal.getcontext().prec = 4
In [9]: a = decimal.Decimal('159.9')
In [10]: a
Out[10]: Decimal('159.9')
In [11]: b = decimal.Decimal('200')
In [12]: b
Out[12]: Decimal('200')
In [13]: b - a
Out[13]: Decimal('40.1')
Experiment #3: (prec is still set to 4)
In [14]: a = decimal.Decimal('159999.9')
In [15]: a
Out[15]: Decimal('159999.9')
In [16]: b = decimal.Decimal('200000')
In [17]: b
Out[17]: Decimal('200000')
In [18]: b - a
Out[18]: Decimal('4.000E+4')
Why does it work like in my examples? How should I work with decimals in my (currency calculations) case?
The precision sets the number of significant digits, which is not equivalent to the number of digits after the decimal point.
So if you have a precision of 2, you'll have two significant digits, so a number with 3 significant digits like 40.1 will be reduced to the upper two significant digits giving 40.
There's no easy way to set the number of digits after the decimal point with Decimal. However you could use a high precision and always round your results to two decimals:
>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 60 # use a higher/lower one if needed
>>> Decimal('200') - Decimal('159.9')
Decimal('40.1')
>>> r = Decimal('200') - Decimal('159.9')
>>> round(r, 2)
Decimal('40.10')
The decimal FAQ also includes a similar question and answer (using quantize):
Q. In a fixed-point application with two decimal places, some inputs have many places and need to be rounded. Others are not supposed to have excess digits and need to be validated. What methods should be used?
A. The quantize() method rounds to a fixed number of decimal places. If the Inexact trap is set, it is also useful for validation:
>>> TWOPLACES = Decimal(10) ** -2 # same as Decimal('0.01')
>>> # Round to two places
>>> Decimal('3.214').quantize(TWOPLACES)
Decimal('3.21')
>>> # Validate that a number does not exceed two places
>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Decimal('3.21')
>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Traceback (most recent call last):
...
Inexact: None
Q. Once I have valid two place inputs, how do I maintain that invariant throughout an application?
A. Some operations like addition, subtraction, and multiplication by an integer will automatically preserve fixed point. Others operations, like division and non-integer multiplication, will change the number of decimal places and need to be followed-up with a quantize() step:
>>> a = Decimal('102.72') # Initial fixed-point values
>>> b = Decimal('3.17')
>>> a + b # Addition preserves fixed-point
Decimal('105.89')
>>> a - b
Decimal('99.55')
>>> a * 42 # So does integer multiplication
Decimal('4314.24')
>>> (a * b).quantize(TWOPLACES) # Must quantize non-integer multiplication
Decimal('325.62')
>>> (b / a).quantize(TWOPLACES) # And quantize division
Decimal('0.03')
In developing fixed-point applications, it is convenient to define functions to handle the quantize() step:
>>> def mul(x, y, fp=TWOPLACES):
... return (x * y).quantize(fp)
>>> def div(x, y, fp=TWOPLACES):
... return (x / y).quantize(fp)
>>> mul(a, b) # Automatically preserve fixed-point
Decimal('325.62')
>>> div(b, a)
Decimal('0.03')
The best method I've found is to set a high prec and use Decimal.quantize to round your result:
decimal.getcontext().prec=100
a = Decimal('400000.123456789')
b = Decimal('200000.0')
a-b
>>> Decimal('2.0000E+5')
(a-b).quantize(Decimal('0.01'))
>>> Decimal('200000.12')

numpy arange: how to make "precise" array of floats?

In short, the problem I encounter is this:
aa = np.arange(-1., 0.001, 0.01)
aa[-1]
Out[16]: 8.8817841970012523e-16
In reality, this cause a series problem since my simulations doesn't allow positive value inputs.
I can sort of get around by doing:
aa = np.arange(-100, 1, 1)/100.
aa[-1]
Out[21]: 0.0
But this is a pain. Practically you can't do this every time.
This seems like such a basic problem. There's gotta be something I am missing here.
By the way, I am using Python 2.7.13.
This happens because Python (like most modern programming languages) uses floating point arithmetic, which cannot exactly represent some numbers (see Is floating point math broken?).
This means that, regardless of whether you're using Python 2, Python 3, R, C, Java, etc. you have to think about the effects of adding two floating point numbers together.
np.arange works by repeatedly adding the step value to the start value, and this leads to imprecision in the end:
>>> start = -1
>>> for i in range(1000):
... start += 0.001
>>> start
8.81239525796218e-16
Similarly:
>>> x = np.arange(-1., 0.001, 0.01)
>>> x[-1]
8.8817841970012523e-16
The typical pattern used to circumvent this is to work with integers whenever possible if repeated operations are needed. So, for example, I would do something like this:
>>> x = 0.01 * np.arange(-100, 0.1)
>>> x[-1]
0.0
Alternatively, you could create a one-line convenience function that will do this for you:
>>> def safe_arange(start, stop, step):
... return step * np.arange(start / step, stop / step)
>>> x = safe_arange(-1, 0.001, 0.01)
>>> x[-1]
0
But note that even this can't get around the limits of floating point precision; for example, the number -0.99 cannot be represented exactly in floating point:
>>> val = -0.99
>>> print('{0:.20f}'.format(val))
-0.98999999999999999112
So you must always keep that in mind when working with floating point numbers, in any language.
Using np.linespace solved it for me:
For example np.linspace(0.5, 0.9, 5) produce [0.5 0.6 0.7 0.8 0.9].
We don't get to forget about the limitations of floating-point arithmetics. Repeatedly adding 0.01, or rather the double-precision float that is close to 0.01, will result in the kind of effects you observe.
To ensure that an array does not contain positive numbers, use numpy.clip:
aa = np.clip(np.arange(-1., 0.001, 0.01), None, 0)
I have the same problem as you do.
Here is a simple solution:
for b in np.arange(maxb,minb+stepb,stepb):
for a in np.arange(mina,maxa+stepa,stepa):
a=round(a,2);b=round(b,2); # 2 is the size of the floating part.

Different behavior of float32/float64 numpy variables

after googling a while, I'm posting here for help.
I have two float64 variables returned from a function.
Both of them are apparently 1:
>>> x, y = somefunc()
>>> print x,y
>>> if x < 1 : print "x < 1"
>>> if y < 1 : print "y < 1"
1.0 1.0
y < 1
Behavior changes when variables are defined float32, in which case the 'y<1' statement doesn't appear.
I tried setting
np.set_printoptions(precision=10)
expecting to see the differences between variables but even so, both of them appear as 1.0 when printed.
I am a bit confused at this point.
Is there a way to visualize the difference of these float64 numbers?
Can "if/then" be used reliably to check float64 numbers?
Thanks
Trevarez
The printed values are not correct. In your case y is smaller than 1 when using float64 and bigger or equal to 1 when using float32. this is expected since rounding errors depend on the size of the float.
To avoid this kind of problems, when dealing with floating point numbers you should always decide a "minimum error", usually called epsilon and, instead of comparing for equality, checking whether the result is at most distant epsilon from the target value:
In [13]: epsilon = 1e-11
In [14]: number = np.float64(1) - 1e-16
In [15]: target = 1
In [16]: abs(number - target) < epsilon # instead of number == target
Out[16]: True
In particular, numpy already provides np.allclose which can be useful to compare arrays for equality given a certain tolerance. It works even when the arguments aren't arrays(e.g. np.allclose(1 - 1e-16, 1) -> True).
Note however than numpy.set_printoptions doesn't affect how np.float32/64 are printed. It affects only how arrays are printed:
In [1]: import numpy as np
In [2]: np.float(1) - 1e-16
Out[2]: 0.9999999999999999
In [3]: np.array([1 - 1e-16])
Out[3]: array([ 1.])
In [4]: np.set_printoptions(precision=16)
In [5]: np.array([1 - 1e-16])
Out[5]: array([ 0.9999999999999999])
In [6]: np.float(1) - 1e-16
Out[6]: 0.9999999999999999
Also note that doing print y or evaluating y in the interactive interpreter gives different results:
In [1]: import numpy as np
In [2]: np.float(1) - 1e-16
Out[2]: 0.9999999999999999
In [3]: print(np.float64(1) - 1e-16)
1.0
The difference is that print calls str while evaluating calls repr:
In [9]: str(np.float64(1) - 1e-16)
Out[9]: '1.0'
In [10]: repr(np.float64(1) - 1e-16)
Out[10]: '0.99999999999999989'
In [26]: x = numpy.float64("1.000000000000001")
In [27]: print x, repr(x)
1.0 1.0000000000000011
In other words, you are plagued by loss of precision in print statement. The value is very slightly different than 1.
Following the advices provided here I summarize the answers in this way:
To make comparisons between floats, the programmer has to define a minimum distance (eps) for them to be considered different (eps=1e-12, for example). Doing so, the conditions should be written like this:
Instead of (x>a), use (x-a)>eps
Instead of (x<a), use (a-x)>eps
Instead of (x==a), use abs(x-a)<eps
This doesn't apply to comparison between integer numbers since difference between them is fixed to 1.
Hope it helps others as it helped me.

How do you round UP a number?

How does one round a number UP in Python?
I tried round(number) but it rounds the number down. Example:
round(2.3) = 2.0
and not 3, as I would like.
The I tried int(number + .5) but it round the number down again! Example:
int(2.3 + .5) = 2
The math.ceil (ceiling) function returns the smallest integer higher or equal to x.
For Python 3:
import math
print(math.ceil(4.2))
For Python 2:
import math
print(int(math.ceil(4.2)))
I know this answer is for a question from a while back, but if you don't want to import math and you just want to round up, this works for me.
>>> int(21 / 5)
4
>>> int(21 / 5) + (21 % 5 > 0)
5
The first part becomes 4 and the second part evaluates to "True" if there is a remainder, which in addition True = 1; False = 0. So if there is no remainder, then it stays the same integer, but if there is a remainder it adds 1.
If working with integers, one way of rounding up is to take advantage of the fact that // rounds down: Just do the division on the negative number, then negate the answer. No import, floating point, or conditional needed.
rounded_up = -(-numerator // denominator)
For example:
>>> print(-(-101 // 5))
21
Interesting Python 2.x issue to keep in mind:
>>> import math
>>> math.ceil(4500/1000)
4.0
>>> math.ceil(4500/1000.0)
5.0
The problem is that dividing two ints in python produces another int and that's truncated before the ceiling call. You have to make one value a float (or cast) to get a correct result.
In javascript, the exact same code produces a different result:
console.log(Math.ceil(4500/1000));
5
You might also like numpy:
>>> import numpy as np
>>> np.ceil(2.3)
3.0
I'm not saying it's better than math, but if you were already using numpy for other purposes, you can keep your code consistent.
Anyway, just a detail I came across. I use numpy a lot and was surprised it didn't get mentioned, but of course the accepted answer works perfectly fine.
Use math.ceil to round up:
>>> import math
>>> math.ceil(5.4)
6.0
NOTE: The input should be float.
If you need an integer, call int to convert it:
>>> int(math.ceil(5.4))
6
BTW, use math.floor to round down and round to round to nearest integer.
>>> math.floor(4.4), math.floor(4.5), math.floor(5.4), math.floor(5.5)
(4.0, 4.0, 5.0, 5.0)
>>> round(4.4), round(4.5), round(5.4), round(5.5)
(4.0, 5.0, 5.0, 6.0)
>>> math.ceil(4.4), math.ceil(4.5), math.ceil(5.4), math.ceil(5.5)
(5.0, 5.0, 6.0, 6.0)
I am surprised nobody suggested
(numerator + denominator - 1) // denominator
for integer division with rounding up. Used to be the common way for C/C++/CUDA (cf. divup)
The syntax may not be as pythonic as one might like, but it is a powerful library.
https://docs.python.org/2/library/decimal.html
from decimal import *
print(int(Decimal(2.3).quantize(Decimal('1.'), rounding=ROUND_UP)))
For those who want to round up a / b and get integer:
Another variant using integer division is
def int_ceil(a, b):
return (a - 1) // b + 1
>>> int_ceil(19, 5)
4
>>> int_ceil(20, 5)
4
>>> int_ceil(21, 5)
5
Note: a and b must be non-negative integers
Here is a way using modulo and bool
n = 2.3
int(n) + bool(n%1)
Output:
3
Try this:
a = 211.0
print(int(a) + ((int(a) - a) != 0))
Be shure rounded value should be float
a = 8
b = 21
print math.ceil(a / b)
>>> 0
but
print math.ceil(float(a) / b)
>>> 1.0
The above answers are correct, however, importing the math module just for this one function usually feels like a bit of an overkill for me. Luckily, there is another way to do it:
g = 7/5
g = int(g) + (not g.is_integer())
True and False are interpreted as 1 and 0 in a statement involving numbers in python. g.is_interger() basically translates to g.has_no_decimal() or g == int(g). So the last statement in English reads round g down and add one if g has decimal.
In case anyone is looking to round up to a specific decimal place:
import math
def round_up(n, decimals=0):
multiplier = 10 ** decimals
return math.ceil(n * multiplier) / multiplier
Without importing math // using basic envionment:
a) method / class method
def ceil(fl):
return int(fl) + (1 if fl-int(fl) else 0)
def ceil(self, fl):
return int(fl) + (1 if fl-int(fl) else 0)
b) lambda:
ceil = lambda fl:int(fl)+(1 if fl-int(fl) else 0)
>>> def roundup(number):
... return round(number+.5)
>>> roundup(2.3)
3
>>> roundup(19.00000000001)
20
This function requires no modules.
x * -1 // 1 * -1
Confusing but it works: For x=7.1, you get 8.0. For x = -1.1, you get -1.0
No need to import a module.
For those who doesn't want to use import.
For a given list or any number:
x = [2, 2.1, 2.5, 3, 3.1, 3.5, 2.499,2.4999999999, 3.4999999,3.99999999999]
You must first evaluate if the number is equal to its integer, which always rounds down. If the result is True, you return the number, if is not, return the integer(number) + 1.
w = lambda x: x if x == int(x) else int(x)+1
[w(i) for i in z]
>>> [2, 3, 3, 3, 4, 4, 3, 3, 4, 4]
Math logic:
If the number has decimal part: round_up - round_down == 1, always.
If the number doens't have decimal part: round_up - round_down == 0.
So:
round_up == x + round_down
With:
x == 1 if number != round_down
x == 0 if number == round_down
You are cutting the number in 2 parts, the integer and decimal. If decimal isn't 0, you add 1.
PS:I explained this in details since some comments above asked for that and I'm still noob here, so I can't comment.
If you don't want to import anything, you can always write your own simple function as:
def RoundUP(num):
if num== int(num):
return num
return int(num + 1)
To do it without any import:
>>> round_up = lambda num: int(num + 1) if int(num) != num else int(num)
>>> round_up(2.0)
2
>>> round_up(2.1)
3
I know this is from quite a while back, but I found a quite interesting answer, so here goes:
-round(-x-0.5)
This fixes the edges cases and works for both positive and negative numbers, and doesn't require any function import
Cheers
I'm surprised I haven't seen this answer yet round(x + 0.4999), so I'm going to put it down. Note that this works with any Python version. Changes made to the Python rounding scheme has made things difficult. See this post.
Without importing, I use:
def roundUp(num):
return round(num + 0.49)
testCases = list(x*0.1 for x in range(0, 50))
print(testCases)
for test in testCases:
print("{:5.2f} -> {:5.2f}".format(test, roundUp(test)))
Why this works
From the docs
For the built-in types supporting round(), values are rounded to the closest multiple of 10 to the power minus n; if two multiples are equally close, rounding is done toward the even choice
Therefore 2.5 gets rounded to 2 and 3.5 gets rounded to 4. If this was not the case then rounding up could be done by adding 0.5, but we want to avoid getting to the halfway point. So, if you add 0.4999 you will get close, but with enough margin to be rounded to what you would normally expect. Of course, this will fail if the x + 0.4999 is equal to [n].5000, but that is unlikely.
You could use round like this:
cost_per_person = round(150 / 2, 2)
You can use floor devision and add 1 to it.
2.3 // 2 + 1
when you operate 4500/1000 in python, result will be 4, because for default python asume as integer the result, logically:
4500/1000 = 4.5 --> int(4.5) = 4
and ceil of 4 obviouslly is 4
using 4500/1000.0 the result will be 4.5 and ceil of 4.5 --> 5
Using javascript you will recieve 4.5 as result of 4500/1000, because javascript asume only the result as "numeric type" and return a result directly as float
Good Luck!!
I think you are confusing the working mechanisms between int() and round().
int() always truncates the decimal numbers if a floating number is given; whereas round(), in case of 2.5 where 2 and 3 are both within equal distance from 2.5, Python returns whichever that is more away from the 0 point.
round(2.5) = 3
int(2.5) = 2
My share
I have tested print(-(-101 // 5)) = 21 given example above.
Now for rounding up:
101 * 19% = 19.19
I can not use ** so I spread the multiply to division:
(-(-101 //(1/0.19))) = 20
I'm basically a beginner at Python, but if you're just trying to round up instead of down why not do:
round(integer) + 1

Categories