# Introduction

The natural logarithm of any real number ${\text{x}}$ greater than zero is usually denoted by abbreviation ${\text{ln(x)}}.$
For example, natural logarithm of $5$ is:
The base of the system of natural logarithms is the number ${\text{e}}$ which may be calculated as follows:
${\text{e}}$ raised to power $\ln(x)=x.$
When $y=a^{x}$ we know from calculus that ${\frac {\Delta y}{\Delta x}}=a^{x}\cdot {\frac {a^{\Delta x}-1}{\Delta x}}$ and that ${\frac {dy}{dx}}=a^{x}\cdot \ln(a).$
Therefore $\ln(a)=\lim _{\Delta x\rightarrow 0}{\frac {a^{\Delta x}-1}{\Delta x}}.$
Let $\Delta x={\frac {1}{2^{200}}}.$ Then $a^{\Delta x}$ is ${\sqrt {a}}$ taken $200$ times.
Calculate $\ln(e):$
Number of accurate digits in result is about $0.3\cdot ({\text{pre}}).$
This calculation of $\ln(e)$ is accurate to $60$ places of decimals, not bad for one line of simple python code using high-school math.
If all we want to do is calculate $\ln(x),$ we can stop here. However, this method contains many calculations of .sqrt, very time consuming.
While simple and accurate, this method is slow.
This page presents a system for calculating $\ln(x)$ that is much faster than this simple method.
* Generally, for $x$ close to $x_{0}:$
* ${\text{ln}}(x)={\text{ln}}(x_{0})+K$ where:
* $K={\frac {1}{1}}\cdot {\frac {x-x_{0}}{x_{0}}}$
* $-{\frac {1}{2}}\cdot {\frac {(x-x_{0})^{2}}{x_{0}^{2}}}$
* $+{\frac {1}{3}}\cdot {\frac {(x-x_{0})^{3}}{x_{0}^{3}}}$
* $-{\frac {1}{4}}\cdot {\frac {(x-x_{0})^{4}}{x_{0}^{4}}}$
* $+{\frac {1}{5}}\cdot {\frac {(x-x_{0})^{5}}{x_{0}^{5}}}-\cdots$
* On this page we pay close attention to value ${\frac {x-x_{0}}{x_{0}}},$ trying to get this value as small as possible
* so that calculation of $K$ converges quickly.

# Data Structures
## values_of_x0

