Конвертер (перевод) систем счисления
На языке JavaScript написать программу без встроенных функций с использованием условий, циклов и массивов конвертации из десятичной системы счисления в двоичную, восьмеричную и шестнадцатеричную, а так же реализовать конвертацию чисел в обратном направлении.
Помогите понять, где ошибка. Неправильно переводит из 10 в 2, 8 и 16, а в обратном направлении вообще не работает. <html> <head> <meta charset="utf-8" /> <title>Конвертёр чисел между системами счисления</title> <script type="text/javascript"> function translaten() { var number = document.getElementById('number').value; var vhod = document.getElementById('input').value; var vihod = document.getElementById('output').value; var resultat = ""; if (vhod == 10 && vihod == 2 || vihod == 8 || vihod == 16) { var a; while (number > 0) { a = number % vihod; resultat = resultat + a; var b; b=number/vihod; number=number-Math.ceil(b); } alert('Ваш результат - '+resultat); } if (vhod == 2 || vhod == 8 || vihod == 16 && vihod == 10) { var resultat = 0, m = 0, nnazad, n = number.length; nnazad = n - 1; var arr=number.split(''); // for (var i=1; i == n; i++) { var i = 0; while (i < number.length) { if (arr[i] == "A") { arr[i] = "10"; } if (arr[i] == "B") { arr[i] = "11"; } if (arr[i] == "C") { arr[i] = "12"; } if (arr[i] == "D") { arr[i] = "13"; } if (arr[i] == "E") { arr[i] = "14"; } if (arr[i] == "F") { arr[i] = "15"; } m = number[i] * Math.pow(input, n); resultat = m + resultat; n--; i++; alert('Ваш результат - ', resultat); if (i > nnazad) { alert('Ваш результат - ', resultat, '.'); break; } } //} } } </script> <title>Перевод из одной системы счисления в другую</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <style type="text/css"> * { padding: 0; } body { color: #80e8ff; background: #2E69E3; text-align: center; /* выравниваем все содержимое body по центру */ } div { width: 800px; /* ширина основного блока */ height: 100%; /* высота для наглядности */ background: #004A7f; /* цвет блока для наглядности */ margin: 0 auto; /* задаем отступ слева и справа auto чтобы сработало выравнивание по центру */ } p { font-family: courier; font-size: 160%; } .input { border: 5px solid #cccccc; border-radius: 9px; -webkit-border-radius: 9px; -moz-border-radius: 3px; -khtml-border-radius: 3px; background: #ffffff !important; outline: none; height: 34px; width: 220px; color: #80e8ff; font-size: 16px; font-family: Tahoma; text-align: right; } .button { background: #2E8CE3; padding: 7px 30px; font-size: 16px; font-weight: bold; color: #FFFFFF; text-align: center; border: solid 1px #73C8F0; cursor: pointer; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; background: -moz-linear-gradient(0% 100% 90deg, #2E8CE3, #73C2Fd); background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#73C2Fd), to(#2E8CE3)); box-shadow: inset 0 1px 0 0 #FFFFFF; -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.5); -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.5); border-bottom: 1px solid rgba(0,0,0,0.25); text-shadow: 0 -1px 1px rgba(0,0,0,0.25); } .button:hover { background: #80e8ff; background: -moz-linear-gradient(0% 100% 90deg, #2E69E3, #59C2FF); background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#59C2FF), to(#2E69E3)); } .button:active { background: #80e8ff; background: -moz-linear-gradient(0% 100% 90deg, #2E69E3, #59C2fF); background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#59C2FF), to(#2E69E3)); box-shadow: inset 1px 1px 0 0 #004A7f; -moz-box-shadow: inset 1px 1px 0 0 #004A7f; -webkit-box-shadow: inset 1px 1px 0 0 #004A7F; padding: 8px 29px 6px 31px; } .select { border: 5px solid #cccccc; border-radius: 9px; -webkit-border-radius: 9px; -moz-border-radius: 3px; -khtml-border-radius: 3px; background: #ffffff !important; outline: none; height: 34px; width: 60px; color: #004A7f; font-size: 16px; font-family: Tahoma; } </style> </head> <body> <form> <div> <p><strong>Конвертёр чисел между системами счисления:</strong></p> <p> число <input type="text" name="number" id="number" /> </p> из <select class="element select medium" id="input" name="input"> <option value="" selected="selected"></option> <option>2</option> <option>8</option> <option>10</option> <option>16</option> </select> системы счисления в <select class="element select medium" id="output" name="output"> <option value="" selected="selected"></option> <option>2</option> <option>8</option> <option>10</option> <option>16</option> </select> систему счисления <p><input type="button" value="Перевести" onclick="translaten();" /></p> </div> </form> </body> </html> |
Я вспомнил, что я когда-то делал такое, когда ещё не знал о существовании toString() пока для перевода из десятичной в любую систему:
<script> var mas=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L"]; // Можно завершить латинский алфавит, а если не хватит - добавить русский var mas1=[]; function NumConvert(a,b){ while(a>=1){ c=Math.floor(a/b); d=a-b*c; mas1.push(d); a=c; } var result=""; for(i=0;i<mas1.length;i++){ result+=mas[mas1[mas1.length-1-i]]+""; } alert(result); } </script> Тут аргументы a - число, b - система. |
Опан, а теперь запусти этот код в строгом режиме. Его нельзя использовать.
|
<script> "use strict"; //************************************ // эта функция переводит число из одной в другую систему счисления function convert(number, fromBase, toBase) { return fromDec(toDec(number, fromBase), toBase); } function toDec(number, fromBase) { var result = 0; number = number.toString().toLowerCase().split(''); for(var index = 0, length = number.length, digit; index < length; index++) { digit = prepareDigit(number[index]); result = result * fromBase + digit; } return result; } function fromDec(number, toBase) { var result = [], integerPart, digit; while(number >= 1) { integerPart = parseInt(number/toBase); digit = number - toBase * integerPart; if(digit >= 10) digit = String.fromCharCode(digit + 87); result.unshift(digit); number = integerPart; } return result.join(''); } function prepareDigit(digit) { digit = digit.charCodeAt() - 48; if(digit > 48) digit -= 39; return digit; } //********************************** function onClick(q) { var BASES = { 'bin': '2', 'oct': '8', 'dec': '10', 'hex': '16' }; var PATTERN = /([\dabcdef]+)(?:\s*(?:from|из|\s)(?:\s*base)?\s*(\d+|bin|oct|dec|hex))?\s*(?:(?:to|в)(?:\s*base)?\s*(\d+|bin|oct|dec|hex))?/; var PATTERN_BASE = /bin|oct|dec|hex/; var value = document.getElementById('inpution').value || q || ''; var match = value.match(PATTERN); var number = match && match[1] || '0'; var from = match && match[2]; var to = match && match[3]; if(PATTERN_BASE.test(from)) { from = BASES[from]; } if(PATTERN_BASE.test(to)) { to = BASES[to]; } from = +from || 10; to = +to || 10; var result = convert(number, from , to); document.getElementById('result').innerHTML = 'convert <span class="hightlight">' + number.toUpperCase() + '<sub>' + (from == 10 ? '' : from) + '</sub></span> to <span class="hightlight">base ' + to + '</span> = ' + result.toUpperCase() + '<sub>' + (to == 10 ? '' : to) + '</sub>'; } function example(q) { document.getElementById('inpution').value = q; onClick(); } </script> <style> #result, #examples {font-family: monospace; font-size: 18px; color: #aaa; } #examples a:link, #examples a:visited {text-decoration: none; display: block; font-size: 14px; } #examples a:hover, #examples a:focus {text-decoration: underline; } #result .hightlight {color: #000; } #result sub {font-size: 12px; } #examples {float: left; margin-left: 20px; } #examples .description {font-size: 12px; } </style> <div style="float: left; "> <input id="inpution" type="text" value="125 base 10 to base 2" /> <input id="button" type="button" value="=" onclick="onClick(); " /> <div id="result"></div> </div> <div id="examples"> <span>Примеры</span> <div class="description">Из десятичной в другую систему счисления</div> <a href="#" onclick="example('147 to base 2');">147 to base 2</a> <a href="#" onclick="example('1025 to base 5');">1025 to base 5</a> <a href="#" onclick="example('255 to base 16');">255 to base 16</a> <div class="description">Из данной в 10-ую систему счисления</div> <a href="#" onclick="example('1000101011 base 2');">1000101011 base 2</a> <a href="#" onclick="example('fff base 16');">fff base 16</a> <div class="description">Из одной в другую систему счисления</div> <a href="#" onclick="example('1424 base 5 to base 12');">1424 base 5 to base 12</a> </div> |
Цитата:
Остальное относится к вводу-выводу информации на странице, каждый может заменить на своё. |
Цитата:
Перевести 1024 в двоичную систему: 1024 to bin Перевести шестнадцатиричное FF в десятичную систему: FF hex Перевести десятичное 25 в восьмеричную систему: 25 dec to oct С 3-ей по 38-ую строки описаны четыре функций, которые позволяют перевести число из одной системы счисления в другую. Главная из них — convert, которая осуществляет перевод, остальные три — вспомогательные. Функция convert, берёт число number по основанию fromBase и переводит его в десятичную систему. (Осуществляется при помощи toDec(number, fromBase), строка 7) Затем полученное десятичное число переводится в систему счисления toBase при помощи функций fromDec, которая берёт десятичное число и переводит его в указанную во втором параметре систему счисления. В функции toDec (строки 9-17) для перевода в десятичную систему вычисляется сумма произведения цифры на основание возведённое в степень, соответствующей позиции цифры. Для упрощения вычисления используется правило Горнера. Поскольку «цифрой» являются строки "0", "1", ..., "9", "a", "b", ..., "f", то для перевода этих «цифр» используется вспомогательная функция prepareDigit (строки 31-36), которая переводит «цифру» в её десятичное представление. Для этого используется код символа. Символу "0" соответствует код 48, "1" соответствует 49, ..., "9" соответствует 57. Отняв от кода символов число 48 (строка 32), мы получим число соответствующее числовому значению строки. Такое срабатывает только для "0", "1", ..., "9". Коды же символов "a", "b", ..., "f" равны соответственно 97, 98, ..., 102. Поскольку мы уже отняли 48, то у нас соответственно имеется 49, 50, ..., 54. Поэтому проверяется (строка 33) равна ли «цифра» числу большему чем 48. Если это действительно так, то следует ещё отнять 39. (Чтобы из ряда 49, 50, ..., 54 получился ряд 10, 11, ..., 15). Короче говоря, функция prepareDigit для ряда переданных ей значении "0", "1", ..., "9", "a", "b", ..., "f" возвращает 1, 2, ..., 9, 10, 11, ..., 15 соответственно. В функции fromDec (строки 18-30) используется алгоритм[1] перевода десятичного числа в соответствующее основание.
[1] https://ru.wikipedia.org/w/index.php...oldid=91753916 С 40-ой по 67-ую строки описана функция, которая вызывается каждый раз, когда человек нажимает на кнопку «=». В 49-ой строке переменной value присваивается то, что ввёл человек в текстовое поле. Затем (50-ая строка) проверяется, подходит ли введённый текст под регулярное выражение, описанное в 47-ой строке, и в переменную match записываются результаты. Данное регулярное выражение, визуально можно представить так: https://regexper.com/#%2F%28%5B%5Cda...ex%29%29%3F%2F NB!!! Числа, которые совпали в регулярном выражении имеют тип String, т. е. это число которое записано как последовательность символов и представляет из себя строку. Первая группа в этом регулярном выражении обозначает число, которое нужно перевести. Оно состоит из одной или более цифр, а также символов A, B, C, D, E и F. Это значит, что для перевода подходит любое целое неотрицательное число из систем счисления от 2 до 16 включительно. В случае, когда человек ввёл запрос, который подходит под выражение (и переменная match не равна null), переменной number присваивается число, которое нужно перевести, иначе присваивается '0' (строка 51) Вторая и третья группы обозначают сами системы счисления, которые присваиваются переменным from и to (строки 52 и 53). Когда from или to это не числа (проверяется в 55-61 строках, регулярное выражение для проверки в 48-ой строке), а краткое обозначение двоичной, восьмеричной, десятичной или шестнадцатеричной системы счисления, то такое обозначение преобразуется в число согласно описанию в 41-46 строках. Соответственно теперь в переменных from или to содержатся только числа обозначающие систему счисления. Согласно регулярному выражению на 47-ой строке, 2-ая и/или 3-яя группы могут отсутствовать. Тогда считается, что число преобразуется из/в десятичную систему. (строки 63 и 64, «+» перед строкой, представляющей из себя число, означает, что это теперь будет число типа Number) Теперь известны число (number), система счисления этого числа (from), и система, в которую нужно перевести это число (to). Используя вышеупомянутую функцию convert, производится перевод и записывается в переменную result — результат готов. (строка 65) В 66-ой строке немного «синтактической криптографии», которая печатает на странице результат. Сначала печатается, что удалось выудить из того, что ввёл человек (типа компьютер говорит, я вас понял вот таким образом), затем после знака равно записан результат перевода. Строки 69-72, которые описывают функцию вставляющую в текстовое поле какой-либо запрос и выполняющую его, нужны только для запуска примеров на 88-99 строках. Цитата:
Метод toString на 11-ой строке, применялся именно для того, чтобы гарантированно была строка в том месте. Можно было бы написать вместо number.toString() так: ("" + number) или String(number) Во всяком случае ни parseInt ни toString не применялись, чтобы использовать встроенные возможности перевода из одной системы счисления в другую. |
Часовой пояс GMT +3, время: 04:01. |