Python round to next highest power of 10 - python

How would I manage to perform math.ceil such that a number is assigned to the next highest power of 10?
# 0.04 -> 0.1
# 0.7 -> 1
# 1.1 -> 10
# 90 -> 100
# ...
My current solution is a dictionary that checks the range of the input number, but it's hardcoded and I would prefer a one-liner solution. Maybe I am missing a simple mathematical trick or a corresponding numpy function here?

You can use math.ceil with math.log10 to do this:
>>> 10 ** math.ceil(math.log10(0.04))
0.1
>>> 10 ** math.ceil(math.log10(0.7))
1
>>> 10 ** math.ceil(math.log10(1.1))
10
>>> 10 ** math.ceil(math.log10(90))
100
log10(n) gives you the solution x that satisfies 10 ** x == n, so if you round up x it gives you the exponent for the next highest power of 10.
Note that for a value n where x is already an integer, the "next highest power of 10" will be n:
>>> 10 ** math.ceil(math.log10(0.1))
0.1
>>> 10 ** math.ceil(math.log10(1))
1
>>> 10 ** math.ceil(math.log10(10))
10

Your problem is under-specified, you need to step back and ask some questions.
What type(s) are your inputs?
What type(s) do you want for your outputs?
For results less than 1, what exactly do you want to round to? Do you want actual powers of 10 or floating point approximations of powers of 10? You are aware that negative powers of 10 can't be expressed exactly in floating point right? Let's assume for now that you want floating point approximations of powers of 10.
If the input is exactly a power of 10 (or the closest floating point approximation of a power of 10), should the output be the same as the input? Or should it be the next power of 10 up? "10 -> 10" or "10 -> 100"? Let's assume the former for now.
Can your input values be any possible value of the types in question? or are they more constrained.
In another answer it was proposed to take the logarithm, then round up (ceiling function), then exponentiate.
def nextpow10(n):
return 10 ** math.ceil(math.log10(n))
Unfortunately this suffers from rounding errors. First of all n is converted from whatever data type it happens to have into a double precision floating point number, potentially introducing rounding errors, then the logarithm is calculated potentially introducing more rounding errors both in its internal calculations and in its result.
As such it did not take me long to find an example where it gave an incorrect result.
>>> import math
>>> from numpy import nextafter
>>> n = 1
>>> while (10 ** math.ceil(math.log10(nextafter(n,math.inf)))) > n:
... n *= 10
...
>>> n
10
>>> nextafter(n,math.inf)
10.000000000000002
>>> 10 ** math.ceil(math.log10(10.000000000000002))
10
It is also theoretically possible for it to fail in the other direction, though this seems to be much harder to provoke.
So for a robust solution for floats and ints we need to assume that the value of our logarithm is only approximate, and we must therefore test a couple of possibilities. Something along the lines of
def nextpow10(n):
p = round(math.log10(n))
r = 10 ** p
if r < n:
r = 10 ** (p+1)
return r;
I believe this code should give correct results for all arguments in a sensible real-world range of magnitudes. It will break for very small or very large numbers of non integer and non-floating point types because of issues converting them to floating point. Python special cases integer arguments to the log10 function in an attempt to prevent overflow, but still with a sufficiently massive integer it may be possible to force incorrect results due to rounding errors.
To test the two implementations I used the following test program.
n = -323 # 10**-324 == 0
while n < 1000:
v = 10 ** n
if v != nextpow10(v): print(str(v)+" bad")
try:
v = min(nextafter(v,math.inf),v+1)
except:
v += 1
if v > nextpow10(v): print(str(v)+" bad")
n += 1
This finds lots of failures in the naive implementation, but none in the improved implementation.

It seems you want rather the lowest next power of 10...
Here is a way using pure maths and no log, but recursion.
def ceiling10(x):
if (x > 10):
return ceiling10(x / 10) * 10
else:
if (x <= 1):
return ceiling10(10 * x) / 10
else:
return 10
for x in [1 / 1235, 0.5, 1, 3, 10, 125, 12345]:
print(x, ceiling10(x))

