Предполагая, что в вашем распоряжении нет математического пакета произвольной точности, но у вас есть
набор основных процедур для работы со строками, вы можете сделать следующее:
Построить список степеней 2, а затем деконструировать двоичную строку в обратном порядке.
упорядочивайте по одному биту за раз, добавляя соответствующую степень 2 для каждого бита '1' в строке.
Единственная арифметическая функция произвольной точности, которую вам нужно сделать, это сложение, и это довольно
легко реализовать с помощью арифметики длинной руки.
Предположим, вы реализовали произвольную арифметическую функцию добавления, которая называется:
ADD
принимает 2 строки, содержащие десятичные числа, в качестве входных данных и возвращает десятичную сумму
как строка Что-то вроде:
SumString = ADD(DecimalString1, DecimalString2)
SumString
- это строка десятичных цифр, представляющая сумму DecimalString1
и DecimalString2
.
Шаг 1. Составьте список из 2-х степеней следующим образом:
BitString is string /* String of '1' and '0' values... */
BitString = '111001101001110100100(...)1001001111011100100' /* or whatever... */
PowerOf2 is array of string /* Array of strings containing powers of 2 */
PowerOf2[1] = '1' /* 2**0 to get things started... */
/* Build as many powers of 2 as there are 'bits' in the input string */
for i from 2 to length(BitString) by +1
PowerOf2[i] = ADD(PowerOf2[i-1], PowerOf2[i-1])
end
Примечание. Выше предполагается, что массивы / строки основаны на 1 (в отличие от нуля).
Шаг 2: Деконструируйте BitString, накапливая сумму по ходу:
DecimalValue is string /* Decimal value of BitString */
BitString is string /* Your input set of bits as a string... */
ReverseBitString is string /* Reversed input */
DecimalValue = '' /* Result */
BitString = '111001101001110100100(...)1001001111011100100' /* or whatever... */
ReverseBitString = reverse(BitString) /* Reverse so we process lsb to msb */
for i from 1 to length(ReverseBitString) by +1
if substr(ReverseBitString, i, 1) == '1' then /* Bit at position i */
DecimalValue = ADD(DecimalValue, PowerOf2[i])
end
end
if DecimalValue = '' then DecimalValue = '0' /* bit string was all zero */
Display DecimalValue /* This is the result */
Как построить функцию произвольной точности ADD
? Это выглядит примерно так:
function ADD (DecVal1 is string, DecVal2 is string) return string
SumVal is string
Rev1 is string
Rev2 is string
DigitSum is integer
CarryDigit is integer
SumVal = '' /* Result so far... */
Rev1 = reverse(DecVal1) /* Reverse digit order */
Rev2 = reverse(DecVal2) /* Reverse digit order */
/* Pad shorter reversed sting with trailing zeros... */
if length(Rev1) > length(Rev2) then
Rev2 = concat(Rev2, copies(length(Rev1) - length(Rev2), '0')
end
else
Rev1 = concat(Rev1, copies(length(Rev2) - length(Rev1), '0')
end
/* Sum by digit position, least to most significant */
CarryDigit = 0
for i from 1 to length(Rev1) by + 1
DigitSum = CtoI(substr(Rev1, i, 1)) + CtoI(substr(Rev2, i, 1)) + CarryDigit
if DigitSum > 9 then
DigitSum = DigitSum - 10
CarryDigit = 1
end
else
CarryDigit = 0
end
SumVal = concat(ItoC(DigitSum), SumVal)
end
if CarryDigit > 0 then
SumVal = concat(ItoC(CarryDigit), SumVal)
end
return SumVal
Предполагаемые встроенные строковые функции:
- reverse (String): возвращает строку в обратном порядке
- length (String): Возвращает длину данной строки
- concat (String, String): возвращает объединение двух строк
- substr (String, start, length): возвращает подстроку строки из начала для символов длины (на основе 1)
- CtoI (String): возвращает десятичное целочисленное значение заданного символа (например, '1' = 1, '2' = 2, ...)
- ItoC (Integer): возвращает десятичное представление целого числа (например, 1 = '1', 2 = '2', ...)
- копий (количество, строка): возвращает количество конкатинированных копий строки