我正在尝试将数字存储在4个整数的数组中。该数组在类Num
中。我的问题是,当我调用getValue
时,该函数返回的数字不正确。我尝试在纸上浏览该程序,并使用Microsoft的计算器进行所有计算,该程序应提供正确的输出。我什至不知道哪个功能可能有问题,因为没有任何错误或警告,并且两者都可以在纸上工作。
21(二进制):10101
我要做什么:
输入setValue
函数:21
setValue
将21
(0101
)的前四位放入num[3]
中。因此num[3]
现在是二进制的0101
。然后,应将21
的后四位放入num[2]
中。接下来的四位是0001
,因此0001
进入num[2]
其余的位是0,因此我们忽略它们。现在num
是{0,0,1,5}
。 getValue
首先进入num[3]
。 5
是二进制文件0101
。因此,它将其放入返回值的前四位。然后将0001
放入接下来的四位。其余数字为0
,因此应该忽略它们。然后,直接输出函数getValue
的输出。实际输出在底部。
我的代码:
#include <iostream>
class Num {
char len = 4;
int num[4];
public:
void setValue(int);
int getValue();
};
void Num::setValue(int toSet)
{
char len1=len-1;
for (int counter = len1;counter>=0;counter--)
{
if(toSet&(0xF<<(len1-counter))!=0)
{
num[counter]=(toSet&(0xF<<(len1-counter)))>>len1-counter;
} else {
break;
}
}
}
int Num::getValue()
{
char len1 = len-1;
int returnValue = 0;
for(char counter = len1; counter>=0;counter--)
{
if (num[counter]!=0) {
returnValue+=(num[counter]<<(len1-counter));
} else {
break;
}
}
return returnValue;
}
int main()
{
int x=260;
Num number;
while (x>0)
{
number.setValue(x);
std::cout<<x<<"Test: "<<number.getValue()<<std::endl;
x--;
}
std::cin>>x;
return 0;
}
输出:
260Test: -1748023676
259Test: 5
258Test: 5
257Test: 1
256Test: 1
255Test: 225
254Test: 225
253Test: 221
252Test: 221
251Test: 213
250Test: 213
249Test: 209
248Test: 209
247Test: 193
246Test: 193
245Test: 189
244Test: 189
243Test: 181
242Test: 181
241Test: 177
240Test: 177
239Test: 177
238Test: 177
237Test: 173
236Test: 173
235Test: 165
234Test: 165
233Test: 161
232Test: 161
231Test: 145
230Test: 145
229Test: 141
228Test: 141
227Test: 133
226Test: 133
225Test: 1
224Test: 1
223Test: 161
222Test: 161
221Test: 157
220Test: 157
219Test: 149
218Test: 149
217Test: 145
216Test: 145
215Test: 129
214Test: 129
213Test: 125
212Test: 125
211Test: 117
210Test: 117
209Test: 113
208Test: 113
207Test: 113
206Test: 113
205Test: 109
204Test: 109
203Test: 101
202Test: 101
201Test: 97
200Test: 97
199Test: 81
198Test: 81
197Test: 77
196Test: 77
195Test: 5
194Test: 5
193Test: 1
192Test: 1
191Test: 161
190Test: 161
189Test: 157
188Test: 157
187Test: 149
186Test: 149
185Test: 145
184Test: 145
183Test: 129
182Test: 129
181Test: 125
180Test: 125
179Test: 117
178Test: 117
177Test: 113
176Test: 113
175Test: 113
174Test: 113
173Test: 109
172Test: 109
171Test: 101
170Test: 101
169Test: 97
168Test: 97
167Test: 81
166Test: 81
165Test: 77
164Test: 77
163Test: 69
162Test: 69
161Test: 1
160Test: 1
159Test: 97
158Test: 97
157Test: 93
156Test: 93
155Test: 85
154Test: 85
153Test: 81
152Test: 81
151Test: 65
150Test: 65
149Test: 61
148Test: 61
147Test: 53
146Test: 53
145Test: 49
144Test: 49
143Test: 49
142Test: 49
141Test: 45
140Test: 45
139Test: 37
138Test: 37
137Test: 33
136Test: 33
135Test: 17
134Test: 17
133Test: 13
132Test: 13
131Test: 5
130Test: 5
129Test: 1
128Test: 1
127Test: 225
126Test: 225
125Test: 221
124Test: 221
123Test: 213
122Test: 213
121Test: 209
120Test: 209
119Test: 193
118Test: 193
117Test: 189
116Test: 189
115Test: 181
114Test: 181
113Test: 177
112Test: 177
111Test: 177
110Test: 177
109Test: 173
108Test: 173
107Test: 165
106Test: 165
105Test: 161
104Test: 161
103Test: 145
102Test: 145
101Test: 141
100Test: 141
99Test: 133
98Test: 133
97Test: 1
96Test: 1
95Test: 161
94Test: 161
93Test: 157
92Test: 157
91Test: 149
90Test: 149
89Test: 145
88Test: 145
87Test: 129
86Test: 129
85Test: 125
84Test: 125
83Test: 117
82Test: 117
81Test: 113
80Test: 113
79Test: 113
78Test: 113
77Test: 109
76Test: 109
75Test: 101
74Test: 101
73Test: 97
72Test: 97
71Test: 81
70Test: 81
69Test: 77
68Test: 77
67Test: 5
66Test: 5
65Test: 1
64Test: 1
63Test: 161
62Test: 161
61Test: 157
60Test: 157
59Test: 149
58Test: 149
57Test: 145
56Test: 145
55Test: 129
54Test: 129
53Test: 125
52Test: 125
51Test: 117
50Test: 117
49Test: 113
48Test: 113
47Test: 113
46Test: 113
45Test: 109
44Test: 109
43Test: 101
42Test: 101
41Test: 97
40Test: 97
39Test: 81
38Test: 81
37Test: 77
36Test: 77
35Test: 69
34Test: 69
33Test: 1
32Test: 1
31Test: 97
30Test: 97
29Test: 93
28Test: 93
27Test: 85
26Test: 85
25Test: 81
24Test: 81
23Test: 65
22Test: 65
21Test: 61
20Test: 61
19Test: 53
18Test: 53
17Test: 49
16Test: 49
15Test: 49
14Test: 49
13Test: 45
12Test: 45
11Test: 37
10Test: 37
9Test: 33
8Test: 33
7Test: 17
6Test: 17
5Test: 13
4Test: 13
3Test: 5
2Test: 5
1Test: 1
我用g++ 6.3.0
和g++ a.cpp -o a.exe
的命令对此进行了编译
答案 0 :(得分:0)
使用-Wall
进行编译时,有许多警告:
orig.cpp: In member function ‘void Num::setValue(int)’:
orig.cpp:15:39: warning: suggest parentheses around comparison in operand of ‘&’ [-Wparentheses]
if(toSet&(0xF<<(len1-counter))!=0)
~~~~~~~~~~~~~~~~~~~~~^~~
orig.cpp:17:61: warning: suggest parentheses around ‘-’ inside ‘>>’ [-Wparentheses]
num[counter]=(toSet&(0xF<<(len1-counter)))>>len1-counter;
~~~~^~~~~~~~
orig.cpp: In member function ‘int Num::getValue()’:
orig.cpp:30:24: warning: array subscript has type ‘char’ [-Wchar-subscripts]
if (num[counter]!=0) {
^
orig.cpp:31:38: warning: array subscript has type ‘char’ [-Wchar-subscripts]
returnValue+=(num[counter]<<(len1-counter));
^
如果在更改之前打印num
的值,您会发现某些值可能非零(即它们未初始化),这会导致未定义的行为,并且可能会中断for
和getValue
中的setValue
循环。
所以改变:
int num[4];
进入:
int num[4] = { 0 };
这是一个修正了警告的清理版本:
#include <iostream>
class Num {
int len = 4;
int num[4] = { 0 };
public:
void setValue(int);
int getValue();
void showval();
};
void Num::setValue(int toSet)
{
int len1=len-1;
for (int counter = len1;counter>=0;counter--)
{
if ((toSet & (0xF << (len1-counter))) != 0)
{
num[counter] = (toSet & (0xF << (len1-counter))) >> (len1-counter);
} else {
break;
}
}
}
int Num::getValue()
{
int len1 = len-1;
int returnValue = 0;
for(int counter = len1; counter>=0;counter--)
{
if (num[counter]!=0) {
returnValue+=(num[counter]<<(len1-counter));
} else {
break;
}
}
return returnValue;
}
void Num::showval()
{
for (int i = 0; i < len; ++i)
std::cout << i << ": show: " << num[i] << "\n";
#if 0
for (int i = 0; i < len; ++i)
num[i] = 0;
#endif
}
int main()
{
int x=260;
Num number;
number.showval();
while (x>0)
{
number.setValue(x);
std::cout << x << " Test: " << number.getValue() << std::endl;
x--;
}
std::cin>>x;
return 0;
}
答案 1 :(得分:0)
要将数字细分为零,移位计数应为4的倍数。否则,将提取不排成一行的4位切片。
00010101 (21)
^^^^ first nibble
^^^^ second nibble
第二个半字节移位了4位,因此需要右移4,而不是1。
您可以将班次计数乘以4,但是有一种更简单的方法:仅将班次乘以4。例如:
for (int i = len - 1; i >= 0; i--) {
num[i] = toSet & 0xF;
toSet >>= 4;
}
然后,每次迭代都提取toSet
中的最低半字节,并将toSet
移至下一个半字节,从而成为最低半字节。
我没有放入break
,因此不应有一个。绝对不应该是您所拥有的break
类型,它会在数字中间有零时也停止循环(例如,在0x101中,中间的0会导致循环停止)。当数字的其余全部为零时,循环也不应停止,因为这样会在num
的其他条目中留下垃圾。
在第0个元素中存储最低的半字节是更常见的,依此类推(然后,您不必使用递减计数循环处理所有“逆逻辑”并从长度中减去东西),但这取决于你。
可以对称地提取值,在移动结果时累积结果,而不是立即将每一部分移到最终位置。或仅将(len1-counter)
乘以4。提取值时,num[i]
为零时也不能停止,因为这不能证明数字的其余部分也为零。