Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Перевод числа в симметричную систему счисления


Автор: ТарасАтавин 29.8.2013, 09:10
Например, в симметричную троичную. Просто в тоичную не проблема: собрать остатки от деления на основание и всё. А в симметричную как? Там цифры -1, 0 и +1, остаток же отрицательным не бывает. Да и деление переводимого числа не очень помогает: например, число 55 в троичной систем будет 2001, а в симметричной троичной  +-00+, что на один знак длиннее.

Автор: bsa 29.8.2013, 18:16
Цитата(ТарасАтавин @  29.8.2013,  10:10 Найти цитируемый пост)
число 55 в троичной систем будет 2001, а в симметричной троичной  +-00+, что на один знак длиннее. 

На сколько я понял, надо штатно перевести в троичную, затем поменять 2 на - и 1 на +:
http://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%BE%D0%B8%D1%87%D0%BD%D0%B0%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F#.D0.9F.D0.B5.D1.80.D0.B5.D0.B2.D0.BE.D0.B4_.D1.87.D0.B8.D1.81.D0.B5.D0.BB_.D0.B8.D0.B7_.D0.B4.D0.B5.D1.81.D1.8F.D1.82.D0.B8.D1.87.D0.BD.D0.BE.D0.B9_.D1.81.D0.B8.D1.81.D1.82.D0.B5.D0.BC.D1.8B_.D0.B2_.D1.82.D1.80.D0.BE.D0.B8.D1.87.D0.BD.D1.83.D1.8E

Автор: ТарасАтавин 29.8.2013, 18:35
Цитата(bsa @  29.8.2013,  18:16 Найти цитируемый пост)
На сколько я понял, надо штатно перевести в троичную, затем поменять 2 на - и 1 на +:
Нет. Простая подмена символа не меняет систему счисления. В троичной асимметричной 55 десятичное соответствует четырёхзначному числу, а в симметричной троичной пятизначному. Замена не увеличивает разрядность. И если даже менять, то 55 десятичное = 2001 троичное = -00+, а это вообще отрицательное число -26 (минус двадцать шесть).

Автор: feodorv 29.8.2013, 22:54
Для положительных чисел. Делите число на 3. Если остаток от деления равен 0 или 1, то это 0 или + в симметричной троичной системе счисления. Если же остаток - двойка, то результат деления увеличиваете на единицу, а в соответствующий разряд пишете -. Например: 56(10) = 18[*3] + 2 = 19[*3] + "-" = 6[*3*3] + "+-" = 2[*3*3*3] + "0+-" = 1[*3*3*3*3] + "-0+-" = "+-0+-".

Для отрицательных чисел. Обращаем знак числа, получаем положительное число, которое уже раскладывать умеете. А затем меняете знаки на противоположные.

Как-то так...

Автор: ТарасАтавин 30.8.2013, 04:54
Перенос в частное при двойке? Это всегда даст правильный результат? А если в симметричную пятеричную? Тогда перенос единицы в частное при получении тройки и четвёрки, так как в этой системе нет уже двух цифр асимметричной системы с равным основанием?

Автор: feodorv 30.8.2013, 10:09
Цитата(ТарасАтавин @  30.8.2013,  05:54 Найти цитируемый пост)
Это всегда даст правильный результат?

Ну а как Вы думаете?

Цитата(ТарасАтавин @  30.8.2013,  05:54 Найти цитируемый пост)
Тогда перенос единицы в частное при получении тройки и четвёрки

Да. Только 3 в остатке заменяется на "двойной минус", а 4  - на "одинарный минус":
Код

#include <stdio.h>

void toBase( int num, int base, const char *syms)
{
  char buf[128], rbuf[128];
  int orig = num, negative, n = 0, i;

  if( num < 0 )
  {
    negative = 1;
    num = -num;
  }
  else
    negative = 0;

  if( num == 0 )
    buf[n++] = syms[0];
  else
    while( num != 0 )
    {
      int rem = num % base;
      num /= base;

      if( rem > base/2 ) num++;
      if( negative && rem > 0 ) rem = base - rem;

      buf[n++] = syms[rem];
    }

  for( i = 0; i < n; i++) rbuf[i] = buf[n-i-1];
  rbuf[n] = '\0';

  printf( "%d(%d) = %s\n", orig, base, rbuf);
}

#define BASE3 3
const char *syms3 = "0+-";

#define BASE5 5
const char *syms5 = "0+#=-";

int main( void )
{
  int num;
  for( num = -100; num <= 100; num++) toBase( num, BASE3, syms3);
  for( num = -100; num <= 100; num++) toBase( num, BASE5, syms5);
  return 0;
}

Автор: Walterfew 24.1.2023, 18:24
Модератор: Сообщение скрыто.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)