Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <script type="text/javascript">
- //инициация операндов
- var operand1 = '9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999';
- var operand2 = '1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112';
- //действие
- var operation = '/';
- document.write(operand1 + '<br>' + operation + '<br>' + operand2 + '<br>=<br>');
- document.write(calc(operand1, operand2, operation));
- //главная функция вычисления
- function calc(op1, op2, operation)
- {
- //строка для результата
- var result = '';
- //знаки операндов (false - плюс, true - минус)
- var sign1 = false;
- var sign2 = false;
- if(op1[0] == '-')
- {
- sign1 = true;
- op1 = op1.substr(1); //отрезаем знак от числа
- }
- if(op2[0] == '-')
- {
- sign2 = true;
- op2 = op2.substr(1);
- }
- if(operation == '-')
- {
- sign2 = !sign2; //меняем знак у второго операнда
- operation = '+'; //и работаем как со сложением
- }
- if(operation == '+')
- {
- if(!sign1 && !sign2)
- result = adding(op1, op2);
- if(!sign1 && sign2)
- result = substract(op1, op2);
- if(sign1 && !sign2)
- result = substract(op2, op1);
- if(sign1 && sign2)
- result = '-' + adding(op1, op2);
- }
- if(operation == '*')
- {
- //при умножении чисел с разным знаком результат будет отрицательным, иначе - положительным
- sign = '';
- if(sign1 != sign2) sign = '-';
- result = sign + multiply(op1, op2);
- }
- if(operation == '/')
- {
- //при делении чисел с разным знаком результат будет отрицательным, иначе - положительным
- sign = '';
- if(sign1 != sign2) sign = '-';
- result = sign + divide(op1, op2);
- }
- return result;
- }
- //сложение
- function adding(op1, op2)
- {
- var result = '';
- //перенос из младшего разряда в старший
- var shift = 0;
- //нормализация длины операндов
- var diff = op1.length - op2.length;
- if(diff > 0)
- op2 = addZeroToBegin(op2, diff);
- if(diff < 0)
- op1 = addZeroToBegin(op1, - diff);
- for(var i = op1.length - 1; i >= 0; i--)
- {
- //считаем текущий разряд
- var currByte = parseInt(op1.charAt(i)) + parseInt(op2.charAt(i)) + shift;
- shift = currByte / 10 | 0;
- currByte = currByte % 10;
- result = currByte.toString() + result;
- }
- if(shift != 0)
- result = shift.toString() + result;
- return result;
- }
- //вычитание
- function substract(op1, op2)
- {
- var result = '';
- var sign = '';
- //нормализация длины операндов
- var diff = op1.length - op2.length;
- if(diff > 0)
- op2 = addZeroToBegin(op2, diff);
- if(diff < 0)
- op1 = addZeroToBegin(op1, - diff);
- //перед выполнением вычитания проверим, действительно ли уменьшаемое больше вычитаемого
- //в противном случае нам нужно поменять их местами, а разность взять со знаком минус
- for(var i = 0; i < op1.length; i++)
- {
- if(op1[i] > op2[i]) break;
- if(op1[i] < op2[i])
- {
- var temp = op1;
- op1 = op2;
- op2 = temp;
- sign = '-';
- break;
- }
- }
- //заём из старшего разряда в младший
- var shift = 0;
- for(var i = op1.length - 1; i >= 0; i--)
- {
- //считаем текущий разряд
- var currByte = parseInt(op1.charAt(i)) - parseInt(op2.charAt(i)) - shift;
- if(currByte < 0)
- {
- currByte = 10 + currByte;
- shift = 1;
- }
- else shift = 0;
- result = currByte.toString() + result;
- }
- return sign + clearZero(result);
- }
- //умножение
- function multiply(op1, op2)
- {
- var result = '';
- for(var i = op2.length - 1; i >= 0; i--)
- {
- //перенос из младшего разряда в старший
- var shift = 0;
- //промежуточный результат - умножение первого операнда на очередную цифру второго
- var currRow = '';
- for(var j = op1.length - 1; j >= 0; j--)
- {
- //считаем текущий разряд
- var currByte = parseInt(op1.charAt(j)) * parseInt(op2.charAt(i)) + shift;
- shift = currByte / 10 | 0;
- currByte = currByte % 10;
- currRow = currByte.toString() + currRow;
- }
- if(shift != 0)
- currRow = shift.toString() + currRow;
- //нулями в конце осуществляем сдвиг при сложении результатов суммирования отдельных строк
- currRow = addZeroToEnd(currRow, op2.length - 1 - i);
- result = adding(result, currRow);
- }
- return result;
- }
- //деление
- function divide(op1, op2)
- {
- var result = '';
- //сначала сравним операнды: если делитель больше делимого, то результат будет нулём
- if(compare(op1, op2) < 0) return '0';
- //промежуточная разность для перехода между итерациями деления
- var shift = '';
- //промежуточное уменьшаемое на каждой итерации
- var currOp1 = op1.substr(0, op2.length);
- op1 = op1.substr(op2.length); //отрезаем от уменьшаемого взятые символы, чтобы не мешались
- while(true) //условие исправить!
- {
- //ищем очередной разряд частного - для этого перебираем все цифры от 9 до 1
- //на ноль проверим отдельно, чтобы не гонять цикл с умножением
- if(compare(currOp1, op2) < 0)
- {
- shift = currOp1;
- result = result + '0';
- }
- else
- for(var i = 9; i > 0; i--)
- {
- var currOp2 = multiply(op2, i.toString());
- if(compare(currOp1, currOp2) >= 0)
- {
- shift = substract(currOp1, currOp2);
- result = result + i.toString();
- break;
- }
- }
- if(op1.length == 0) break; //граничное условие
- //после итерации добавляем к промежуточному уменьшаемому ещё один разряд
- currOp1 = shift + op1[0];
- op1 = op1.substr(1);
- }
- return clearZero(result);
- }
- //заполнение строки начальными нулями
- function addZeroToBegin(str, count)
- {
- for(i = 0; i < count; i++)
- str = '0' + str;
- return str;
- }
- //заполнение строки конечными нулями
- function addZeroToEnd(str, count)
- {
- for(i = 0; i < count; i++)
- str = str + '0';
- return str;
- }
- //удаление начальных нулей из строки
- function clearZero(str)
- {
- for(i = 0; i < str.length; i++)
- {
- if(str[i] != '0') //пока не найдём первый ненулевой символ
- {
- str = str.substr(i); //запоминаем всю строку, начиная с него
- return str;
- }
- }
- //на случай, если вся строка состоит из нулей
- if(str[str.length-1] == '0') return '0';
- return str; //если ничего не нашли
- }
- //функция сравнения длин двух операндов
- //возвращает 1, если op1 > op2, -1, если op1 < op2, и 0, если равны
- function compare(op1, op2)
- {
- if(op1.length > op2.length) return 1;
- if(op1.length < op2.length) return -1;
- //если число знаков равно, то ищем до первого несовпадающего
- if(op1.length == op2.length)
- for(var i = 0; i < op1.length; i++)
- {
- if(op1[i] > op2[i]) return 1;
- if(op1[i] < op2[i]) return -1;
- }
- return 0;
- }
- </script>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement