在一个数字内填写三个数字

时间:2016-09-16 14:25:26

标签: math arduino numbers protocols

我想在1个数字中输入3个数字。但是数字只会在0到11之间。因此他们(基数)是12.例如我有7,5,2个数字。我想出这样的东西:

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 ??? 

3 个答案:

答案 0 :(得分: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向左移位n个位中的每一位,这相当于乘以2 ^ n。同样,a >> n向右移动。一个例子:

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

&运算符按位和两个操作数执行:

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

这两个运营商合并为&#34; pack&#34;和&#34;解包&#34;三个数字。对于包装,每个小数字都向左移动一点,它们都被加在一起。这就是big现在看起来的位置(其中有16个因为Arduino中的整数是16位宽):

    0000aaaabbbbcccc

解包时,这些位再次向右移动,它们与15一起按位,以滤除任何多余的位。这就是最后一次操作看起来再次出局的原因:

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

答案 1 :(得分: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位,从而节省一个字节。不使用base 12的easyer方法将每个数字拟合为半个字节(更好的代码效率和相同的传输长度):

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

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

因为MOD(12)和除以12的效率远低于使用2的幂

答案 2 :(得分:0)

你可以使用http://oi68.tinypic.com/j79fer.jpg的原则来改变任何基础

中的一个或另一个

将您的数字(n0,n1,...,nm)视为您所选基数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^mN mod B给你n0,然后减去它,留下你n1*B^1 + ... + nm*B^m并除以B以减少所有B的指数,这就是新的N ,N = n1*B^0 + ... + nm*B^(m-1)重复这一点,为您提供所有以

开头的数字

这是python中的一个工作示例

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]
>>>