Sed ifadesini kullanmak harika olsa da, sınırlamaları vardır. Örneğin aşağıdaki başarısız:
$ echo "1000000000000000000000000000000+1" | sed -e 's/\([0-9]*\)+\([0-9]*\)/expr \1 + \2/e'
expr: 1000000000000000000000000000000: Numerical result out of range
Bu sınırlamayı aşmak için basitçe saf sed'in gücüne yönelmek ve isteğe bağlı uzunluktaki ondalık toplayıcıyı uygulamak:
#! / bin / sed -f
s / + / \ N / g
s / $ / \ n \ n0 /
: DÖNGÜ
s / ^ \ (. * \) \ (. \) \ n \ (. * \) \ (. \) \ n \ (. * \) \ n \ (. \) $ / 0 \ 1 \ n0 \ 3 \ n \ 5 \ n \ 6 \ 2 \ 4 /
h
s /^.*. \ n * \ n. * \ n \ (... \) $ / \ 1 /
# ondalık ondalık toplayıcı modülü
# GİRİŞ: 3 basamak (Taşıma, A, B,)
# ÇIKIŞ: 2 bit (Taşıma, Toplam)
s / $ /;000 = 00001 = 01002 = 02.003 = 03004 = 04005 = 05006 = 06007 = 07008 = 08009 = 09010 = 01011 = 02012 = 03013 = 04.014 = 05.015 = 06.016 = 07017 = 08018 = 09019 = 10020 = 02021 = 03022 = 04023 = 05.024 = 06025 = 07026 = 08027 = 09028 = 10029 = 11030 = 03031 = 04032 = 05033 = 06034 = 07035 = 08036 = 09037 = 10038 = 11039 = 12040 = 04041 = 05042 = 06043 = 07044 = 08045 = 09046 = 10047 = 11048 = 12049 = 13050 = 05051 = 06052 = 07053 = 08054 = 09055 = 10056 = 11057 = 12058 = 13059 = 14060 = 06061 = 07062 = 08063 = 09064 = 10065 = 11066 = 12067 = 13068 = 14069 = 15070 = 07071 = 08072 = 09073 = 10074 = 11075 = 12076 = 13077 = 14078 = 15079 = 16080 = 08081 = 09.082 = 10083 = 11084 = 12085 = 13086 = 14087 = 15088 = 16089 = 17090 = 09.091 = 10092 = 11093 = 12094 = 13095 = 14096 = 15097 = 16098 = 17099 = 18100 = 01101 = 02102 = 03103 = 04104 = 05105 = 06106 = 07107 = 08108 = 09109 = 10110 = 02111 = 03112 = 04113 = 05114 = 06115 = 07116 = 08117 = 09118 = 10119 = 11120 = 03121 = 04122 = 05123 = 06124 = 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 = 07161 = 08162 = 09163 = 10164 = 11165 = 12166 = 13167 = 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 LOOP
Çalışma şekli, Carry Bit'in yanı sıra iki giriş hanesi (A ve B) ekleyen ve bir Sum ve Carry biti üreten bir ondalık toplama modülü uygulamaktır. Bu fikir, ikili toplayıcıyı ikili sayılar için aynı olan elektronikten ödünç alınır . Tek yapmamız gereken, toplayıcıyı tüm rakamlar arasında dolaşmak ve isteğe bağlı uzunluk numaraları ekleyebiliriz (hafıza ile sınırlıdır). Aşağıda işlem yapan toplayıcı var:
./decAdder.sed
666666666666666666666666666666999999999999991111111112222+1100000000000000000000011111111111111111111111111111111111
1766666666666666666666677777778111111111111102222222223333
Tam olarak aynı şekilde bir ikili (veya başka bir taban) toplayıcı uygulanabilir. Tek yapmanız gereken s/$/;000=00001...
verilen taban için uygun ikame modeliyle başlayan çizgiyi değiştirmek . Örneğin: s/$/;000=00001=01010=01011=10100=01101=10110=10111=11/
isteğe bağlı uzunluktaki ikili toplayıcı için değiştirme modelidir.
Benim github üzerinde belgelenen kodunu sığdırabilirsiniz .