2016-09-16 6 views
-1

Я пытаюсь поместить 3 числа внутри 1 числа. Но числа будут только между 0 и 11. Так что их (база) равна 12. Например, у меня есть 7,5,2 числа. I придумайте что-то вроде этого:Заполните три числа внутри одного номера

Three numbers into One number : 
7x12=84 
84x5=420 
420+2=422 

Now getting back Three numbers from One number : 
422 MOD 12 = 2 (the third number) 
422 - 2 = 420 
420/12 = 35 
And i understanded that 35 is multiplication of first and the second number (i.e 7 and 5) 
And now i cant get that 7 and 5 anyone knows how could i ??? 
+1

Это выглядит подозрительно, как бессмысленное задание на домашнюю работу. Зачем вам это нужно? – Missy

+0

Возможно, вам повезет больше на math.stackexchange.com – CoconutBandit

+0

Я буду отвечать «Зачем вам это нужно?» Вы можете просто использовать базу 16, так как тогда она жестко закодирована практически в каждом языке программирования. И если это не связано с программированием, то это, вероятно, вне темы. – Teepeemm

ответ

1

(я начал набирать этот ответ до того, как другой был размещен, но это один более специфичен для Arduino, то другой один, так что я «м оставить его)

код

Вы можете использовать немного сдвигая, чтобы получить несколько небольших чисел в одно большое число, в коде будет выглядеть следующим образом:

int a, b, c; 

//putting then together 
int big = (a << 8) + (b << 4) + c; 

//separating them again 
a = (big >> 8) & 15; 
b = (big >> 4) & 15; 
c = big & 15; 

Этот код работает только в том случае, если a, b и c находятся в диапазоне [0, 15]. Кажется, что для вас достаточно колдовства.

Как это работает

В >> и << операторы операторы Bitshift, в коротких a << n сдвигов каждый бит в по п местах влево, это эквивалентно умножению на 2^п. Аналогично, a >> n сдвигается вправо.Пример:

11 << 3 == 120 //0000 1011 -> 0101 1000 

Оператор & выполняет побитовое и на двух операндов:

6 & 5 == 4  // 0110 
       // & 0101 
       //-> 0100 

Эти два оператора объединены в «пакет» и «распаковать» три числа. Для упаковки каждое небольшое число сдвигается немного влево, и все они складываются вместе. Это как биты big выглядеть (есть 16 из них, потому что Интс в Arduino 16 бита):

0000aaaabbbbcccc 

При распаковке, биты сдвигаются вправо снова, и они побитовое операции AND вместе с 15 для фильтрации любых лишних бит. Это то, что последняя операция выглядит так, чтобы снова получить b:

00000000aaaabbbb //big shifted 4 bits to the right 
    & 0000000000001111 //anded together with 15 
-> 000000000000bbbb //gives the original number b 
+1

Спасибо, действительно хорошее объяснение, я просто думаю, что должно быть 15, где бы вы ни использовали 16, правильно ? Кроме того, поскольку я отправляю число по nrf, он может использовать только 8 бит int (байт), но я думаю, что невозможно поставить 3 числа 0-15 в 1 байт. –

+0

Да, это должно быть 15 везде, отредактировано это. Три числа, каждый в диапазоне 0-15, должны иметь по меньшей мере 12 бит, когда они имеют значение 0-11, им требуется не менее 11 бит. Так что нет, вы не сможете упаковать их в один байт. В то же время принятый ответ не будет работать. –

+0

Проблема в том, что я не могу принять 2 ответа. Оба ваших ответа полезны. Не решайте мою конкретную проблему, но очень полезны. И я не могу голосовать, потому что у меня нет репутации 15. –

0

Все работает точно так же, как в основании 10 (или 16). Вот после вашего исправленного примера.

Three numbers into One number : 
7x12^2=1008 
5*12^1=60 
2*12^0=2 
1008+60+2=1070 

Now getting back Three numbers from One number : 
1070 MOD 12 = 2 (the third number) 
1070/12 = 89 (integer division) => 89 MOD 12 = 5 
89/12 = 7 

Следует также отметить, что максимальное значение будет 11 * 12 * 12 + 11 * 12 + 11 = +1727.

Если это действительно связано с программированием, вы будете использовать 16 бит вместо 3 * 8 бит, поэтому экономьте один байт. Метод easyer не используется основание 12 будет соответствовать каждое число в половину байта (эффективность лучше кода и той же длины передачи):

7<<(4+4) + 5<<4 + 2 = 1874 

1874 & 0x000F = 2 
1874>>4 & 0x000F = 5 
1874>>8 & 0x0F = 7 

Поскольку MOD (12) и деление на 12, гораздо менее эффективны, чем работа с полномочиями 2

+0

Спасибо, это действительно полезно :) –

0

вы можете использовать принцип positional notation для перехода от одного или другого в любой базе

Treat Yours числа (n0, n1, ..., нм) в виде цифры большого числа в база B по вашему выбору, поэтому новый номер

N = n0*B^0 + n1*B^1 + ... + nm*B^m 

, чтобы вернуть процесс, также прост, в то время как ваш номер больше 0, найдите его по модулю относительно базы, чтобы получить первую цифру, затем вычитает эту цифру и разделите ее на базу, повторите до конца, сохраняя каждая цифра по пути

digit_list = [] 
while N > 0 do: 
    d = N mod B 
    N = (N - d)/B 
    digit_list.append(d) 

затем, если N является N = n0*B^0 + n1*B^1 + ... + nm*B^m делать N mod B дать вам n0, а затем вычесть его оставив вас с n1*B^1 + ... + nm*B^m и разделите на B, чтобы уменьшить показатели всех B и является новым N, N = n1*B^0 + ... + nm*B^(m-1) повторения из которого вы получите всю цифру, начинающуюся с

здесь рабочий пример в питоне

def compact_num(num_list, base=12): 
    return sum(n*pow(base,i) for i,n in enumerate(num_list)) 

def decompact_num(n, base=12): 
    if n==0: 
     return [0] 
    result = [] 
    while n: 
     n,d = divmod(n,base) 
     result.append(d) 
    return result 

пример

>>> compact_num([2,5,7]) 
1070 
>>> decompact_num(1070) 
[2, 5, 7] 
>>> compact_num([10,2],16) 
42 
>>> decompact_num(42,16) 
[10, 2] 
>>> 
+0

Спасибо и хороший код :) –

Смежные вопросы