-
Notifications
You must be signed in to change notification settings - Fork 119
/
zzporcento.sh
157 lines (132 loc) · 5.01 KB
/
zzporcento.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# ----------------------------------------------------------------------------
# Calcula porcentagens.
# Se informado um número, mostra sua tabela de porcentagens.
# Se informados dois números, mostra a porcentagem relativa entre eles.
# Se informados um número e uma porcentagem, mostra o valor da porcentagem.
# Se informados um número e uma porcentagem com sinal, calcula o novo valor.
#
# Uso: zzporcento valor [valor|[+|-]porcentagem%]
# Ex.: zzporcento 500 # Tabela de porcentagens de 500
# zzporcento 500.0000 # Tabela para número fracionário (.)
# zzporcento 500,0000 # Tabela para número fracionário (,)
# zzporcento 5.000,00 # Tabela para valor monetário
# zzporcento 500 25 # Mostra a porcentagem de 25 para 500 (5%)
# zzporcento 500 1000 # Mostra a porcentagem de 1000 para 500 (200%)
# zzporcento 500,00 2,5% # Mostra quanto é 2,5% de 500,00
# zzporcento 500,00 +2,5% # Mostra quanto é 500,00 + 2,5%
#
# Autor: Aurelio Marinho Jargas, www.aurelio.net
# Desde: 2008-12-11
# Versão: 6
# Requisitos: zzzz zztool zztestar
# Tags: número, cálculo
# ----------------------------------------------------------------------------
zzporcento ()
{
zzzz -h porcento "$1" && return
local i porcentagem sinal
local valor1="$1"
local valor2="$2"
local escala=0
local separador=','
local tabela='200 150 125 100 90 80 75 70 60 50 40 30 25 20 15 10 9 8 7 6 5 4 3 2 1'
# Verificação dos parâmetros
test -n "$1" || { zztool -e uso porcento; return 1; }
# Remove os pontos dos dinheiros para virarem fracionários (1.234,00 > 1234,00)
zztestar dinheiro "$valor1" && valor1=$(echo "$valor1" | sed 's/\.//g')
zztestar dinheiro "$valor2" && valor2=$(echo "$valor2" | sed 's/\.//g')
### Vamos analisar o primeiro valor
# Número fracionário (1.2345 ou 1,2345)
if zztestar numero_fracionario "$valor1"
then
separador=$(echo "$valor1" | tr -d 0-9)
escala=$(echo "$valor1" | sed 's/.*[.,]//')
escala="${#escala}"
# Sempre usar o ponto como separador interno (para os cálculos)
valor1=$(echo "$valor1" | sed 'y/,/./')
# Número inteiro ou erro
else
zztool -e testa_numero "$valor1" || return 1
fi
### Vamos analisar o segundo valor
# O segundo argumento é uma porcentagem
if test $# -eq 2 && zztool grep_var % "$valor2"
then
# O valor da porcentagem é guardado sem o caractere %
porcentagem=$(echo "$valor2" | tr -d %)
# Sempre usar o ponto como separador interno (para os cálculos)
porcentagem=$(echo "$porcentagem" | sed 'y/,/./')
# Há um sinal no início?
if test "${porcentagem#[+-]}" != "$porcentagem"
then
sinal=$(printf %c $porcentagem) # pega primeiro char
porcentagem=${porcentagem#?} # remove primeiro char
fi
# Porcentagem fracionada
if zztestar numero_fracionario "$porcentagem"
then
# Se o valor é inteiro (escala=0) e a porcentagem fracionária,
# é preciso forçar uma escala para que o resultado apareça correto.
test $escala -eq 0 && escala=2 valor1="$valor1.00"
# Porcentagem inteira ou erro
elif ! zztool testa_numero "$porcentagem"
then
zztool erro "O valor da porcentagem deve ser um número. Exemplos: 2 ou 2,5."
return 1
fi
# O segundo argumento é um número
elif test $# -eq 2
then
# Ao mostrar a porcentagem entre dois números, a escala é fixa
escala=2
# O separador do segundo número é quem "manda" na saída
# Sempre usar o ponto como separador interno (para os cálculos)
# Número fracionário
if zztestar numero_fracionario "$valor2"
then
separador=$(echo "$valor2" | tr -d 0-9)
valor2=$(echo "$valor2" | sed 'y/,/./')
# Número normal ou erro
else
zztool -e testa_numero "$valor2" || return 1
fi
fi
# Ok. Dados coletados, analisados e formatados. Agora é hora dos cálculos.
# Mostra tabela
if test $# -eq 1
then
for i in $tabela
do
printf "%s%%\t%s\n" $i $(echo "scale=$escala; $valor1*$i/100" | bc)
done
# Mostra porcentagem
elif test $# -eq 2
then
# Mostra a porcentagem relativa entre dois números
if ! zztool grep_var % "$valor2"
then
echo "scale=$escala; $valor2*100/$valor1" | bc | sed 's/$/%/'
# valor + n% é igual a…
elif test "$sinal" = '+'
then
echo "scale=$escala; $valor1+$valor1*$porcentagem/100" | bc
# valor - n% é igual a…
elif test "$sinal" = '-'
then
echo "scale=$escala; $valor1-$valor1*$porcentagem/100" | bc
# n% do valor é igual a…
else
echo "scale=$escala; $valor1*$porcentagem/100" | bc
### Saída antiga, uma mini tabelinha
# printf "%s%%\t%s\n" "+$porcentagem" $(echo "scale=$escala; $valor1+$valor1*$porcentagem/100" | bc)
# printf "%s%%\t%s\n" 100 "$valor1"
# printf "%s%%\t%s\n" "-$porcentagem" $(echo "scale=$escala; $valor1-$valor1*$porcentagem/100" | bc)
# echo
# printf "%s%%\t%s\n" "$porcentagem" $(echo "scale=$escala; $valor1*$porcentagem/100" | bc)
#
# | sed "s/\([^0-9]\)\./\10./ ; s/^\./0./; y/./$separador/"
fi
fi |
# Assegura 0.123 (em vez de .123) e restaura o separador original
sed "s/^\./0./; y/./$separador/"
}