Mặc dù sử dụng biểu hiện sed là tuyệt vời nhưng nó có những hạn chế. Ví dụ sau thất bại:
$ echo "1000000000000000000000000000000+1" | sed -e 's/\([0-9]*\)+\([0-9]*\)/expr \1 + \2/e'
expr: 1000000000000000000000000000000: Numerical result out of range
Để khắc phục hạn chế này, tôi chỉ cần chuyển sang sức mạnh của sed thuần túy và thực hiện theo bộ cộng thập phân có độ dài tùy ý:
#! / bin / sed -f
s / + / \ n / g
s / $ / \ n \ n0 /
:VÒNG
s / ^ \ (. * \) \ (. \) \ n \ (. * \) \ (. \) \ n \ (. * \) \ n \ (. \) $ / 0 \ 1 \ n0 \ 3 \ n \ 5 \ n \ 6 \ 2 \ 4 /
h
s / ^. * \ n. * \ n. * \ n \ (... \) $ / \ 1 /
# mô đun cộng đầy đủ thập phân
# INPUT: 3digits (Mang theo, A, B,)
# ĐẦU RA: 2 bit (Thực hiện, Tổng hợp)
s / $ /;000 = 00001 = 01002 = 02003 = 03004 = 04005 = 05006 = 06007 = 07008 = 08009 = 09010 = 01011 = 02012 = 03013 = 04014 = 05015 = 06016 = 07017 = 08018 = 09019 = 10020 = 02021 = 03022 = 04023 = 06025 = 07026 = 08027 = 09028 = 10029 = 11030 = 03031 = 04032 = 05033 = 06034 = 07035 = 08036 = 09037 = 10038 = 11039 = 12040 = 04041 = 05042 = 06043 = 070 13050 = 05051 = 06052 = 07053 = 08054 = 09055 = 10056 = 11057 = 12058 = 13059 = 14060 = 06061 = 07062 = 08063 = 09064 = 10065 = 11066 = 12067 = 13068 = 14069 = 15070 = 070 = = 11075 = 12076 = 13077 = 14078 = 15079 = 16080 = 08081 = 09082 = 10083 = 11084 = 12085 = 13086 = 14087 = 15088 = 16089 = 17090 = 09091 = 10092 = 11093 = 12094 = 13095 = 14096 = 15097 = 18100 = 01101 = 02102 = 03103 = 04104 = 05105 = 06106 = 07107 = 08108 = 09109 = 10110 = 02111 = 03112 = 04113 = 05114 = 06115 = 07116 = 08117 = 09118 = 10119 = 11120 = 03121 = 04122 = 05123 = 07125 = 08126 = 09127 = 10128 = 11129 = 12130 = 04131 = 05132 = 06133 = 07134 = 08135 = 09136 = 10137 = 11138 = 12139 = 13140 = 05141 = 06142 = 0714 = =3 = 08144 = 09145 = 10146 = 11147 = 12148 = 13149 = 14150 = 06151 = 07152 = 08153 = 09154 = 10155 = 11156 = 12157 = 13158 = 14159 = 15160 = 11161 = 08162 = 09163 = 10164 = 11165 = 14168 = 15169 = 16170 = 08171 = 09172 = 10173 = 11174 = 12175 = 13176 = 14177 = 15178 = 16179 = 17180 = 09181 = 10182 = 11183 = 12184 = 13185 = 14186 = 15187 = 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
Cách thức hoạt động của nó là bằng cách triển khai mô đun bộ cộng thập phân có thêm hai chữ số đầu vào (A và B) cũng như Carry Bit và tạo ra bit Sum và Carry. Ý tưởng được mượn từ điện tử trong đó bộ cộng nhị phân thực hiện tương tự cho số nhị phân. Tất cả những gì chúng ta phải làm là lặp bộ cộng trên tất cả các chữ số và chúng ta có thể thêm các số có độ dài tùy ý (giới hạn bởi bộ nhớ). Dưới đây là trình bổ sung đang hoạt động:
./decAdder.sed
666666666666666666666666666666999999999999991111111112222+1100000000000000000000011111111111111111111111111111111111
1766666666666666666666677777778111111111111102222222223333
Trong cùng một cách chính xác, người ta có thể thực hiện bộ cộng nhị phân (hoặc bất kỳ cơ sở nào khác). Tất cả bạn phải làm là thay thế dòng bắt đầu bằng s/$/;000=00001...
mẫu thay thế phù hợp cho cơ sở nhất định. Ví dụ: s/$/;000=00001=01010=01011=10100=01101=10110=10111=11/
là mẫu thay thế cho bộ cộng nhị phân có độ dài tùy ý.
Bạn có thể phù hợp với mã được ghi lại trên github của tôi .