Bien que l'utilisation de sed soit excellente, elle a ses limites. Par exemple, la suite échoue:
$ echo "1000000000000000000000000000000+1" | sed -e 's/\([0-9]*\)+\([0-9]*\)/expr \1 + \2/e'
expr: 1000000000000000000000000000000: Numerical result out of range
Pour surmonter cette limitation, il suffit de se tourner vers la puissance intrinsèque de sed sed et de mettre en œuvre l'additionneur décimal de longueur arbitraire suivant:
#! / bin / sed -f
s / + / \ n / g
s / $ / \ n \ n0 /
:BOUCLE
s / ^ \ (. * \) \ (. \) \ n \ (. * \) \ (. \) \ n \ (. * \) \ n \ (. \) $ / 0 \ 1 \ n0 \ 3 \ n \ 5 \ n \ 6 \ 2 \ 4 /
h
s /^.* \ n. * \ n. * \ n \ (... \) $ / \ 1 /
# module d'additionneur décimal complet
# INPUT: 3 chiffres (Carry in, A, B,)
# SORTIE: 2bits (Carry, Sum)
s / $ /;000 = 00001 = 01002 = 02003 = 03004 = 04005 = 05006 = 06007 = 07008 = 08009 = 09010 = 01011 = 02012 = 03013 = 04014 = 05016 = 06016 = 07017 = 08018 = 09019 = 02019 = 02019 = 02021 = 03021 = 06025 = 07026 = 08027 = 09028 = 10029 = 11030 = 03031 = 04032 = 05033 = 06034 = 07035 = 08036 = 09037 = 10038 = 11039 = 12040 = 04042 = 05042 = 06043 = 07044 = 07044 = 08045 = 04045 = 10045 = 10048 = 10048 = 10048 = 10048 = 10048 = 10048 = 10048 = 10048 = 10048 = 10048 = 10048 = 10040 = 04041 = 04042 = 06042 = 06042 = 04034 = 04034 = 0 13050 = 05051 = 06052 = 07053 = 08054 = 09055 = 10056 = 11056 = 12058 = 13059 = 14060 = 06061 = 07062 = 08064 = 09064 = 10065 = 11066 = 12067 = 13067 = 13069 = 06062 = 06062 = 07055 = 09054 = 11075 = 12076 = 13077 = 14078 = 15079 = 16080 = 08081 = 09082 = 10083 = 11084 = 12085 = 13086 = 14087 = 15088 = 15089 = 17090 = 09091 = 10092 = 11093 = 12094 = 13094 = 13096 = 15097 = 16098 = 17099 = = 18100 = 01101 = 02102 = 03103 = 04104 = 05105 = 06106 = 07107 = 08108 = 09109 = 10110 = 0113 = 0113 = 05115 = 07117 = 08118 = 08117 = 09119 = 10119 = 10110 = 0113 = 04114 = 06115 = 04124 = 05121 = 05121 = 05121 07125 = 08126 = 09127 = 10128 = 11129 = 12130 = 04131 = 05132 = 06133 = 07134 = 08135 = 09136 = 10137 = 11138 = 12139 = 13140 = 05141 = 06142 = 07143 = 08144 = 09145 = 10146 = 11147 = 12148 = 13149 = 14150 = 06151 = 07152 = 08153 = 09154 = 10155 = 11156 = 12157 = 13158 = 14159 = 15160 = 07162 = 08162 = 09162 = 09163 = 10164 = 11165 = 11166 = 11166 = 11167 = 11167 = 11167 = 11167 = 13167 = 13167 = 11167 = 13167 = 13167 = 11167 = 11167 = 13167 = 11166 = 11167 = 11167 = 14168 = 15169 = 16170 = 08171 = 09172 = 10173 = 11174 = 12175 = 13176 = 14177 = 15178 = 16179 = 17180 = 09181 = 10182 = 11183 = 12184 = 13185 = 14186 = 15187 = 16188 = 17189 = 18190 = 10191 = 11192 = 12193 = 13194 = 14195 = 15196 = 16197 = 17198 = 18199 = 19 /
s / ^ \ (... \) [^;] *; [^;] * \ 1 = \ (.. \). * / \ 2 /
H
g
s / ^ \ (. * \) \ n \ (. * \) \ n \ (. * \) \ n ... \ n \ (. \) \ (. \) $ / \ 1 \ n \ 2 \ n \ 5 \ 3 \ n \ 4 /
/ ^ \ ([0] * \) \ n \ ([0] * \) \ n / {
s /^.* \ n. * \ n \ (. * \) \ n \ (. \) / \ 2 \ 1 /
s / ^ 0 \ (. * \) / \ 1 /
q
}
b boucle
Cela fonctionne en mettant en œuvre un module d'additionneur décimal qui ajoute deux chiffres d'entrée (A et B) ainsi que Carry Bit et produit un bit Sum et Carry. L'idée est empruntée à l'électronique où l' additionneur binaire fait la même chose pour les nombres binaires. Tout ce que nous avons à faire est de boucler l'additionneur sur tous les chiffres et nous pouvons ajouter des nombres de longueur arbitraires (limités par la mémoire). Voici l'additionneur en action:
./decAdder.sed
666666666666666666666666666666999999999999991111111112222+1100000000000000000000011111111111111111111111111111111111
1766666666666666666666677777778111111111111102222222223333
De la même manière, on peut implémenter un additionneur binaire (ou n’importe quelle autre base). Tout ce que vous avez à faire est de remplacer la ligne qui commence s/$/;000=00001...
par un modèle de substitution approprié pour une base donnée. Par exemple: s/$/;000=00001=01010=01011=10100=01101=10110=10111=11/
est un modèle de substitution pour un additionneur binaire de longueur arbitraire.
Vous pouvez adapter le code documenté sur mon github .