C/C++ 生成指定格式的32位資料
概述
可能看到這個標題,大家還是比較疑惑,不是很明白想表達什麼意思,不著急,接著往下看就知道了.
假定有這樣一個需求:
0-7 位這8個bit 儲存 整形變數count的值,那麼整形變數count的取值範圍可以是(0,255).
8-13位 這6個bit 儲存 整形變數second的值,那麼整形變數second的取值範圍是(0,63).
14-19位 6個bit 儲存 整形變數minute得值,取值範圍同上.
20-31位 這個12個bit 儲存整形變數hour的值,那麼其取值範圍是(0,4095).
同時現在我們是知道hour,minute,second,count這個四個變數的值的.
分析
我們來分析一下怎麼做,我們可以這樣,把這四個變數的值分別轉化成二進位制,然後用字元陣列存起來,就獲得了對應的4個二進位制陣列,然後再用memcpy函式,把這四個陣列按順序copy到一個新的數組裡不就行了嘛.
說幹就幹
首先我們先寫一個函式,專門用來進行整數型->二進位制陣列的轉換.這裡可以有多種演算法,大家可自行選擇實現.
char* getBinaryArray(unsigned long value,int length){ int len = length; int index = len - 1; char *binary = (char*)malloc(sizeof(char)*len); memset(binary,'0',sizeof(char)*len); int r_value; r_value = value%2; *(binary+index) = r_value==0?'0':'1'; int n = value/2; while(n>=2){ r_value = n%2; index--; *(binary+index) = r_value==0?'0':'1'; n = n/2; } r_value = n%2; index--; *(binary+index) = r_value==0?'0':'1'; return binary; }
上面函式第一個引數的型別,可以是int,long,unsigned int ,第二個引數表示生成陣列的長度.
我們來測試一下,這個函式有沒有達到我們的要求.
#include <time.h> #include <iostream> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <math.h> using namespace std; int main(){ char* getBinaryArray(unsigned long value,int length); printf("size = %ld",sizeof(unsigned long)); printf("\n"); char* d = getBinaryArray(8,12); for(int i=0;i<12;i++){ printf("d[%d] = %c -- ",i,*(d+i)); } printf("\n"); } char* getBinaryArray(unsigned long value,int length){ int len = length; int index = len - 1; char* binary = (char*)malloc(sizeof(char)*len); memset(binary,'0',sizeof(char)*len); int r_value; r_value = value%2; *(binary+index) = r_value==0?'0':'1'; int n = value/2; while(n>=2){ r_value = n%2; index--; *(binary+index) = r_value==0?'0':'1'; n = n/2; } r_value = n%2; index--; *(binary+index) = r_value==0?'0':'1'; return binary; }
命令列編譯執行一下:
g+±4.8 -o getbinaryarraytest.out GetBinaryArrayTest.cpp
./getbinaryarraytest.out
結果如下:
size = 8
d[0] = 0 – d[1] = 0 – d[2] = 0 – d[3] = 0 – d[4] = 0 – d[5] = 0 – d[6] = 0 – d[7] = 0 – d[8] = 1 – d[9] = 0 – d[10] = 0 – d[11] = 0 –
這邊因為我的裝置是64位的,所以unsigned long型是8個位元組,重點的是下面的輸出結果.
000000001000
結果是我們想要的,沒毛病.利用這個方法我們就可以得到其他幾個值的二進位制表示.
然後我們再利用memcpy函式把這幾個二進位制表示拼接起來就可以了.程式碼如下:
1 #include <time.h>
2 #include <iostream>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <sstream>
7 #include <math.h>
8 using namespace std;
9
10 int main(){
11
12 char* getBinaryArray(unsigned long value,int length);
13 printf("\n");
14 printf("\n");
15 char* d = getBinaryArray(8,12);
16 for(int i=0;i<12;i++){
17 printf("d[%d] = %c -- ",i,*(d+i));
18 }
19 printf("\n");
20 char* e = getBinaryArray(12,6);
21 for(int i=0;i<6;i++){
22 printf("e[%d] = %c -- ",i,*(e+i));
23 }
24 printf("\n");
25 char* f = getBinaryArray(33,6);
26 for(int i=0;i<6;i++){
27 printf("f[%d] = %c -- ",i,*(f+i));
28 }
29 printf("\n");
30 char* g = getBinaryArray(28,8);
31 for(int i=0;i<8;i++){
32 printf("g[%d] = %c -- ",i,*(g+i));
33 }
34 printf("\n");
35 char* kk=(char*)malloc(sizeof(char)*32);
36 int hl=sizeof(char)*12;
37 int ml = sizeof(char)*6;
38 int sl = sizeof(char)*6;
39 int fl = sizeof(char)*8;
40 memcpy(kk,d,hl);
41 memcpy(kk+hl,e,ml);
42 memcpy(kk+hl+ml,f,sl);
43 memcpy(kk+hl+ml+sl,g,fl);
44
45 for(int i=0;i<32;i++){
46 printf(" %c ",*(kk+i));
47 }
48
49 unsigned long sum = 0;
50 for(int i=0;i<32;i++){
51 if(*(kk+i) == '1'){
52 sum = sum + 1*(long)pow(2,31-i);
53 }
54 }
55 printf("\n");
56 printf("sum=%ld",sum);
57 return 0;
58 }
59
60 char* getBinaryArray(unsigned long value,int length){
61 int len = length;
62 int index = len - 1;
63 char* binary = (char*)malloc(sizeof(char)*len);
64 memset(binary,'0',sizeof(char)*len);
65 int r_value;
66 r_value = value%2;
67 *(binary+index) = r_value==0?'0':'1';
68 int n = value/2;
69 while(n>=2){
70 r_value = n%2;
71 index--;
72 *(binary+index) = r_value==0?'0':'1';
73 n = n/2;
74 }
75 r_value = n%2;
76 index--;
77 *(binary+index) = r_value==0?'0':'1';
78 return binary;
79 }
編譯執行後結果如下:
d[0] = 0 – d[1] = 0 – d[2] = 0 – d[3] = 0 – d[4] = 0 – d[5] = 0 – d[6] = 0 – d[7] = 0 – d[8] = 1 – d[9] = 0 – d[10] = 0 – d[11] = 0 –
e[0] = 0 – e[1] = 0 – e[2] = 1 – e[3] = 1 – e[4] = 0 – e[5] = 0 –
f[0] = 1 – f[1] = 0 – f[2] = 0 – f[3] = 0 – f[4] = 0 – f[5] = 1 –
g[0] = 0 – g[1] = 0 – g[2] = 0 – g[3] = 1 – g[4] = 1 – g[5] = 1 – g[6] = 0 – g[7] = 0 –
0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 0 0 0 1 0 0 0 1 1 1 0 0
sum=8593692
上面加粗的結果就是最終的,我們想要的二進位制表示,它的十進位制表示值是8593692.
上面的方法,確實實現了我們的需求,但是吧,這也太麻煩了吧.首先,需要把整型值轉化成二進位制表示,並用char 陣列存起來,然後在記憶體拷貝進行拼接,最後如果想得到十進位制的結果還需要再轉化一下…比較麻煩,那能不能有簡單點的方法呢? 我們可以用位操作運算來實現. 程式碼如下:
1 #include<iostream>
2 #include<stdio.h>
3 int main(){
4 unsigned int value = 0;
5 unsigned int count = 28;
6 unsigned int second = 33;
7 unsigned int minute = 12;
8 unsigned int hour = 8;
9 //從低位到高位
10 //set count
11 value = 0 | count;
12 //set second
13 value = value | (second << 8);
14 //set minute
15 value = value | (minute << 14);
16 //set hour
17 value = value | (hour << 20);
18 printf("%d",value);
19 }
編譯執行結果如下:
8593692
結果和上面的一樣,但是思路完全不一樣,程式碼量是不是少很多.通過這種方式,如果後端要求怎麼控制32位的格式或者64位,我們都可以很方便的做到.
掃碼加入我的個人微信公眾號:Android開發圈 ,一起學習Android知識!!