Cube root
Introduction
editCalculation
editPreparation
edit
It is desired to calculate the cube root of real number
where:
# python code.
NormalizeNumberDebug = 0
def NormalizeNumber (number) :
'''
sign, newNumber, exponent = NormalizeNumber (number)
sign & exponent are both ints.
newNumber is Decimal object.
1000 > newNumber >= 1 and
exponent % 3 = 0.
This prepares number for cube root of number.
eg, 1234.56e-2 becomes 12.3456
123.456e7 becomes 1.23456e9
'''
number = D(str(number))+0
if number == 0 : return (0, D(0), 0)
sign, digits, exponent = tuple(number.as_tuple())
digits = list(digits)
# Remove leading zeroes.
while (digits[0] == 0) : digits[:1] = []
# Remove trailing zeroes.
while (digits[-1] == 0) :
digits[-1:] = [] ; exponent += 1
# Ensure that there are at least 3 digits.
while ( len(digits) < 3 ) :
digits += [0]; exponent -= 1
# Ensure that exponent is exactly divisible by 3.
while exponent % 3 :
digits += [0] ; exponent -= 1
# Insert the decimal point so that there are exactly 1 or 2 or 3
# digits to left of decimal point.
len1 = len(digits) % 3
if len1 == 0 : len1 = 3
len2 = len(digits) - len1
digits[len1:len1] = '.' ; exponent += len2
# Produce number reformatted.
str1 = ''.join( [ str(v) for v in digits ] )
newNumber = D(str1)
# If necessary, check.
if NormalizeNumberDebug :
v1 = D( ('', '-')[sign] + str1 + 'e' + str(exponent) )
if v1 != number :
print ('NormalizeNumber (number) : error', v1 , '!=', number)
return sign, newNumber, exponent
|
Implementation
edit
Newton's method is used to derive the root starting with # python code.
simpleCubeRootDebug = 0
def simpleCubeRoot (N) :
if simpleCubeRootDebug :
print ('simpleCubeRoot (N): N =',N)
if N == 0 : return D(0)
if abs(N) == 1 : return D(str(N))
sign1, n, exponent = NormalizeNumber (N)
if 1 <= n < 1000 : pass
else :
print ('simpleCubeRoot (N) : internal error 1.')
return None
x = 5 # Starting value of x.
y = x*x*x - n # Starting value of y.
count = 33 ; L1 = []
while count :
count -= 1
if simpleCubeRootDebug :
print ('simpleCubeRoot (N) : x,y =',x,y)
slope = 3*x*x
delta_x = y/slope
x -= delta_x
if x in L1[-1:-5:-1] :
# This value of x has been used previously.
break
L1 += [x]
y = x*x*x - n
if count == 0 :
print ('simpleCubeRoot (N): count expired.')
multiplier1 = (1,-1)[bool(sign1)]
exponent1, remainder = divmod (exponent, 3)
if remainder :
print ('simpleCubeRoot (N): internal error 2.')
return None
multiplier2 = 10**D(exponent1)
root3 = (multiplier1 * x * multiplier2).normalize() # The cube root.
if simpleCubeRootDebug :
print ('simpleCubeRoot (N): root3 =',root3)
return root3
|
Examples
edit(-27)^(⅓)
edit
axis compressed for clarity. Newton's method quickly finds result: # python code.
import decimal
D = decimal.Decimal
simpleCubeRootDebug = 1
N = -27
v = simpleCubeRoot (N)
print ('cube root of',N,'=',v)
|
N small
edit
# python code.
import decimal
D = decimal.Decimal
simpleCubeRootDebug = 1
N = (D('654.12345')**3)* D('1e-234')
v = simpleCubeRoot (N)
print ('cube root of',N,'=',v)
simpleCubeRoot (N): N = 2.79884698523170070963625E-226
simpleCubeRoot (N) : x,y = 5 -154.884698523170070963625
simpleCubeRoot (N) : x,y = 7.065129313642267612848333333 72.7786652269624099669721028
simpleCubeRoot (N) : x,y = 6.579122227796059655581363000 4.8916155561565606595741185
simpleCubeRoot (N) : x,y = 6.541452268317643764895392436 0.0279543788313674002066771
simpleCubeRoot (N) : x,y = 6.541234507249539089853395935 9.305743731604330476E-7
simpleCubeRoot (N) : x,y = 6.541234500000000008034541024 1.0313397688E-15
simpleCubeRoot (N) : x,y = 6.541234500000000000000000000 0E-25
simpleCubeRoot (N): root3 = 6.5412345E-76
cube root of 2.79884698523170070963625E-226 = 6.5412345E-76
|
N with 102 decimal digits
edit
# python code.
import decimal
D = decimal.Decimal
prec = decimal.getcontext().prec = 110. # Precision.
simpleCubeRootDebug = 0
N = D('91234567890.12345678901234567890123')**3
v = simpleCubeRoot (N)
print ('cube root of',N,'=',v)
cube root of 759413404032709802223035921205529.781633123988862756497856617560063741408069807576943069432557725290867 = 91234567890.12345678901234567890123
|