* # python code.
* import decimal
* dD = Decimal = decimal.Decimal
* dgt = decimal.getcontext
* Precision = dgt.prec = 100
* length = 8191
* base = dD(10) ** (dD(1)/(length-1))
* list1 = [ base**p for p in range (0,length) ]
* dgt.prec = 30
* list2 = [ +v for v in list1 ]
* values_of_x0 = tuple(list2)
* def print_values_of_x0 (print_all=0) :
* This function prints contents of tuple values_of_x0.
* Default is to print reduced listing.
* lines =
* for p in range (0, len(values_of_x0)) :
* lines += [ " '', # base **".format(values_of_x0[p], p) ]
* new_line = '''
* '''[-1:]
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'tuple([ dD(v) for v in ])'.format(str2)
* values_of_x01 = eval(str3)
* (values_of_x01 == values_of_x0) or ([3])
* if print_all : pass
* else :
* lines[15:len(values_of_x0)-15] = ( [ ' '+('#'*22) ] * 3 )
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'tuple([ dD(v) for v in ])'.format(str2)
* if 1 :
* str10 = '''
* # Tuple values_of_x0 contains values from 1 through 10 both included.
* # Values have precision of.
* # Number of lines printed =.'''.lstrip
* str11 = str10.format(
* len(values_of_x0),
* dgt.prec,
* len(lines),
* print_str = '''
* # python code
* import decimal
* dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
* values_of_x0 =
* print (print_str.format(
* str11,
* str3,
* if (len(lines) > 35) : print (str11)
* print_values_of_x0
* Tuple values_of_x0:
* # python code
* import decimal
* dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
* # Tuple values_of_x0 contains 8191 values from 1 through 10 both included.
* # Values have precision of 30.
* # Number of lines printed = 33.
* values_of_x0 = tuple([ dD(v) for v in (
* '1', # base ** 0
* '1.00028118544621897278573806728', # base ** 1
* '1.00056244995769311093431302175', # base ** 2
* '1.00084379355665441349981435563', # base ** 3
* '1.00112521626534113085090592508', # base ** 4
* '1.00140671810599776642860462823', # base ** 5
* '1.00168829910087507850455334504', # base ** 6
* '1.00196995927223008193978827786', # base ** 7
* '1.00225169864232604994400083181', # base ** 8
* '1.00253351723343251583529417399', # base ** 9
* '1.00281541506782527480043461065', # base ** 10
* '1.00309739216778638565559792132', # base ** 11
* '1.00337944855560417260761078936', # base ** 12
* '1.00366158425357322701568746780', # base ** 13
* '1.00394379928399440915366181998', # base ** 14
* '9.96071693169670355246242166923', # base ** 8176
* '9.96351774033180356752203256087', # base ** 8177
* '9.96631933651352941713150174299', # base ** 8178
* '9.96912172046332775069436351828', # base ** 8179
* '9.97192489240270748518907841861', # base ** 8180
* '9.97472885255323982267776904570', # base ** 8181
* '9.97753360113655826781987911337', # base ** 8182
* '9.98033913837435864539075707594', # base ** 8183
* '9.98314546448839911780516572726', # base ** 8184
* '9.98595257970050020264571915569', # base ** 8185
* '9.98876048423254479019624844046', # base ** 8186
* '9.99156917830647816098009747521', # base ** 8187
* '9.99437866214430800330335030510', # base ** 8188
* '9.99718893596810443080299136420', # base ** 8189
* '10.0000000000000000000000000000', # base ** 8190

## Dictionary dict4

* # python code
* dict4 = dict
* for p in range (len(values_of_x0)-2,0,-1) :
* x0 = values_of_x0[p]
* sign,digits,exp = x0.as_tuple
* dD1 = dD((0,digits[:4],0))
* if dD1 in dict4 :
* del(dict4[dD1])
* break
* dict4[dD1] = p
* keys4 = sorted([ v for v in dict4 ])
* start = int(keys4[0]) ; end = 10000
* for key in range (start, end) :
* if key in dict4 : pass
* else :
* v = dict4[key-1]
* dict4[key] = v
* def print_dict4 (print_all=0) :
* This function prints contents of dictionary dict4.
* Default is to print reduced listing.
* keys4 = sorted([ key for key in dict4 ])
* lines = [ ]
* for key in keys4 :
* v = dict4[key]
* lines += [ ' (,), # dict4[] =. values_of_x0[] ='.format(key,v, key, v, v, values_of_x0[v]) ]
* new_line = '''
* '''[-1:]
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'dict( )'.format(str2)
* dict41 = eval(str3)
* (dict41 == dict4) or ([4])
* if print_all : pass
* else :
* lines[15:len(keys4)-15] = ( [ ' '+('#'*22) ] * 3 )
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'dict( )'.format(str2)
* if 1 :
* # An example:
* x = dD('9.99456789') ; key = 9994 ; value = dict4[key]
* x0 = values_of_x0[value]
* str10 = '''
* # Let x =
* # This value of x uses key. Value associated with this key is.
* # Value is an index into tuple values_of_x0.
* # x0 = values_of_x0[] =.
* # x - x0 -
* # In this case, ratio = ------ = -------------------------------------------- =
* # x0'''.lstrip
* str11 = str10.format(
* x,
* key, value,
* value,
* value,x0,
* x,x0,
* (x-x0)/x0,
* x0,
* # End of an example.
* if 1 :
* str20 = '''
* # Dictionary dict4 contains keys from through both included.
* # Number of lines printed =.'''.lstrip
* str21 = str20.format(
* len(keys4), keys4[0], keys4[-1],
* len(lines),
* print_str = '''
* # python code
* import decimal
* dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
* dict4 =
* print (print_str.format(
* str21,
* str3,
* str11,
* if (len(lines) > 35) : print (str21)
* print_dict4
* Dictionary dict4:
* # python code
* import decimal
* dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
* # Dictionary dict4 contains 6494 keys from 3506 through 9999 both included.
* # Number of lines printed = 33.
* dict4 = dict( (
* (3506, 4463), # dict4[3506] = 4463. values_of_x0[4463] = 3.50697641293426289558998224666
* (3507, 4464), # dict4[3507] = 4464. values_of_x0[4464] = 3.50796252366181322886561787736
* (3508, 4465), # dict4[3508] = 4465. values_of_x0[4465] = 3.50894891166934850969761612419
* (3509, 4466), # dict4[3509] = 4466. values_of_x0[4466] = 3.50993557703483583438104568033
* (3510, 4467), # dict4[3510] = 4467. values_of_x0[4467] = 3.51092251983626422242373736544
* (3511, 4468), # dict4[3511] = 4468. values_of_x0[4468] = 3.51190974015164462271077248878
* (3512, 4469), # dict4[3512] = 4469. values_of_x0[4469] = 3.51289723805900991967070457669
* (3513, 4470), # dict4[3513] = 4470. values_of_x0[4470] = 3.51388501363641493944351495183
* (3514, 4471), # dict4[3514] = 4471. values_of_x0[4471] = 3.51487306696193645605030265189
* (3515, 4472), # dict4[3515] = 4472. values_of_x0[4472] = 3.51586139811367319756470917515
* (3516, 4473), # dict4[3516] = 4473. values_of_x0[4473] = 3.51685000716974585228607854104
* (3517, 4474), # dict4[3517] = 4474. values_of_x0[4474] = 3.51783889420829707491435315329
* (3518, 4475), # dict4[3518] = 4475. values_of_x0[4475] = 3.51882805930749149272670595406
* (3519, 4476), # dict4[3519] = 4476. values_of_x0[4476] = 3.51981750254551571175590935706
* (3520, 4477), # dict4[3520] = 4477. values_of_x0[4477] = 3.52080722400057832297044144817
* (9985, 8185), # dict4[9985] = 8185. values_of_x0[8185] = 9.98595257970050020264571915569
* (9986, 8185), # dict4[9986] = 8185. values_of_x0[8185] = 9.98595257970050020264571915569
* (9987, 8185), # dict4[9987] = 8185. values_of_x0[8185] = 9.98595257970050020264571915569
* (9988, 8186), # dict4[9988] = 8186. values_of_x0[8186] = 9.98876048423254479019624844046
* (9989, 8186), # dict4[9989] = 8186. values_of_x0[8186] = 9.98876048423254479019624844046
* (9990, 8186), # dict4[9990] = 8186. values_of_x0[8186] = 9.98876048423254479019624844046
* (9991, 8187), # dict4[9991] = 8187. values_of_x0[8187] = 9.99156917830647816098009747521
* (9992, 8187), # dict4[9992] = 8187. values_of_x0[8187] = 9.99156917830647816098009747521
* (9993, 8187), # dict4[9993] = 8187. values_of_x0[8187] = 9.99156917830647816098009747521
* (9994, 8188), # dict4[9994] = 8188. values_of_x0[8188] = 9.99437866214430800330335030510
* (9995, 8188), # dict4[9995] = 8188. values_of_x0[8188] = 9.99437866214430800330335030510
* (9996, 8188), # dict4[9996] = 8188. values_of_x0[8188] = 9.99437866214430800330335030510
* (9997, 8189), # dict4[9997] = 8189. values_of_x0[8189] = 9.99718893596810443080299136420
* (9998, 8189), # dict4[9998] = 8189. values_of_x0[8189] = 9.99718893596810443080299136420
* (9999, 8189), # dict4[9999] = 8189. values_of_x0[8189] = 9.99718893596810443080299136420
* # Let x = 9.99456789
* # This value of x uses key 9994. Value associated with this key is 8188.
* # Value 8188 is an index into tuple values_of_x0.
* # x0 = values_of_x0[8188] = 9.99437866214430800330335030510.
* # x - x0 9.99456789 - 9.99437866214430800330335030510
* # In this case, ratio = ------ = -------------------------------------------- = 0.0000189334286891425018292826392422
* # x0 9.99437866214430800330335030510

## Dictionary dict5

* # python code.
* dict5 = dict
* for p in range (4463,-1,-1) :
* x0 = values_of_x0[p]
* sign,digits,exp = x0.as_tuple
* dD1 = dD((0,(digits+(0,0,0,0))[:5],0))
* if dD1 in dict5 :
* del(dict5[dD1])
* break
* dict5[dD1] = p
* keys5 = sorted([ v for v in dict5 ])
* start = int(keys5[0]) ; end = keys5[-1]
* for key in range (start, 35070) :
* if key in dict5 : pass
* else :
* v = dict5[key-1]
* dict5[key] = v
* def print_dict5 (print_all=0) :
* This function prints contents of dictionary dict5.
* Default is to print reduced listing.
* keys5 = sorted([ key for key in dict5 ])
* lines = [ ]
* for key in keys5 :
* v = dict5[key]
* lines += [ ' (,), # dict5[] =. values_of_x0[] ='.format(key,v, key, v, v, values_of_x0[v]) ]
* new_line = '''
* '''[-1:]
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'dict( )'.format(str2)
* dict51 = eval(str3)
* (dict51 == dict5) or ([5])
* if print_all : pass
* else :
* lines[15:len(keys5)-15] = ( [ ' '+('#'*22) ] * 3 )
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'dict( )'.format(str2)
* if 1 :
* # An example:
* x = dD('3.50667891') ; key = 35066 ; value = dict5[key]
* x0 = values_of_x0[value]
* str10 = '''
* # Let x =
* # This value of x uses key. Value associated with this key is.
* # Value is an index into tuple values_of_x0.
* # x0 = values_of_x0[] =.
* # x - x0 -
* # In this case, ratio = ------ = -------------------------------------------- =
* # x0'''.lstrip
* str11 = str10.format(
* x,
* key, value,
* value,
* value,x0,
* x,x0,
* (x-x0)/x0,
* x0,
* # End of an example.
* if 1 :
* str20 = '''
* # Dictionary dict5 contains keys from through both included.
* # Number of lines printed =.'''.lstrip
* str21 = str20.format(
* len(keys5), keys5[0], keys5[-1],
* len(lines),
* print_str = '''
* # python code
* import decimal
* dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
* dict5 =
* print (print_str.format(
* str21,
* str3,
* str11,
* if (len(lines) > 35) : print (str21)
* print_dict5
* Dictionary dict5:
* # python code
* import decimal
* dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
* # Dictionary dict5 contains 25070 keys from 10000 through 35069 both included.
* # Number of lines printed = 33.
* dict5 = dict( (
* (10000, 0), # dict5[10000] = 0. values_of_x0[0] = 1
* (10001, 0), # dict5[10001] = 0. values_of_x0[0] = 1
* (10002, 1), # dict5[10002] = 1. values_of_x0[1] = 1.00028118544621897278573806728
* (10003, 1), # dict5[10003] = 1. values_of_x0[1] = 1.00028118544621897278573806728
* (10004, 1), # dict5[10004] = 1. values_of_x0[1] = 1.00028118544621897278573806728
* (10005, 2), # dict5[10005] = 2. values_of_x0[2] = 1.00056244995769311093431302175
* (10006, 2), # dict5[10006] = 2. values_of_x0[2] = 1.00056244995769311093431302175
* (10007, 2), # dict5[10007] = 2. values_of_x0[2] = 1.00056244995769311093431302175
* (10008, 3), # dict5[10008] = 3. values_of_x0[3] = 1.00084379355665441349981435563
* (10009, 3), # dict5[10009] = 3. values_of_x0[3] = 1.00084379355665441349981435563
* (10010, 3), # dict5[10010] = 3. values_of_x0[3] = 1.00084379355665441349981435563
* (10011, 4), # dict5[10011] = 4. values_of_x0[4] = 1.00112521626534113085090592508
* (10012, 4), # dict5[10012] = 4. values_of_x0[4] = 1.00112521626534113085090592508
* (10013, 4), # dict5[10013] = 4. values_of_x0[4] = 1.00112521626534113085090592508
* (10014, 5), # dict5[10014] = 5. values_of_x0[5] = 1.00140671810599776642860462823
* (35055, 4461), # dict5[35055] = 4461. values_of_x0[4461] = 3.50500502300735826561653416805
* (35056, 4461), # dict5[35056] = 4461. values_of_x0[4461] = 3.50500502300735826561653416805
* (35057, 4461), # dict5[35057] = 4461. values_of_x0[4461] = 3.50500502300735826561653416805
* (35058, 4461), # dict5[35058] = 4461. values_of_x0[4461] = 3.50500502300735826561653416805
* (35059, 4462), # dict5[35059] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
* (35060, 4462), # dict5[35060] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
* (35061, 4462), # dict5[35061] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
* (35062, 4462), # dict5[35062] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
* (35063, 4462), # dict5[35063] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
* (35064, 4462), # dict5[35064] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
* (35065, 4462), # dict5[35065] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
* (35066, 4462), # dict5[35066] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
* (35067, 4462), # dict5[35067] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
* (35068, 4462), # dict5[35068] = 4462. values_of_x0[4462] = 3.50599057940875233062564717952
* (35069, 4463), # dict5[35069] = 4463. values_of_x0[4463] = 3.50697641293426289558998224666
* # Let x = 3.50667891
* # This value of x uses key 35066. Value associated with this key is 4462.
* # Value 4462 is an index into tuple values_of_x0.
* # x0 = values_of_x0[4462] = 3.50599057940875233062564717952.
* # x - x0 3.50667891 - 3.50599057940875233062564717952
* # In this case, ratio = ------ = -------------------------------------------- = 0.000196329846203907638094539889319
* # x0 3.50599057940875233062564717952

## Decision Points

* # python code
* decision_points=
* for p in range (0, len(values_of_x0)-1) :
* a,b = values_of_x0[p], values_of_x0[p+1]
* # ab
* # ratio = ---------
* # (a + b)/2
* decision_point = 2*a*b/(a+b)
* decision_points += [ decision_point ]
* decision_points = tuple(decision_points)
* def print_decision_points(print_all=0) :
* This function prints contents of tuple decision_points.
* Default is to print reduced listing.
* lines =
* for p in range (0, len(decision_points)) :
* lines += [ " '', # Decision point for values_of_x0[],".format(decision_points[p], p, values_of_x0[p]) ]
* new_line = '''
* '''[-1:]
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'tuple([ dD(v) for v in ])'.format(str2)
* decision_points1 = eval(str3)
* (decision_points1 == decision_points) or ([3])
* if print_all : pass
* else :
* lines[15:len(values_of_x0)-16] = ( [ ' '+('#'*22) ] * 3 )
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'tuple([ dD(v) for v in ])'.format(str2)
* if 1 :
* # Check the decision points:
* list1 =
* for p in range (0, len(decision_points)) :
* x = decision_points[p]
* x0 = values_of_x0[p]
* list1 += [ (x-x0)/x0 ]
* x0 = values_of_x0[p+1]
* list1 += [ (x-x0)/x0 ]
* list2 = sorted(list1)
* str11 = '''
* # If x ==, initial x0 chosen is values_of_x0[8188].
* # Ratio (x-x0)/x0 for this value of x0 =
* # However, x >= decision_points[8188],
* # therefore x0 chosen is values_of_x0[8189].
* # Ratio (x-x0)/x0 for this value of x0 =
* # Minimum value of (x-x0)/x0 =
* # Maximum value of (x-x0)/x0 ='''.lstrip
* x = dD('9.996')
* str12 = str11.format(
* x,
* ( x - values_of_x0[8188] )/values_of_x0[8188],
* ( x - values_of_x0[8189] )/values_of_x0[8189],
* list2[0],
* list2[-1],
* if 2 :
* str20 = '''
* # Tuple decision_points contains values.
* # Values have precision of.
* # Number of lines printed =.'''.lstrip
* str21 = str20.format(
* len(decision_points),
* dgt.prec,
* len(lines),
* print_str = '''
* # python code
* import decimal
* dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
* decision_points =
* print (print_str.format(
* str21,
* str3,
* str12,
* if (len(lines) > 35) : print (str21)
* print_decision_points
* Tuple decision_points:
* # python code
* import decimal
* dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
* # Tuple decision_points contains 8190 values.
* # Values have precision of 30.
* # Number of lines printed = 33.
* decision_points = tuple([ dD(v) for v in (
* '1.00014057295957430428168296256', # Decision point for values_of_x0[0], 1
* '1.00042179793286364128979317200', # Decision point for values_of_x0[1], 1.00028118544621897278573806728
* '1.00070310198252258057883287150', # Decision point for values_of_x0[2], 1.00056244995769311093431302175
* '1.00098448513078624642079583976', # Decision point for values_of_x0[3], 1.00084379355665441349981435563
* '1.00126594739989601528101601040', # Decision point for values_of_x0[4], 1.00112521626534113085090592508
* '1.00154748881209951757619324607', # Decision point for values_of_x0[5], 1.00140671810599776642860462823
* '1.00182910938965063943291344401', # Decision point for values_of_x0[6], 1.00168829910087507850455334504
* '1.00211080915480952444666311171', # Decision point for values_of_x0[7], 1.00196995927223008193978827786
* '1.00239258812984257544133855191', # Decision point for values_of_x0[8], 1.00225169864232604994400083181
* '1.00267444633702245622924979608', # Decision point for values_of_x0[9], 1.00253351723343251583529417399
* '1.00295638379862809337161942522', # Decision point for values_of_x0[10], 1.00281541506782527480043461065
* '1.00323840053694467793957641743', # Decision point for values_of_x0[11], 1.00309739216778638565559792132
* '1.00352049657426366727564516130', # Decision point for values_of_x0[12], 1.00337944855560417260761078936
* '1.00380267193288278675572977430', # Decision point for values_of_x0[13], 1.00366158425357322701568746780
* '1.00408492663510603155159386566', # Decision point for values_of_x0[14], 1.00394379928399440915366181998
* '9.95931672423813306357100081673', # Decision point for values_of_x0[8175], 9.95791691038684497262024697178
* '9.96211713915527404135384252174', # Decision point for values_of_x0[8176], 9.96071693169670355246242166923
* '9.96491834150833309369022259996', # Decision point for values_of_x0[8177], 9.96351774033180356752203256087
* '9.96772033151872574057278088598', # Decision point for values_of_x0[8178], 9.96631933651352941713150174299
* '9.97052310940792976081594615060', # Decision point for values_of_x0[8179], 9.96912172046332775069436351828
* '9.97332667539748520956221068667', # Decision point for values_of_x0[8180], 9.97192489240270748518907841861
* '9.97613102970899443579332740474', # Decision point for values_of_x0[8181], 9.97472885255323982267776904570
* '9.97893617256412209984643082198', # Decision point for values_of_x0[8182], 9.97753360113655826781987911337
* '9.98174210418459519093508332990', # Decision point for values_of_x0[8183], 9.98033913837435864539075707594
* '9.98454882479220304467524812459', # Decision point for values_of_x0[8184], 9.98314546448839911780516572726
* '9.98735633460879736061619018673', # Decision point for values_of_x0[8185], 9.98595257970050020264571915569
* '9.99016463385629221977630669417', # Decision point for values_of_x0[8186], 9.98876048423254479019624844046
* '9.99297372275666410218388825624', # Decision point for values_of_x0[8187], 9.99156917830647816098009747521
* '9.99578360153195190442281235396', # Decision point for values_of_x0[8188], 9.99437866214430800330335030510
* '9.99859427040425695718317037442', # Decision point for values_of_x0[8189], 9.99718893596810443080299136420
* # If x == 9.996, initial x0 chosen is values_of_x0[8188].
* # Ratio (x-x0)/x0 for this value of x0 = 0.000162224977710033689939296541400
* # However, x >= decision_points[8188],
* # therefore x0 chosen is values_of_x0[8189].
* # Ratio (x-x0)/x0 for this value of x0 = -0.000118927027959514803376227947800
* # Minimum value of (x-x0)/x0 = -0.000140572959574304281682962568892
* # Maximum value of (x-x0)/x0 = 0.000140572959574304281682962568536

## values_of_ln_x0_

* # python code
* Precision = dgt.prec = 115 # Preparing for values containing 110 places of decimal numbers.
* Tolerance = Decimal('1e-' + str( Precision-3 ))
* ln_x_Global_Flag = 0
* def ln_x (x, x0, C) :
* Return ln(x) for x close to x0.
* ln_x_ = ln_x (x, x0, C)
* C is the constant of integration. Usually C = ln(x0).
* If ln_x_Global_Flag is non-zero, this function prints useful information.
* global ln_x_Global_Flag
* if ln_x_Global_Flag :
* thisName = 'ln_x (x, x0, C=0) :'
* print (thisName)
* print (' x =', x)
* print (' x0 =', x0)
* print (' C =', C)
* status = 1 ; limit = dgt.prec
* sum = progressiveValue = multiplier = (x - x0)/x0
* progressiveValue *= multiplier
* addendum = progressiveValue / 2
* sum -= addendum
* min,max = sorted((C,abs(progressiveValue)))
* limit_small = Tolerance * max
* if ln_x_Global_Flag :
* print (' multiplier =', multiplier)
* print (' limit =', limit)
* print
* print (' addendum =', addendum)
* print (' sum =', sum)
* for p in range (3, limit, 2) :
* progressiveValue *= multiplier
* addendum = progressiveValue / p
* sum += addendum
* progressiveValue *= multiplier
* addendum = progressiveValue / (p+1)
* sum -= addendum
* if ln_x_Global_Flag :
* print
* print (' addendum =', addendum)
* print (' sum =', sum)
* if (abs(addendum) < limit_small) :
* status = 0
* break
* if (status) :
* print ('ln_x:')
* print (' error: count expired, p =',p)
* return
* output = sum + C
* if ln_x_Global_Flag :
* print (' p =', p)
* print (' output =', output)
* return output
* values_of_ln_x0_ = [ Decimal(0) ]
* for p in range(1, len(values_of_x0),1) :
* # Size of list values_of_ln_x0_ increases with every pass through this loop.
* x = values_of_x0[p]
* x0 = values_of_x0[p-1]
* C = values_of_ln_x0_[p-1]
* ln = ln_x (x, x0, C)
* values_of_ln_x0_ += [ ln ]
* Precision = dgt.prec = 110
* Tolerance = Decimal('1e-' + str( Precision-3 ))
* dC = decimal.Context
* values_of_ln_x0_ = tuple([ dC(prec=Precision,rounding=decimal.ROUND_HALF_UP).create_decimal(v) for v in values_of_ln_x0_])
* def print_values_of_ln_x0_ (print_all=0) :
* This function prints contents of tuple values_of_ln_x0_.
* Default is to print reduced listing.
* lines =
* for p in range (0, len(values_of_ln_x0_)) :
* x = values_of_x0[p] ; logn_x_ = values_of_ln_x0_[p]
* (logn_x_ == x.ln) or ([17])
* lines += [ " '', # ln(x) for x = values_of_x0[] =.".format(logn_x_, p, x) ]
* new_line = '''
* '''[-1:]
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'tuple([ dD(v) for v in ])'.format(str2)
* values_of_ln_x0_1 = eval(str3)
* (values_of_ln_x0_1 == values_of_ln_x0_) or ([3])
* if print_all : pass
* else :
* lines[15:len(values_of_ln_x0_)-15] = ( [ ' '+('#'*22) ] * 3 )
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'tuple([ dD(v) for v in ])'.format(str2)
* if 1 :
* str20 = '''
* # Tuple values_of_ln_x0_ contains values.
* # Values have precision of.
* # Number of lines printed =.'''.lstrip
* str21 = str20.format(
* len(values_of_ln_x0_),
* dgt.prec,
* len(lines),
* print_str = '''
* # python code
* import decimal
* dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
* values_of_ln_x0_ =
* # All values match corresponding values calculated from python's method .ln.
* print (print_str.format(
* str21,
* str3,
* if (len(lines) > 35) : print (str21)
* print_values_of_ln_x0_
* Tuple values_of_ln_x0_:
* # python code
* import decimal
* dD = decimal.Decimal # Decimal object is like float with (almost) unlimited precision.
* # Tuple values_of_ln_x0_ contains 8191 values.
* # Values have precision of 110.
* # Number of lines printed = 33.
* values_of_ln_x0_ = tuple([ dD(v) for v in (
* '0', # ln(x) for x = values_of_x0[0] = 1.
* '0.00028114592100049397851257526958789318557823685315140509591146945610630681924483554634842715913155791553935763353', # ln(x) for x = values_of_x0[1] = 1.00028118544621897278573806728.
* '0.00056229184200098795702515053832076377529815817685091034900099838032371576474647395210890353807586706979025309841', # ln(x) for x = values_of_x0[2] = 1.00056244995769311093431302175.
* '0.00084343776300148193553772580559921306036271356639510059614615649527672916175199470705511306484712247456495136785', # ln(x) for x = values_of_x0[3] = 1.00084379355665441349981435563.
* '0.0011245836840019759140503010760592633243233373666630274912240526872189379027309580785200788485985603865985895688', # ln(x) for x = values_of_x0[4] = 1.00112521626534113085090592508.
* '0.0014057296050024698925628763418989224560236605191226558916675419561961081724994394224778473772989675950066240433', # ln(x) for x = values_of_x0[5] = 1.00140671810599776642860462823.
* '0.0016868755260029638710754516132125138240706054425728603309033120607959071382243819085331207823151560952524126555', # ln(x) for x = values_of_x0[6] = 1.00168829910087507850455334504.
* '0.0019680214470034578495880268872333649791972073653457158404410113008355450069732509641759673340415353071544323205', # ln(x) for x = values_of_x0[7] = 1.00196995927223008193978827786.
* '0.0022491673680039518281006021580778932979673021988265352275636839430354663150269526071071437607450560006442621246', # ln(x) for x = values_of_x0[8] = 1.00225169864232604994400083181.
* '0.0025303132890044458066131774196426391914772962305290824563142073882759834795702976123051014571348552310189175327', # ln(x) for x = values_of_x0[9] = 1.00253351723343251583529417399.
* '0.0028114592100049397851257526950841486394900305702168719174622980317602779030546368107920305020685647504214850020', # ln(x) for x = values_of_x0[10] = 1.00281541506782527480043461065.
* '0.0030926051310054337636383279576467230904015964551099672846920959011633015793790942523210207705866150801840718264', # ln(x) for x = values_of_x0[11] = 1.00309739216778638565559792132.
* '0.0033737510520059277421509032273666711656003353833161378685286907465997110550477881401427392163316523076635049655', # ln(x) for x = values_of_x0[12] = 1.00337944855560417260761078936.
* '0.0036548969730064217206634785007033901080823462730164946725801425392961788141621195388687950276169252526202813317', # ln(x) for x = values_of_x0[13] = 1.00366158425357322701568746780.
* '0.0039360428940069156991760537694132046752291888691499866508887763250737472392296047255077029503512257389803956675', # ln(x) for x = values_of_x0[14] = 1.00394379928399440915366181998.
* '2.2986490501000387683188154009156080387928397456918301259039789087944336216064685316414378199045428924326799354', # ln(x) for x = values_of_x0[8176] = 9.96071693169670355246242166923.
* '2.2989301960210392622973279761851826912850498262636764478593466003783569959365230606881295712717359785963112572', # ln(x) for x = values_of_x0[8177] = 9.96351774033180356752203256087.
* '2.2992113419420397562758405514538127154368379767714938128234341386785761356659428151509538766438052956987514456', # ln(x) for x = values_of_x0[8178] = 9.96631933651352941713150174299.
* '2.2994924878630402502543531267234795446120177448761439909215905629390155692208202036169724706742616903146745976', # ln(x) for x = values_of_x0[8179] = 9.96912172046332775069436351828.
* '2.2997736337840407442328657019924935957228985155357974105355104395265542601189816673651603550100698554337262110', # ln(x) for x = values_of_x0[8180] = 9.97192489240270748518907841861.
* '2.3000547797050412382113782772620075034105144024446410997113100105048869297857113614199956326399453812234259798', # ln(x) for x = values_of_x0[8181] = 9.97472885255323982267776904570.
* '2.3003359256260417321898908525304842706062415677704389700357254056059757438662458766613085787045702337983018714', # ln(x) for x = values_of_x0[8182] = 9.97753360113655826781987911337.
* '2.3006170715470422261684034277999240939447294182933534442617229885402608324814372163790494646489096111864238087', # ln(x) for x = values_of_x0[8183] = 9.98033913837435864539075707594.
* '2.3008982174680427201469160030695937857213769448822598470814633753680217668218642029270879455834911773531417718', # ln(x) for x = values_of_x0[8184] = 9.98314546448839911780516572726.
* '2.3011793633890432141254285783381842630937332590762005140545211954364744522739221910731492477352251364727532941', # ln(x) for x = values_of_x0[8185] = 9.98595257970050020264571915569.
* '2.3014605093100437081039411536072957843624648926396223086157833390784873434028789437068207364140323800128952846', # ln(x) for x = values_of_x0[8186] = 9.98876048423254479019624844046.
* '2.3017416552310442020824537288772066438368127181180454803304105302438376670970053383184297088473645195882839920', # ln(x) for x = values_of_x0[8187] = 9.99156917830647816098009747521.
* '2.3020228011520446960609663041459434200397763370975986092768268975848700083257305096479892286265624964942134938', # ln(x) for x = values_of_x0[8188] = 9.99437866214430800330335030510.
* '2.3023039470730451900394788794156639713397781053105254292750160375440587140647147489289589658979929574060205262', # ln(x) for x = values_of_x0[8189] = 9.99718893596810443080299136420.
* '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840', # ln(x) for x = values_of_x0[8190] = 10.0000000000000000000000000000.
* # All values match corresponding values calculated from python's method .ln.

## nat_logs_of_10_integers

* This data structure is included because this author believes that it would be handy
* to have natural logarithms of the small integers readily available.
* def simple_ln (x, flag = 0) :
* This function calculates ln(x) using the slow, simple method.
* Result is accurate to precision as in dgt.prec.
* If flag, this function also calculates x.ln for internal checking.
* x_ = dD(str(x))
* old_precision = dgt.prec
* pre = precision = dgt.prec = int((dgt.prec + 5)*10/3)
* lnx = ([ root for root in [x_] for p in range (1,pre+1) for root in [root.sqrt] ][-1] - 1) * (1 << pre)
* dgt.prec = old_precision
* lnx += 0
* if flag : (x_.ln == lnx) or ([13])
* return lnx
* # python code
* nat_logs_of_10_integers = [0,dD(0)]
* for x in range(2,11) :
* nlog = simple_ln (x)
* nat_logs_of_10_integers += [ nlog ]
* nat_logs_of_10_integers = tuple(nat_logs_of_10_integers)
* def print_nat_logs_of_10_integers :
* This function prints contents of tuple nat_logs_of_10_integers.
* lines =
* lines += [ " '0', # Filler." ]
* for x in range (1, len(nat_logs_of_10_integers)) :
* logn_x_ = nat_logs_of_10_integers[x]
* ( logn_x_ == dD(x).ln ) or ([30])
* lines += [ " '', # ln() = nat_logs_of_10_integers[]".format(logn_x_, x, x) ]
* new_line = '''
* '''[-1:]
* str1 = new_line.join(lines)
* str2 = '()'.format(new_line,str1,new_line)
* str3 = 'tuple([ dD(v) for v in ])'.format(str2)
* nat_logs_of_10_integers1 = eval(str3)
* (nat_logs_of_10_integers1 == nat_logs_of_10_integers) or ([3])
* print_str = '''
* import decimal
* dD = decimal.Decimal
* # Tuple nat_logs_of_10_integers contains values:
* # 1 filler and ln(x) for x in (1,2,3,4,5,6,7,8,9,10).
* # Values have precision of.
* # Number of lines printed =.
* # All values match corresponding values calculated from python's method .ln.
* nat_logs_of_10_integers =
* print (print_str.format(
* len(nat_logs_of_10_integers),
* dgt.prec,
* len(lines),
* str3,
* print_nat_logs_of_10_integers
* Tuple nat_logs_of_10_integers:
* import decimal
* dD = decimal.Decimal
* # Tuple nat_logs_of_10_integers contains 11 values:
* # 1 filler and ln(x) for x in (1,2,3,4,5,6,7,8,9,10).
* # Values have precision of 110.
* # Number of lines printed = 11.
* # All values match corresponding values calculated from python's method .ln.
* nat_logs_of_10_integers = tuple([ dD(v) for v in (
* '0', # Filler.
* '0', # ln(1) = nat_logs_of_10_integers[1]
* '0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102', # ln(2) = nat_logs_of_10_integers[2]
* '1.0986122886681096913952452369225257046474905578227494517346943336374942932186089668736157548137320887879700291', # ln(3) = nat_logs_of_10_integers[3]
* '1.3862943611198906188344642429163531361510002687205105082413600189867872439393894312117266539928373750840029620', # ln(4) = nat_logs_of_10_integers[4]
* '1.6094379124341003746007593332261876395256013542685177219126478914741789877076577646301338780931796107999663030', # ln(5) = nat_logs_of_10_integers[5]
* '1.7917594692280550008124773583807022727229906921830047058553743431308879151883036824794790818101507763299715101', # ln(6) = nat_logs_of_10_integers[6]
* '1.9459101490553133051053527434431797296370847295818611884593901499375798627520692677876584985878715269930616942', # ln(7) = nat_logs_of_10_integers[7]
* '2.0794415416798359282516963643745297042265004030807657623620400284801808659090841468175899809892560626260044431', # ln(8) = nat_logs_of_10_integers[8]
* '2.1972245773362193827904904738450514092949811156454989034693886672749885864372179337472315096274641775759400581', # ln(9) = nat_logs_of_10_integers[9]
* '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840', # ln(10) = nat_logs_of_10_integers[10]

# Accessing the data structures
## Function natural_log

* # python code.
* natural_log_Global_Flag = 0
* def natural_log (x) :
* This function calculates x0 and ln(x0), and invokes function ln_x.
* ln_x_ = natural_log (x)
* x is limited to (10 >= x >= 1).
* (10 >= x >= 1) or ([89])
* if x == 1 : return dD(0)
* if x == 10 : return values_of_ln_x0_[-1]
* while 1 :
* This code is written for speed.
* If x == 5.67 key generated is 5670. p = dict4[5670].
* If x == 2.3456789 key generated is 23456. p = dict5[23456].
* Check values_of_x0[p], values_of_x0[p-1]. Return appropriate value of p.
* Result must be found with max of 2 tests. Anything else means internal error.
* if x >= dD('3.506') :
* sign,digits,exp = x.as_tuple
* p = dict4[dD(( 0,(digits+(0,0,0))[:4],0 ))]
* if x >= values_of_x0[p] : break
* p -= 1
* if x >= values_of_x0[p] : break
* ([13])
* sign,digits,exp = x.as_tuple
* p = dict5[dD(( 0,(digits+(0,0,0,0))[:5],0 ))]
* if x >= values_of_x0[p] : break
* p -= 1
* if x >= values_of_x0[p] : break
* ([14])
* if x >= decision_points[p] : p += 1
* x0 = values_of_x0[p]
* C = values_of_ln_x0_[p]
* if natural_log_Global_Flag :
* print ('natural_log (x) :')
* print (' x =', x)
* print (' x0 =', x0)
* print (' C =', C)
* print (' multiplier =', (x-x0)/x0)
* if x == x0 : return C
* ln_x_ = ln_x (x, x0, C)
* if natural_log_Global_Flag :
* print (' ln(x) =', ln_x_)
* return ln_x_

## Testing Function natural_log
### For accuracy

* This test compares natural_log(x) with python's calculation, x.ln, using almost 9,000,000 values of x from 1 to 10.
* # python code.
* count = count1 = count2 = count3 = 0
* for X in range(100_000_001, 1_000_000_000,101) : # 8910892
* count += 1
* x = dD(X)/100_000_000
* lnx = natural_log (x) ; lnx_ = x.ln
* # test 1
* if lnx == lnx_ :
* # Both values are equal.
* count1 += 1 ; continue
* # test 2
* str1 = str(lnx).upper ; str2 = str(lnx_)
* if 'E' not in str1 :
* if str1[:-1] == str2[:-1] :
* # Both values are equal except for least significant digit.
* count2 += 1 ; continue
* # test 3
* v1 = dC(prec=dgt.prec-1,rounding=decimal.ROUND_HALF_UP).create_decimal(lnx)
* v2 = dC(prec=dgt.prec-1,rounding=decimal.ROUND_HALF_UP).create_decimal(lnx_)
* if v1 == v2 :
* # With precision reduced by 1, both values are equal.
* count3 += 1 ; continue
* ([17])
* values = count1,count2,count3,count
* len1 = sorted([ len(str(v)) for v in values ])[-1]
* a,b,c,d = [ ((' '*len1)+str(v))[-len1:] for v in values ]
* str20 = 'count == count1+count2+count3'
* str1 = '''
* count1 = Both values equal.
* count2 = Both values equal except for least significant digit.
* count3 = Both values equal with precision reduced by 1.
* count =
*:'''.format(a,b,c,d,str20, eval(str20))
* print (str1)
* count1 = 6687475 Both values equal.
* count2 = 2001406 Both values equal except for least significant digit.
* count3 = 222011 Both values equal with precision reduced by 1.
* count = 8910892
* count == count1+count2+count3: True
* Considering that function natural_log(x) was written for speed, this author finds these results quite satisfactory.

### For speed

* # python code.
* count = 0
* for X in range(100_000_001, 1_000_000_000, 1001) : # 899101
* count += 1
* x = dD(X)/100_000_000
* if 1 : natural_log (x)
* else : x.ln
* sx = 'count' ; print (sx, '=', eval(sx))
* python3 ./wiki_005.py > j1q 2> j2q 16.85s user 0.02s system 99% cpu 16.878 total
* count = 899101
* # python code.
* count = 0
* for X in range(100_000_001, 1_000_000_000, 1001) : # 899101
* count += 1
* x = dD(X)/100_000_000
* if 0 : natural_log (x)
* else : x.ln
* sx = 'count' ; print (sx, '=', eval(sx))
* python3 ./wiki_005.py > j1q 2> j2q 77.01s user 0.10s system 99% cpu 1:17.11 total
* count = 899101
* This test indicates that this implementation of ln(x) is four times faster than python's method x.ln.

# Putting all together

* # python code.
* def make_Decimal_number_clean(number) :
* Number such as 0.9999999999999999999999999999999999999999
* is returned as 1.
* Number 0.9999999999999999999999999999999999999999 is described as "raw."
* Number 1 is described as "clean."
* Number 1E-103 becomes 0.
* if abs(number) < Tolerance : return dD(0)
* dgt.prec -= 2
* dD1 = (+number).normalize
* dgt.prec += 2
* sign,digits,exponent = dD1.as_tuple
* if len(digits) < (dgt.prec - (dgt.prec >> 2)) : return dD1
* return number
* # python code.
* def sum_zero(values) :
* This function calculates sum of all values.
* However, if sum is close to zero and Tolerance permits, sum
* is returned as zero.
* Useful for testing 2 numbers for being "almost" equal.
* For example:
* let v1 be 1.9999999999999999999999999999999999999
* let v2 be 2
* sum_zero((v1,-v2)) returns 0.
* sump = sumn = 0
* for v in values :
* if v > 0 : sump += v
* else : sumn -= v
* sum = sump - sumn
* if abs(sum) < Tolerance : return dD(0)
* min,max = sorted((sump,sumn))
* if abs(sum) <= Tolerance*min : return dD(0)
* return sum
* # python code.
* import sys
* def natural_logarithm (number, flag=0) :
* ln_x_ = natural_logarithm (x [,flag])
* ln(number) = ln(standard_number * (10 ** exponent))
* = ln(standard_number) + ln(10 ** exponent))
* = ln(standard_number) + exponent*ln(10)
* For example:
* ln(12345.6789)
* = ln(1.23456789 * 10**4)
* = ln(1.23456789) + 4(ln(10))
* Value 1.23456789 is called standard_number and 4 is exponent.
* print_ = flag & 1
* print_all = flag & 2
* check = flag & 4
* do_not_clean = flag & 8
* thisName = 'natural_logarithm (number) :'
* error = ''
* try :
* number = dD(str(number)).normalize
* print_ = flag & 1
* except : v1,v2,v3 = error = sys.exc_info
* if error :
* print
* print (thisName)
* print (' Input not recognized.')
* print (' ', v1)
* print (' ', v2)
* print (' ', v3)
* print
* return
* print_all = flag & 2
* check = flag & 4
* if print_all : print_ = 1
* if print_ : check = 4
* do_not_clean = flag & 8
* if number <= 0 :
* print
* print (thisName)
* print (' Input number must be > 0.')
* print
* return
* if print_ :
* print
* print(thisName)
* print(' Input number =', number)
* if print_all :
* print(' flag =', bin(flag))
* if 10 >= number >= 1 :
* ln_x_ = natural_log (number)
* else :
* sign, digits, exponent = number.as_tuple
* if print_all :
* print(thisName)
* print(' digits =', digits)
* print(' exponent =', exponent)
* if (len(digits) == 1) :
* standard_number = dD(digits[0])
* else :
* digits = list(digits)
* exponent += (len(digits)-1)
* digits[1:1] = '.'
* standard_number = dD( ''.join([str(v) for v in digits]) )
* if standard_number == 1 : standard_log = 0
* else : standard_log = natural_log (standard_number)
* ln_x_ = standard_log + exponent * nat_logs_of_10_integers[10]
* if print_all :
* print(thisName)
* print(' standard_number =', standard_number)
* print(' ln of standard_number =', standard_log)
* if check:
* # Some internal checking.
* b = number ; lnb = ln_x_ ; count = 0
* if 1 :
* # Two values in each of the following tuples should be equal.
* b__2 = ( natural_logarithm(b**2), 2*lnb )
* b_2 = ( natural_logarithm(b*2), (lnb + nat_logs_of_10_integers[2]) )
* b_5 = ( natural_logarithm(b/5), (lnb - nat_logs_of_10_integers[5]) )
* b_r = ( natural_logarithm(1/b), -lnb )
* for str1 in 'b__2 b_2 b_5 b_r'.split :
* v1,v2 = eval(str1)
* sum = sum_zero((v1,-v2))
* if sum :
* count += 1
* if not print_ :
* print_ = 1 ; print
* print (thisName)
* if count == 1:
* print (' number =', b)
* print (' ln_x_ =', ln_x_)
* print (' precision =', dgt.prec)
* print (' Tolerance =', Tolerance)
* print (' Test failed.'.format(str1))
* print (' v1 =', v1)
* print (' v2 =', v2)
* print (' sum =', sum)
* if count :
* print (' Number of errors detected =', count)
* print ; return
* if do_not_clean : pass
* else : ln_x_ = make_Decimal_number_clean(ln_x_)
* if print_ :
* print(thisName)
* if int(ln_x_) == ln_x_ : print(' Output =', int(ln_x_))
* else : print(' Output =', ln_x_ )
* print
* return ln_x_