Sanallinen esitys kymmenkantaisen logaritmin laskemisesta:
- tässä skriptissä alkuoletus on että logaritmoitava on yli 1.
- kun puhutaan numerosta niin tarkoitetaan yhtä merkkiä: 1, 2, 3, 4, 5, 6, 7, 8, 9 tai 0.
- toiminta ei muutu mitenkään vaikka logaritmoitava olisin kokonaisluku ilman desimaaleja.
- aluksi logaritmi nollataan. Sitten logaritmin ensimmäiseksi numeroksi tulee "logaritmoitavan kokonaisosan numeroiden lukumäärä -1" ja perään tulee desimaaipiste.
Sitten logaritmiin lisätään numeroita yksi kerrallaan niin monta kertaa kuin tulokseen halutaan desimaaleja: logaritmin seuraava numeron selvittämiseksi lasketaan uusi logaritmoitava siirtämällä desimaalipiste vanhassa logaritmoitavassa ensimmäisen numeron perään ja korottamalla saatu luku potenssiin kymmenen. Logaritmin seuaava numero on "logaritmoitavan kokonaisosan numeroiden määrä -1". Uudesta logaritmoitavasta tulee vanha logaritmoitava. Palataan kohtaan: Sitten logaritmiin lisätään ...
Koodina tämä on:
#!/bin/bash
function kerro18 () {
tulosta=: # vaihtoehdot: tulosta=echo ja tulosta=:
[[ ${1//[^.]/} ]] && luku1=${1:0:17} || luku1=${1:0:17}".0"
[[ ${2//[^.]/} ]] && luku2=${2:0:17} || luku2=${2:0:17}".0"
[[ ${1//[^-]/} ]] && m1=-1 || m1=+1; [[ ${2//[^-]/} ]] && m2=-1 || m2=+1
luku1=${luku1//-/}; luku2=${luku2//-/}
desimaaliosa1=${luku1##*.};
desimaaliosa2=${luku2##*.}; desimaaleja=$((${#desimaaliosa1}+${#desimaaliosa2}))
luku1=000000000000000000${luku1//./}
luku2=000000000000000000${luku2//./}
a=${luku1: -18:9}; b=${luku1: -9}
c=${luku2: -18:9}; d=${luku2: -9}; $tulosta $a' '$b; $tulosta $c' '$d
luku1=00000000000000000000000000000000000000$((10#$b*10#$d))
luku2=00000000000000000000000000000000000000$((10#$d*10#$a))"000000000"
luku3=00000000000000000000000000000000000000$((10#$c*10#$b))"000000000"
luku4=00000000000000000000000000000000000000$((10#$a*10#$c))"000000000000000000"
luku1=${luku1: -36} ; $tulosta $luku1
luku2=${luku2: -36} ; $tulosta $luku2
luku3=${luku3: -36} ; $tulosta $luku3
luku4=${luku4: -36} ; $tulosta $luku4; $tulosta
luku11=${luku1:0:18} # tämänjälkeen 18->17
luku12=${luku1:18}; $tulosta a$luku11' 'b$luku12
luku21=${luku2:0:18}
luku22=${luku2:18}; $tulosta c$luku21' 'd$luku22
luku31=${luku3:0:18}
luku32=${luku3:18}; $tulosta a$luku31' 'b$luku32
luku41=${luku4:0:18}
luku42=${luku4:18}; $tulosta c$luku41' 'd$luku42;$tulosta
summa1=$((10#$luku12+10#$luku22+10#$luku32+10#$luku42)); $tulosta summa1:$summa1
summa1pituus=${#summa1}; ylivuoto=0; (( $summa1pituus >= 19 )) && ylivuoto=${summa1:0: -18} && summa1=${summa1:1}
summa1=000000000000000000$summa1; summa1=${summa1: -18} ;$tulosta ylivuoto:$ylivuoto' summa1:'$summa1
summa2=$((10#$luku11+10#$luku21+10#$luku31+10#$luku41+$ylivuoto)); $tulosta summa2:$summa2
summa2=$(($m1*$m2*10#$summa2))
(( ! summa2 )) && summa1=$(($m1*$m2*10#$summa1))
apu=$summa2$summa1; (( $desimaaleja )) && echo $((10#${apu:0: -$desimaaleja})).${apu: -$desimaaleja} || { echo $(( 10#$summa2 ))$summa1 ;} ;}
function getlog () { # varsinainen logaritmointi
apu=${1//,/.}
[[ ${apu//[^.]/} ]] && vanhalogaritmoitava=$1 || vanhalogaritmoitava=$1".0"
logaritmoitavankokonaisosa=${vanhalogaritmoitava%%.*}
logaritmi=0; logaritmi=$((${#logaritmoitavankokonaisosa}-1)).
# sitten logaritmiin lisätään numeroita yksi kerrallaan mikäli siinä ei vielä ole tarpeeksimontaa numeroa:
until (( ${#logaritmi} >= 19 )); do
apu=${vanhalogaritmoitava//./}; apu=${apu:0:1}.${apu:1}; # echo apu:$apu
uusilogaritmoitava=1.0;
for n in {1..10}; do uusilogaritmoitava=$(kerro18 $apu $uusilogaritmoitava); done
# echo uusilogaritmoitava:$uusilogaritmoitava; read
uudenlogaritmoitavankokonaisosa=${uusilogaritmoitava%%.*}
logaritmi=$logaritmi$((${#uudenlogaritmoitavankokonaisosa}-1))
vanhalogaritmoitava=$uusilogaritmoitava
done
echo luvun: $1 ' logaritmi on: '$logaritmi ;}
getlog 2.0000001234
Pitäisi tulla: luvun: 2.0000001234 logaritmi on: 0.301030022459
# tulee: 0.301030022459
Onhan tämä suunnattoman hidasta eikä tarkkuuskaan riitä kuin tusinaan numeroita. Mutta se on osoitus siitä mihin BASH kykenee 19-numeron kokonaislukukertolaskullaan ja ennenkaikkea osoitus ettei pidä sanoa: BASH ei osaa .....
Jokaisen skriptin kykyjen huonouteen pätee: kun joku esittää jotakin niin täysin varmasti jokutoinen pistää paremmaksi. Tai nykyäänhän se ei enää pidä paikkaansa koska virtuoosit ovat saaneet kaikki uskomaan että BASH on paitsi kelvoton niin myös kyvytön.