16-08-2015, 02:37
en base a una consulta por ahí de cómo calcular logaritmos a mano, me puse a investigar un poco y se me ocurrió hacer un pequeño algoritmo que calcule el logaritmo de un número, usando mi lenguaje predilecto.
si se animan pueden testearlo o poner algoritmos en otros lenguajes.
si se animan pueden testearlo o poner algoritmos en otros lenguajes.
| funcCaract funcMant logaritmo logaritmoNeperiano logaritmoNatural precision |
precision := 3.
funcCaract := [:b :a :c :f | | cc |
cc := c.
(a < b)
ifTrue: [
(a < 1)
ifTrue: [f valueWithArguments: (Array with: b with: (a raisedTo: -1) with: c with: f)]
ifFalse: [Array with: cc with: a]]
ifFalse: [cc := f valueWithArguments: (Array with: b with: (a/b) with: c+1 with: f)]].
funcMant := [:b :r :m :p :c :f |
(p > 0) ifTrue: [
(r < b)
ifTrue: [m at: p put: c.
f valueWithArguments: ((OrderedCollection new) add: b; add: (r raisedTo: 10); add: m; add: (p-1); add: 0; add: f; yourself) asArray]
ifFalse: [f valueWithArguments: ((OrderedCollection new) add: b; add: (r/b); add: m; add: p; add: c+1; add: f; yourself) asArray]].
m].
logaritmo := [:base :argumento | | caracteristica mantisaCalc mantisa result |
caracteristica := 0.
mantisaCalc := 0.
mantisa := (Array new: precision+2) atAllPut: 0; yourself.
(argumento <= 0) ifTrue: [Error signal: 'el argumento debe ser positivo'].
(argumento = 1)
ifFalse: [(argumento = base)
ifTrue: [caracteristica := 1]
ifFalse: [result := funcCaract valueWithArguments: (Array with: base with: argumento with: 0 with: funcCaract).
caracteristica := result at: 1.
result := funcMant valueWithArguments: ((OrderedCollection new) add: base; add: ((result at: 2) raisedTo: 10); add: mantisa; add: precision+2; add: 0; add: funcMant; yourself) asArray]].
mantisa reverse doWithIndex: [:dec :i | mantisaCalc := mantisaCalc + (dec / (10 raisedTo: i))].
(((caracteristica + mantisaCalc) roundTo: (10 raisedTo: precision negated)) * ((argumento < 1) ifTrue: [-1] ifFalse: [1])) asFloat ].
logaritmoNeperiano := [:argumento | logaritmo value: Float e value: argumento ].
logaritmoNatural := [:argumento | logaritmo value: 10 value: argumento ].
"-- pruebas --"
Transcript cr; show: 'log 30 = '; show: (logaritmo value: 10 value: 30) printString.
Transcript cr; show: 'log 5 = '; show: (logaritmoNatural value: 5) printString.
Transcript cr; show: 'log 10 = '; show: (logaritmoNatural value: 10) printString.
Transcript cr; show: 'ln e = '; show: (logaritmoNeperiano value: Float e) printString.