Онлайн конвертер: перевод дробных чисел из одной системы счисления в другую

Просили не так давно конвертер для перевода из одной системы счисления в другую написать, правда там на Java надо было. Решил и на JS написать :D

Онлайн конвертер

Переводит и дробные числа тоже. Заниматься фильтрацией ввода не интересно, поэтому корректность ввода на ваше усмотрение (: Для с.с. больше 10 цифры вводите на английском языке.

Исходное число:

Основание системы счисления исходного числа:


Основание системы счисления переведенного числа:

Результат:


Немного математики

Люди в основном используют 10-ую систему счисления, которая содержит 10 цифр (0-9), а число 10 называется основанием системы счисления. Наша система счисления – позиционная, то есть число зависит от позиций содержащихся в нем цифр (римская – непозиционная).

12310 = 1 * 102 + 2 * 101 + 3 *100

Любое 10-ое число можно разложить на составляющие. Для этого достаточно сложить произведения всех цифр на 10 (основание системы счисления) в степени соответствующего разряда.

Переводы целых чисел из одной системы счисления в другую

Для работы с 2, 8 и 16-ми системами счисления всё просто, там порязрядно операции осуществляются. Больше интересует общий случай. Можно сформулировать алгоритм перевода целых чисел:

  1. Основание новой системы счисления выразить цифрами исходной системы счисления и все последующие действия производить в исходной системе счисления.
  2. Последовательно выполнять деление данного числа и получаемых целых частных на основание новой системы счисления до тех пор, пока не получим частное, меньшее делителя.
  3. Полученные остатки, являющиеся цифрами числа в новой системе счисления, привести в соответствие с алфавитом новой системы счисления.
  4. Составить число в новой системе счисления, записывая его, начиная с последнего остатка.

Пример. Перевести десятичное число 14610 в восьмеричную систему счисления:


146

8

 

2

18

8

 

2

2

Получаем: 14610 = 2228

Переводы дробных чисел из одной системы счисления в другую

В общем ввиде алгоритм:

  1. Основание новой системы счисления выразить цифрами исходной системы счисления и все последующие действия производить в исходной системе счисления.
  2. Последовательно умножать данное число и получаемые дробные части произведений на основание новой системы до тех пор, пока дробная часть произведения не станет равной нулю или будет достигнута требуемая точность представления числа.
  3. Полученные целые части произведений, являющиеся цифрами числа в новой системе счисления, привести в соответствие с алфавитом новой системы счисления.
  4. Составить дробную часть числа в новой системе счисления, начиная с целой части первого произведения.

Пример. Перевести число 0,6562510 в восьмеричную систему счисления:

0,

 65625

*     8

5

 25000

*     8

2

 00000

Получаем: 0,6562510 = 0,528

Для перевода в 10-ую систему можно попроще. Там для целой и дробной части подход один.

123,456x = 1 * x2 + 2 * x1 + 3 *x0 + 4 * x-1 + 5 *x-2+ 6 *x-3 = y10

Как пример:

123,4567 = 1 * 72 + 2 * 71 + 3 *70 + 4 * 7-1 + 5 *7-2+ 6 *7-3 = 66.69096…10

Видно, что из-за использования дробей с разными знаменателями не всегда возможно порой число представить в другой системе счисления без погрешностей (это касается дробных чисел). Процесс вычисления обычно обрывают на некотором шаге, когда считают, что получена требуемая точность представления числа.

Лёгкий перевод из 2, 8, 16 системы счисления

Чтобы перевести число из 8-ой(16-ой) системы в 2-ую надо каждый разряд восьмеричного (16-ого) числа записать триадами(четвёрками), т.е двоичными разрядами согласно таблице.

10-ая 2-ая 8-ая 16-ая
0 0000 0 0
1 0001 1 1
1 0010 2 2
3 0011 3 3
4 0100 5 6
5 0101 5 5
6 0110 6 6
7 0111 7 7
8 1000 10 8
9 1001 11 9
10 1010 12 A
11 1011 13 B
12 1100 14 C
13 1101 15 D
14 1110 16 E
15 1111 17 F

Для перевода числа из двоичной системы в 8-ую(16-ую) надо начиная с младшего разряда разбить число на триады(четверки), а потом каждую из триад(четверок) заменить соответствующей цифрой в 8-ой(16-ой) системе.

Немного исходников

Кому интересно, выкладываю исходники (: Написаны, само собой, на JS. На Java в целом всё выглядит так же, с той лишь разницей, что надо везде типы определить и соответствующие приведения типов сделать.

Для перевода целого числа в десятиричную с.с. в JS достаточно всего одну строку написать:

//sNumber - исходное число
//sSystem - система счисления числа
//на выходе число в десятичной с.с.
return parseInt(sNumber, sSystem);

Для перевода из десятиричной в другую с.с. немного посложнее:

this.fromDecInt= function(sNumber, rSystem){
	var res = "";
	var resDiv = Math.floor(sNumber/rSystem);
	var newSNumber = sNumber;
	if(resDiv>=rSystem)
	{
		while(resDiv>=rSystem)
		{
			resDiv = Math.floor(newSNumber/rSystem);
			var mod = newSNumber-resDiv*rSystem;
			if(mod>=10)
				res+= String.fromCharCode(65+mod-10);
			else
				res+=mod;
					
			newSNumber = resDiv;
		}
	}
	else		
		res=res+(newSNumber-0-resDiv*rSystem);  		
	res+=resDiv;
	var totalResult = "";
	var length =  res.length;
	
	for(i=length-1;i>=0;--i)
			 totalResult+=res.substring(i,i+1);
	return totalResult;	
}

Для дробных чисел целая часть считается функциями описанными выше. Дробная как-то так:

this.toDecD= function(sNumber,sSystem){
	var res = 0;
	var length = sNumber.length;
	for(i=0;i<length;++i)
	{
		 var b = sNumber.charCodeAt(i);

		if(b>57)
			res+=  ((b-55)*Math.pow(sSystem, -i-1));
		else
			res+= (sNumber.substring(i,i+1)*Math.pow(sSystem, -(i+1)));
	}
	
	return res;
}
 
this.fromDecD= function(sNumber, rSystem){
	var res = "";
	var accuracy = 10;
	var step = 0;

	while(step++<= accuracy)
	{
		sNumber = sNumber*rSystem;
		res+=""+parseInt(Math.floor(sNumber),rSystem);
		sNumber = sNumber - Math.floor(sNumber);
	}
	
	return res;
}

Кому интересно, можете глянуть исходник.

Конвертер чисел на Android

Если хотите установить себе программу для перевода чисел из одной системы счисления в другую на Android, то можете установить конвертер чисел. Ну, или QR Code:

QR Code Number Converter

  Категории: Android, JavaScript, Коддинг
  • Lida

    А точность?

    • http://suvitruf.ru Suvitruf

      В коде точность до 10 знаков после запятой поставил. Можно сколько угодно ставить) За счёт того, что вычисления ведутся поэтапно, можно, по сути, какую угодно точность задать (:
      var accuracy = 10;

  • Zhab

    Имеется неточность. Попробуйте,к примеру,перевести число 100.1 из 3-ной сс в 10-ную,а затем обратно

    • http://suvitruf.ru Suvitruf

      Это не неточность, а погрешность. В случае с дробями, перевести из одной с.с. в другую не всегда удаётся со 100% точностью.

      • Zhab

        Просто я имел честь видеть правильный ответ в другом онлайн калькуляторе,потому и решил предупредить(:

        • http://suvitruf.ru Suvitruf

          Там просто округление идёт(:
          9.33333 в 10 в троичной даст 100.02222222222… в 3 с.с.Погрешность на лицо.
          Но другие конвертеры просто округляют число.
          Это как для числа в 10 с.с. число 100,099999 можно округлить до 100,1.

          С точки зрения чистой математики у меня всё верно. Но с точки зрения интерфейса да, может и стоит округление реализовать.

  • Pingback: Взлом Epic Defense - the Elements: изменение значения золота | Suvitruf's Blog()

  • Павел

    4 294 967 296(Десятичная) – 100(Двоичная) -_-

    • http://suvitruf.ru Suvitruf

      4 294 967 296 (десятичная) = 100000000000000000000000000000000 (двоичная). Что не так?

  • Сталкер Петров

    Cпасибо, отличный конвертер, как раз такого не хватало)

    • http://suvitruf.ru Suvitruf

      Рад, что пригодилось )

  • Борис

    По-моему, ошибка: 0,99999 (10) -> 0,2(16). 0.fffff(16) -> 0.3(10). Кроме того, в дробной части мне не удалось ни разу увидеть букв

    • http://suvitruf.ru Suvitruf

      Да, была проблемка. Видимо, при бекапе старый скрипт залил. Поправил.

      • Борис

        Ошибку 0,99999 (10) -> (16) поправили, а 0.fffff(16) -> 0.3(10) осталась.

      • Борис

        Кажется, понял, если вводить 0.FFFFF, то нормально, а если 0.ffff, то ошибка

        • http://suvitruf.ru Suvitruf

          Регистр не смотрится, надо бы поправить )

    • Борис

      Ещё одну ошибку нашёл: 0.FFFFFFFFFFFFF (16) -> 0.99999999999 (10), но стоит добавить ещё одну F, как случается ошибка: 0.FFFFFFFFFFFFFF (16) -> 0.100000000000 (10)

      • http://suvitruf.ru Suvitruf

        Слишком много букв. Вы целыми днями сидите и тестируете? (:

      • Борис

        Ладно, не буду больше :)

  • Влад

    111010010100100000011111111001001111010010010101101001010
    перевод из 2 в 16:
    1D2903FC9E92B50, на конце должно быть 4A (по схеме быстрого перевода)
    Кстати, в таблице в столбиках 8 и 16 вместо цифры 4 стоят 5 и 6