マイナス2進数を求めるプログラムを書いてみた。
まず、2進数についてはこちらをどうぞ。
2進数、16進数と10進数 - CyberLibrarian
マイナス2進数というのは、基本的には同じです。
例えば、マイナス2進数の 1101 を10進数に直すと、
1*(-2)^3 + 1*(-2)^2 + 0*(-2)^1 + 1*(-2)^0
= -8 +4 +1 = -3
あれ、マイナスになってしまった。
んじゃ、次の例です。
マイナス2進数 11010 のときは、
1*(-2)^4 + 1*(-2)^3 + 0*(-2)^2 + 1*(-2)^1 + 0*(-2)^0
= 16 -8 -2 = 6
はい、11010が6です。
当然、11011は7になりますね。
0から30までのマイナス2進数を列挙すると、
0 : 0
1 : 1
2 : 110
3 : 111
4 : 100
5 : 101
6 : 11010
7 : 11011
8 : 11000
9 : 11001
10 : 11110
11 : 11111
12 : 11100
13 : 11101
14 : 10010
15 : 10011
16 : 10000
17 : 10001
18 : 10110
19 : 10111
20 : 10100
21 : 10101
22 : 1101010
23 : 1101011
24 : 1101000
25 : 1101001
26 : 1101110
27 : 1101111
28 : 1101100
29 : 1101101
30 : 1100010
このような数字になります。
マイナス2進数から10進数にするのは簡単です。
10進数からマイナス2進数にするのが少々厄介です。
通常の2進数のような計算方法では10進からマイナス2進数を求めることは出来ない?
出来るなら誰か教えてくだしあ。
/************************************* 正の10進数からマイナス2進数を求めるプログラム ************************************/ #include <stdio.h> long long POW(int a, int b) { int i; long long ret = 1; for( i=0; i<b; i++)ret *= a; return ret; } char* decMinus2bin(char* str, int N) { int u,k; long long i,j,sum; static const long long oddsum[]={ 2LL, 10LL, 42LL, 170LL, 682LL, 2730LL, 10922LL, 43690LL, 174762LL, 699050LL, 2796202LL, 11184810LL, 44739242LL, 178956970LL, 715827882LL, 2863311530LL }; static const long long evensum[]={ 1LL, 5LL, 21LL, 85LL, 341LL, 1365LL, 5461LL, 21845LL, 87381LL, 349525LL, 1398101LL, 5592405LL, 22369621LL, 89478485LL, 357913941LL, 1431655765LL }; if( N<0 )return NULL; if( N==0 ){ str[0] = '0', str[1] = 0; return str; } for(u=0; evensum[u] < N; u++); j = (1LL<<(2*u)); sum = j; do{ if( sum<N ){ for(u=0; sum+evensum[u] < N ; u++); j = j + (1LL<<(2*u)); }else if( sum>N ){ for(u=0; sum-oddsum[u] > N; u++); j = j + (1LL<<(2*u+1)); } sum = 0; for(i=1,k=0; i<=j; i<<=1,k++){ if( j&i ) sum += POW(-2,k); } }while( sum!=N ); str[k] = 0; for(i=1; i<=j; i<<=1){ str[--k] = j&i ? '1' : '0'; } return str; } int main() { char str[34]; int i; /*** Sample ***/ for(i=0; i<=30; i++){ printf("%d : %s\n",i,decMinus2bin(str,i)); } printf("%d : %s\n",-1405737207,decMinus2bin(str,-1405737207)); printf("%d : %s\n",2147483647,decMinus2bin(str,2147483647)); /**************/ return 0; }
追記:
main関数内の char str[33] ---> char str[34] に修正。
某社に提出した後に気付く、あとの祭り\(^o^)/
なんでセグメンが起きてくれなかったんだよorz、手元だと[33]でも普通に動いちゃうよ…。