shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Calculo em Centesimos


From: Arkanon
Subject: Re: [shell-script] Calculo em Centesimos
Date: Fri, 9 Dec 2011 00:17:59 -0200

Em 8 de dezembro de 2011 13:12, williamalves1975br escreveu:

> Alguém conhece uma forma simples, se é que existe, para realizar o calculo
> da diferença entre os tempos abaixo?
>
> 14:59:53,391 14:59:53,419
> 14:59:54,845 14:59:55,866
> 14:59:55,902 15:01:56,918
>
> O Resultado deveria ter o mesmo formato.
>
> Nesse momento estou realizando a conversão para centesimos e depois vou
> precisar converter novamente.
>
Oi.

Ficou meio extensa a resposta, mas a ideia em si é curta :-p
É uma abordagem mais matemática desse assunto.

O formato "*d H:M:S.m*" (dia, hora, minuto, segundo e milésimo) pode ser
encarado como um número deveras complicado :-p Ele é escrito
simultaneamente em 3 bases numéricas: dia e milésimo na base decimal, hora
na base 24 e minuto e segundo na sexagesimal (60).

Não vamos pensar no dia e no milésimo, num primeiro momento. E vamos
assumir que não teremos uma quantidade de horas que ultrapasse 60.

Então o número H:M:S é um número na base sexagesimal com 3 dígitos. Ao
invés de pensar em símbolos para dígitos com valor decimal superior a 9,
pensemos em seu próprio valor decimal.

Assim, 12:37:30 é composto pelos dígitos 12, 37 e 30. Literalmente.

Convertemos o número acima para a base decimal como convertemos qualquer
número em qualquer base para a decimal. Nesse caso, a base 60:

12:37:30[60] = 12*60*60 + 37*60 + 30 = 45450[10]

Aí, se queremos a diferença entre 2 números sexagesimais, fazemos o que
todo mundo faz. Convertemos para segundos (decimal), subtraímos e,
eventualmente, reconvertemos para a base sexagesimal.

Então, para que serve tudo isso que eu disse?

Para, uma vez encarando dessa forma as "strings" de hora, minuto e segundo,
usarmos as ferramentas de manipulação de bases numéricas nativas do bash e
presentes no bc para simplificar o trabalho.

No bash podemos trabalhar de forma transparente com uma vasta gama de bases
numéricas. Basta usar o número numa determinada base na forma *
b#numeronabase*. Ele assume os dígitos *0..9* para bases até a decimal e *
a..zA..Z* para bases superiores (até 64).

Então, o primeiro passo é definir a sequência de dígitos:

*C=({0..9} {a..z} {A..Z})*

Depois, lemos as duas strings de hora (*$1 e $2*), passando-as para arrays
após definir o ":" como separador de campo:

*IFS=: H1=($1) H2=($2)
*
Montamos os números sexagesimais, pegando os dígitos correspondentes em $C:

*for d in ${H1[*]}; do S1=$S1${C[$d]}; done
for d in ${H2[*]}; do S2=$S2${C[$d]}; done*

Pode muito bem haver uma forma melhor de fazer essa junção, sem usar loops.
Não me preocupei com isso agora.

Convertemos os números sexagesimais para decimal:

*D1=$[60#$S1]
D2=$[60#$S2]*

E, usando o bc, passamos a diferença entre eles de decimal para sexagesimal:

*bc <<< "obase=60;$D2-$D1"*

Como o bc não representa bases numéricas superiores a 16 com dígitos
especiais, mas os mantém com seu valor decimal, teremos o resultado já no
formato "*H M S*", precisando apenas trocar o espaço entre eles por ":"

Ex:

*12:37:30 -> cBu -> 45450
14:54:33 -> eSx -> 53673

53673 - 45450 = 8223 -> 02 17 03
*
É isso.
O método acima não resolve todo o problema, mas talvez ajude de alguma
forma.

[]'s  numéricos

-- 
(o_  @arkanon <http://twitter.com/arkanon>  (Twitter)     __o
//\   address@hidden   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------


[As partes desta mensagem que não continham texto foram removidas]



reply via email to

[Prev in Thread] Current Thread [Next in Thread]