Check this out!
>>> i = 0.04123
>>> print i, 10 ** len(str(int(i))) if int(i) > 1 else 10 if i > 1.0 else 1 if i > 0.1 else 10 ** (1 - min([("%.100f" % i).replace('.', '').index(k) for k in [str(j) for j in xrange(1, 10) if str(j) in "%.100f" % i]]))
0.04123 0.1
>>> i = 0.712
>>> print i, 10 ** len(str(int(i))) if int(i) > 1 else 10 if i > 1.0 else 1 if i > 0.1 else 10 ** (1 - min([("%.100f" % i).replace('.', '').index(k) for k in [str(j) for j in xrange(1, 10) if str(j) in "%.100f" % i]]))
0.712 1
>>> i = 1.1
>>> print i, 10 ** len(str(int(i))) if int(i) > 1 else 10 if i > 1.0 else 1 if i > 0.1 else 10 ** (1 - min([("%.100f" % i).replace('.', '').index(k) for k in [str(j) for j in xrange(1, 10) if str(j) in "%.100f" % i]]))
1.1 10
>>> i = 90
>>> print i, 10 ** len(str(int(i))) if int(i) > 1 else 10 if i > 1.0 else 1 if i > 0.1 else 10 ** (1 - min([("%.100f" % i).replace('.', '').index(k) for k in [str(j) for j in xrange(1, 10) if str(j) in "%.100f" % i]]))
90 100
This code based on principle of ten's power in len(str(int(float_number))).
There are 4 cases:
int(i) > 1.
Float number - converted to int, thereafter string str() from it, will give us a string with length which is we are looking exactly. So, first part, for input i > 1.0 - it is ten 10 in power of this length.
& 3. Little branching: i > 1.0 and i > 0.1 <=> it is 10 and 1 respectively.
And last case, when i < 0.1: Here, ten shall be in negative power. To get first non zero element after comma, I've used such construction ("%.100f" % i).replace('.', '').index(k), where k run over [1:10] interval. Thereafter, take minimum of result list. And decrease by one, it is first zero, which shall be counted. Also, here standard python's index() may crash, if it will not find at least one of non-zero element from [1:10] interval, that is why in the end I must "filter" listing by occurrence: if str(j) in "%.100f" % i.
Additionally, to get deeper precise - %.100f may be taken differ.

I think the simplest way is:
import math
number = int(input('Enter a number: '))
next_pow_ten = round(10 ** math.ceil(math.log10(number)))
print(str(10) + ' power ' + str(round(math.log10(number))) + ' = '\
+ str(next_pow_ten))
I hope this help you.

a specific shortcut works for big-integers that are already coming in as string-format :
instead of having to first convert it to integer, or running it through the log()/ceiling() function, or perform any sort of modulo math, the next largest power-of-10 is simply :
10 ** length(big_int_str_var)
—- below : 1st one generates a string formatted power-of-10, the 2nd one is numeric
echo 23958699683561808518065081866850688652086158016508618152865101851111111111111 |
tee >( gpaste | gcat -n >&2; ) | gcat - |
python3 -c '\
import sys; [ print("1"+"0"*len(_.strip("\n"))) for _ in sys.stdin ]'
or '... [ print( 10 ** len(_.strip("\n"))) for _ in sys.stdin ]'
1 23958699683561808518065081866850688652086158016508618152865101851111111111111
1 100000000000000000000000000000000000000000000000000000000000000000000000000000

y = math.ceil(x)
z = y + (10 - (y % 10))
Something like this maybe? It's just off the top of my head but it worked when I tried a few numbers in terminal.

Related

Is ther any other way to get sum 1 to 100 with recursion?

