segunda-feira, outubro 09, 2006

Raiz Quadrada (Square Root) para Bash

A maioria está acostumada com extração de raiz via método de Newton.
Este script fornece raízes inteiras por um método que talvez cause estranheza por um possível desuso. Você consegue compreender o script? O método é fácil, o problema são os bugs gerados pelo modo como o bash lida com os números. Daí as rotinas adicionais.


#!/bin/bash 

verif (){
    str1="$1"
    [[ -z "$str1" ]] && {
        echo "Use $0 <numero>";
        echo "<numero> entre 0 e 9223372036854775807.";
        echo "Caso ultrapasse, havera erro de calculo.";
        exit 1;
    }

    str2=${str1//[0123456789]/}
    [[ -n "$str2" ]] && {
        echo "Use somente digitos de 0 a 9." 
        exit 1;
    }

}

cortazero(){
    a1=$1;
    while [ "$a1" != "$b1" ]; do
        b1=$a1;
        a1=${a1##0};
    done;
    echo $a1;
}

sqrt(){
    tmp1=$1;
    [[ $((${#tmp1}%2)) -eq 1 ]] && tmp1='0'$tmp1;
    j=0;
    rq='0';
    rt='';

    while [ -n "${tmp1:$j:2}" ]; do
        rt=$rt${tmp1:$j:2};
        rt=`cortazero $rt`;
        [[ -z "$rt" ]] && rt='0';
        rq=`cortazero $rq`;
        [[ -z "$rq" ]] && rq='0';    
        for ((i=1;i<=10;i++));do
            [[ $rt -lt $(( (`cortazero $((2*$rq))`$i) *$i)) ]] && { 
                rt=$((rt-(`cortazero $((2*$rq))`$((i-1)))*$((i-1))));
                rq=$rq$((i-1));
                break;
            }
        done;
        let j+=2;
    done;
    rq=`cortazero $rq`;
    [[ -z "$rq" ]] && rq='0';
    echo $rq;
}

verif $1;
sqrt $1;