I'm studing recursive function and i faced question of
"Print sum of 1 to n with no 'for' or 'while' "
ex ) n = 10
answer =
55
n = 100
answer = 5050
so i coded
import sys
sys.setrecursionlimit(1000000)
sum = 0
def count(n):
global sum
sum += n
if n!=0:
count(n-1)
count(n = int(input()))
print(sum)
I know it's not good way to get right answer, but there was a solution
n=int(input())
def f(x) :
if x==1 :
return 1
else :
return ((x+1)//2)*((x+1)//2)+f(x//2)*2
print(f(n))
and it works super well , but i really don't know how can human think that logic and i have no idea how it works.
Can you guys explain how does it works?
Even if i'm looking that formula but i don't know why he(or she) used like that
And i wonder there is another solution too (I think it's reall important to me)
I'm really noob of python and code so i need you guys help, thank you for watching this
Here is a recursive solution.
def rsum(n):
if n == 1: # BASE CASE
return 1
else: # RECURSIVE CASE
return n + rsum(n-1)
You can also use range and sum to do so.
n = 100
sum_1_to_n = sum(range(n+1))
you can try this:
def f(n):
if n == 1:
return 1
return n + f(n - 1)
print(f(10))
this function basically goes from n to 1 and each time it adds the current n, in the end, it returns the sum of n + n - 1 + ... + 1
In order to get at a recursive solution, you have to (re)define your problems in terms of finding the answer based on the result of a smaller version of the same problem.
In this case you can think of the result sumUpTo(n) as adding n to the result of sumUpTo(n-1). In other words: sumUpTo(n) = n + sumUpTo(n-1).
This only leaves the problem of finding a value of n for which you know the answer without relying on your sumUpTo function. For example sumUpTo(0) = 0. That is called your base condition.
Translating this to Python code, you get:
def sumUpTo(n): return 0 if n==0 else n + sumUpTo(n-1)
Recursive solutions are often very elegant but require a different way of approaching problems. All recursive solutions can be converted to non-recursive (aka iterative) and are generally slower than their iterative counterpart.
The second solution is based on the formula ∑1..n = n*(n+1)/2. To understand this formula, take a number (let's say 7) and pair up the sequence up to that number in increasing order with the same sequence in decreasing order, then add up each pair:
1 2 3 4 5 6 7 = 28
7 6 5 4 3 2 1  = 28
-- -- -- -- -- -- -- --
8 8 8 8 8 8 8 = 56
Every pair will add up to n+1 (8 in this case) and you have n (7) of those pairs. If you add them all up you get n*(n+1) = 56 which correspond to adding the sequence twice. So the sum of the sequence is half of that total n*(n+1)/2 = 28.
The recursion in the second solution reduces the number of iterations but is a bit artificial as it serves only to compensate for the error introduced by propagating the integer division by 2 to each term instead of doing it on the result of n*(n+1). Obviously n//2 * (n+1)//2 isn't the same as n*(n+1)//2 since one of the terms will lose its remainder before the multiplication takes place. But given that the formula to obtain the result mathematically is part of the solution doing more than 1 iteration is pointless.
There are 2 ways to find the answer
1. Recursion
def sum(n):
if n == 1:
return 1
if n <= 0:
return 0
else:
return n + sum(n-1)
print(sum(100))
This is a simple recursion code snippet when you try to apply the recurrent function
F_n = n + F_(n-1) to find the answer
2. Formula
Let S = 1 + 2 + 3 + ... + n
Then let's do something like this
S = 1 + 2 + 3 + ... + n
S = n + (n - 1) + (n - 2) + ... + 1
Let's combine them and we get
2S = (n + 1) + (n + 1) + ... + (n + 1) - n times
From that you get
S = ((n + 1) * n) / 2
So for n = 100, you get
S = 101 * 100 / 2 = 5050
So in python, you will get something like
sum = lambda n: ( (n + 1) * n) / 2
print(sum(100))

How do i make a python variable with infinite digits behind comma

Im working with a math paradox in python and i need the number variable to be 100% accurate, i want the variable/number to not have a limit to how many digits it is behind the comma. Im sorry if my english is bad and thanks for all help :D.
addition = 0.5
time = 0
lengthWalked = 0
nr = 0
while True:
nr += 1
time += addition
lengthWalked += addition
addition = addition / 2
print("nr: ",nr,"time: ",time,"Length walked: ",lengthWalked)
What this code does is add 0,5 then half of that or 0,25 then 0,125. You get the point. If the variable could hold infinite numbers it would continue forever with adding half the amount and never reach 1 but it only adds numbers 53 times and reaches 1 at 54
if your wondering, yes this is based on Zeno´s paradox
No physical computer can hold infinite data, but you can get high precision to the limits of process memory by using the fractions module:
>>> from fractions import Fraction
>>> walked = Fraction(0)
>>> addition = Fraction(1,2)
>>> while True:
... walked += addition
... print(walked)
... addition /= 2
...
1/2
3/4
7/8
15/16
31/32
63/64
127/128
255/256
511/512
1023/1024
2047/2048
4095/4096
8191/8192
#snip...
35835915874844867368926665039455365204129607103827921929128897517135717358887465018319582487209796698111/35835915874844867368919076489095108449946327955754392558399825615420669938882575126094039892345713852416
71671831749689734737853330078910730408259214207655843858257795034271434717774930036639164974419593396223/71671831749689734737838152978190216899892655911508785116799651230841339877765150252188079784691427704832
143343663499379469475706660157821460816518428415311687716515590068542869435549860073278329948839186792447/143343663499379469475676305956380433799785311823017570233599302461682679755530300504376159569382855409664
sympy will solve your problem, and then some :
>>> from sympy import symbols, summation, oo
>>> i, n = symbols('i n', integer=True)
>>> f = lambda n: summation(1/2**i, (i, 1, n))
>>> f(n)
-2*2**(-n - 1) + 1
>>> 1 - f(n)
2*2**(-n - 1)
>>> f(n) < 1
True
>>> f(1000)
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069375/10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376
>>> f(oo)
1
So yes, f(n) :
is stricly less than 1 for any n
can be calculated by sympy with 100% accuracy for any n
admits 1 as limit for n->∞

Print a large integer in Python

I'd like to print an large integer without the "e+XX" at the end in Python.
For example, when I write:
n = 100
k = 18
result = 1
i = 0
while i < k:
result = result * (n - i) / (i + 1)
i += 1
The result is 3.066451080298821e+19, and I would like to have 30664510802988208300.
If you want an integer, you have to use integer division, // instead of /, as mentioned in #farsil's deleted answer.
result = 1
k = 18
n = 100
for i in range(k):
result = result * (n - i) // (i + 1)
print(result)
This only gives the correct result if i + 1 is always a divisor of result * (n - i). However, this is always true, so we are fine.
You cannot use / because that will perform floating-point division, which will truncate the results to 56 bits. The correct result does not fit in 56 bits:
In [1]: int(float(30664510802988208300))
Out[1]: 30664510802988208128
# ^^^ oops... off by 172
Why is floor division safe?
In this case, when the division by 2 is performed, we have multiplied result by n and n-1, at least one of which is a multiple of 2. When i+1 is 3, then we have multiplied by n, n-1, and n-2, at least one of which is a multiple of 3. This pattern works for all numbers.
I think the question you really want to ask is 'how can I print a number in Python without scientific notation?'
The answer is, your number right now is a float. Try print(type(result)) and you will see it says float. You could type cast it to an integer by doing int(result), and it will show close to the full number, 30664510802988208128. It will be a bit off because of the memory size storage limitations of int vs float.
The better way to do this would be like:
result = 1
i = 0
while i < 18:
result = result * (100 - i) // (i + 1)
i += 1
print(result)
which will keep result as an int type. It now should print 30664510802988208300

Find the number of digits after the decimal point [duplicate]

This question already has answers here:
Easy way of finding decimal places
(16 answers)
Closed 4 months ago.
I'm trying to write a Python 2.5.4 code to write a function that takes a floating-point number x as input and returns the number of digits after the decimal point in x.
Here's my code:
def number_of_digits_post_decimal(x):
count = 0
residue = x -int(x)
if residue != 0:
multiplier = 1
while int(multiplier * residue) != (multiplier * residue):
count += 1
multiplier = 10 * multiplier
print count
print multiplier
print multiplier * residue
print int(multiplier * residue)
return count
print number_of_digits_post_decimal(3.14159)
The print statements within the while loop are only for debugging purposes.
Now when I run this code, I get the following as output.
1
10
1.4159
1
2
100
14.159
14
3
1000
141.59
141
4
10000
1415.9
1415
5
100000
14159.0
14158
6
1000000
141590.0
141589
7
10000000
1415900.0
1415899
8
100000000
14159000.0
14158999
9
1000000000
....
The final value of count as returned by this function is 17.
How to modify this code in order to achieve our desired result?
Here's a shortcut that you might like:
def num_after_point(x):
s = str(x)
if not '.' in s:
return 0
return len(s) - s.index('.') - 1
This was interesting! So if you run the following:
x = 3.14159
residue = x - int(x)
print residue
You will get the following result:
0.14158999999999988
This decimal does in fact have 17 digits. The only way that I found to override this was to avoid doing the subtraction (which is the root cause of the error, as you can see from the inaccuracy here). So this code should work as you expect:
def number_of_digits_post_decimal(x):
count = 0
residue = x -int(x)
if residue != 0:
multiplier = 1
while not (x*multiplier).is_integer():
count += 1
multiplier = 10 * multiplier
return count
This will just shift the decimal to the right until python identifies it as an integer (it will do a rightward shift exactly the number of times you want too). Your code actually worked as you intended for it to, something unintended just happened during the subtraction process. Hope this helps!
def decimal_places(f):
exp = -1
remainder = True
while remainder:
exp += 1
a = f * 10**exp
remainder = int(a) - a
return(exp)
def precision(f):
integer, remainder = str(f).split('.')
return len(remainder)

Generating digits of square root of 2

I want to generate the digits of the square root of two to 3 million digits.
I am aware of Newton-Raphson but I don't have much clue how to implement it in C or C++ due to lack of biginteger support. Can somebody point me in the right direction?
Also, if anybody knows how to do it in python (I'm a beginner), I would also appreciate it.
You could try using the mapping:
a/b -> (a+2b)/(a+b) starting with a= 1, b= 1. This converges to sqrt(2) (in fact gives the continued fraction representations of it).
Now the key point: This can be represented as a matrix multiplication (similar to fibonacci)
If a_n and b_n are the nth numbers in the steps then
[1 2] [a_n b_n]T = [a_(n+1) b_(n+1)]T
[1 1]
which now gives us
[1 2]n [a_1 b_1]T = [a_(n+1) b_(n+1)]T
[1 1]
Thus if the 2x2 matrix is A, we need to compute An which can be done by repeated squaring and only uses integer arithmetic (so you don't have to worry about precision issues).
Also note that the a/b you get will always be in reduced form (as gcd(a,b) = gcd(a+2b, a+b)), so if you are thinking of using a fraction class to represent the intermediate results, don't!
Since the nth denominators is like (1+sqrt(2))^n, to get 3 million digits you would likely need to compute till the 3671656th term.
Note, even though you are looking for the ~3.6 millionth term, repeated squaring will allow you to compute the nth term in O(Log n) multiplications and additions.
Also, this can easily be made parallel, unlike the iterative ones like Newton-Raphson etc.
EDIT: I like this version better than the previous. It's a general solution that accepts both integers and decimal fractions; with n = 2 and precision = 100000, it takes about two minutes. Thanks to Paul McGuire for his suggestions & other suggestions welcome!
def sqrt_list(n, precision):
ndigits = [] # break n into list of digits
n_int = int(n)
n_fraction = n - n_int
while n_int: # generate list of digits of integral part
ndigits.append(n_int % 10)
n_int /= 10
if len(ndigits) % 2: ndigits.append(0) # ndigits will be processed in groups of 2
decimal_point_index = len(ndigits) / 2 # remember decimal point position
while n_fraction: # insert digits from fractional part
n_fraction *= 10
ndigits.insert(0, int(n_fraction))
n_fraction -= int(n_fraction)
if len(ndigits) % 2: ndigits.insert(0, 0) # ndigits will be processed in groups of 2
rootlist = []
root = carry = 0 # the algorithm
while root == 0 or (len(rootlist) < precision and (ndigits or carry != 0)):
carry = carry * 100
if ndigits: carry += ndigits.pop() * 10 + ndigits.pop()
x = 9
while (20 * root + x) * x > carry:
x -= 1
carry -= (20 * root + x) * x
root = root * 10 + x
rootlist.append(x)
return rootlist, decimal_point_index
As for arbitrary big numbers you could have a look at The GNU Multiple Precision Arithmetic Library (for C/C++).
For work? Use a library!
For fun? Good for you :)
Write a program to imitate what you would do with pencil and paper. Start with 1 digit, then 2 digits, then 3, ..., ...
Don't worry about Newton or anybody else. Just do it your way.
Here is a short version for calculating the square root of an integer a to digits of precision. It works by finding the integer square root of a after multiplying by 10 raised to the 2 x digits.
def sqroot(a, digits):
a = a * (10**(2*digits))
x_prev = 0
x_next = 1 * (10**digits)
while x_prev != x_next:
x_prev = x_next
x_next = (x_prev + (a // x_prev)) >> 1
return x_next
Just a few caveats.
You'll need to convert the result to a string and add the decimal point at the correct location (if you want the decimal point printed).
Converting a very large integer to a string isn't very fast.
Dividing very large integers isn't very fast (in Python) either.
Depending on the performance of your system, it may take an hour or longer to calculate the square root of 2 to 3 million decimal places.
I haven't proven the loop will always terminate. It may oscillate between two values differing in the last digit. Or it may not.
The nicest way is probably using the continued fraction expansion [1; 2, 2, ...] the square root of two.
def root_two_cf_expansion():
yield 1
while True:
yield 2
def z(a,b,c,d, contfrac):
for x in contfrac:
while a > 0 and b > 0 and c > 0 and d > 0:
t = a // c
t2 = b // d
if not t == t2:
break
yield t
a = (10 * (a - c*t))
b = (10 * (b - d*t))
# continue with same fraction, don't pull new x
a, b = x*a+b, a
c, d = x*c+d, c
for digit in rdigits(a, c):
yield digit
def rdigits(p, q):
while p > 0:
if p > q:
d = p // q
p = p - q * d
else:
d = (10 * p) // q
p = 10 * p - q * d
yield d
def decimal(contfrac):
return z(1,0,0,1,contfrac)
decimal((root_two_cf_expansion()) returns an iterator of all the decimal digits. t1 and t2 in the algorithm are minimum and maximum values of the next digit. When they are equal, we output that digit.
Note that this does not handle certain exceptional cases such as negative numbers in the continued fraction.
(This code is an adaptation of Haskell code for handling continued fractions that has been floating around.)
Well, the following is the code that I wrote. It generated a million digits after the decimal for the square root of 2 in about 60800 seconds for me, but my laptop was sleeping when it was running the program, it should be faster that. You can try to generate 3 million digits, but it might take a couple days to get it.
def sqrt(number,digits_after_decimal=20):
import time
start=time.time()
original_number=number
number=str(number)
list=[]
for a in range(len(number)):
if number[a]=='.':
decimal_point_locaiton=a
break
if a==len(number)-1:
number+='.'
decimal_point_locaiton=a+1
if decimal_point_locaiton/2!=round(decimal_point_locaiton/2):
number='0'+number
decimal_point_locaiton+=1
if len(number)/2!=round(len(number)/2):
number+='0'
number=number[:decimal_point_locaiton]+number[decimal_point_locaiton+1:]
decimal_point_ans=int((decimal_point_locaiton-2)/2)+1
for a in range(0,len(number),2):
if number[a]!='0':
list.append(eval(number[a:a+2]))
else:
try:
list.append(eval(number[a+1]))
except IndexError:
pass
p=0
c=list[0]
x=0
ans=''
for a in range(len(list)):
while c>=(20*p+x)*(x):
x+=1
y=(20*p+x-1)*(x-1)
p=p*10+x-1
ans+=str(x-1)
c-=y
try:
c=c*100+list[a+1]
except IndexError:
c=c*100
while c!=0:
x=0
while c>=(20*p+x)*(x):
x+=1
y=(20*p+x-1)*(x-1)
p=p*10+x-1
ans+=str(x-1)
c-=y
c=c*100
if len(ans)-decimal_point_ans>=digits_after_decimal:
break
ans=ans[:decimal_point_ans]+'.'+ans[decimal_point_ans:]
total=time.time()-start
return ans,total
Python already supports big integers out of the box, and if that's the only thing holding you back in C/C++ you can always write a quick container class yourself.
The only problem you've mentioned is a lack of big integers. If you don't want to use a library for that, then are you looking for help writing such a class?
Here's a more efficient integer square root function (in Python 3.x) that should terminate in all cases. It starts with a number much closer to the square root, so it takes fewer steps. Note that int.bit_length requires Python 3.1+. Error checking left out for brevity.
def isqrt(n):
x = (n >> n.bit_length() // 2) + 1
result = (x + n // x) // 2
while abs(result - x) > 1:
x = result
result = (x + n // x) // 2
while result * result > n:
result -= 1
return result

Categories