数组初始化为所有元素为零,吐出随机数
Array initialised with all elements as zero is spitting out random numbers
因此,对于我的作业,我必须创建一个适用于长度不超过 256 个字符的大整数的计算器。我目前要做的作业部分是在从较小的数字开始后让它处理较大的数字。我有一个充满数字的数组,并且在我所有的测试中都可以很好地处理 10 个数字。我将 DIGITS 的值从 256 更改为 10,在得到奇怪的数字时,我用一些 cout 进行了调查,结果发现如果我添加 00000 + 00000(可以是任何大小的数字或任何数字,我选择了这些,因为它很容易筛选,因为所有数组元素中的所有内容都应该为零(我得到一个非常奇怪的答案
(2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180000000000000020000000000000002000000000000000000000000000000000000000000000000000(。
我检查了每个数组元素,其中一些元素将填充一个随机数。我的数组初始化为
digits_[DIGITS] = { 0 };
还尝试了 for 循环将数组元素设置为零,结果相同。
DIGITS 在头文件中设置为 256
我注意到的一个模式是,在两个数组中,n1 和 n2 应该是两个不同的数字被添加或减去等,在该特定元素上填充相同的数字。因此,由于某种原因,n1[81] 和 n2[81] 都将设置为 9。但是,每次编译和运行程序时,这种情况都会更改。
下面的完整代码(方法中的couts只是为了让我评估数组中的这些错误(
#include <iostream>
#include <string>
#include "Bigint.h"
using namespace std;
Bigint::Bigint()
{
digits_[DIGITS] = { 0 };
}
ostream& operator<< (ostream& out, const Bigint& n)
{
string s = "";
bool found = false;
for (int i = DIGITS - 1; i >= 0; --i) {
if(n.digits_[i] > 0) {
found = true;
}
if(n.digits_[i] != 0 || found == true) {
s += char(n.digits_[i] + '0');
}
}
if (s == "") {
s = "0";
}
return out << s;
}
istream& operator>> (istream& in, Bigint& n)
{
string s;
if (in >> s) {
for (int i = 0; i < DIGITS; ++i) {
n.digits_[i] = s[s.length() - 1 - i] - '0';
}
}
return in;
}
Bigint operator+ (const Bigint& n1, const Bigint& n2)
{
Bigint ret;
int cur_carry = 0;
for(int i = 0; i < DIGITS; ++i) {
int n1_digit = n1.get(i);
int n2_digit = n2.get(i);
if(n1_digit < 0 || n1_digit > 9) {
n1_digit = 0;
}
if(n2_digit < 0 || n2_digit > 9) {
n2_digit = 0;
}
printf("n1 : %dn", n1_digit);
printf("n2 : %dn", n2_digit);
int sum = n1_digit + n2_digit + cur_carry;
cout << "sum : " << sum << endl;
cur_carry = Bigint::getCarry(sum);
cout << "new carry : " << cur_carry << endl;
ret.set(i, Bigint::getDigitValue(sum));
cout << "Set : " << i << "," << Bigint::getDigitValue(sum) << endl;
}
return ret;
}
Bigint operator- (const Bigint& n1, const Bigint& n2)
{
Bigint ret;
//Should only ever have a max value of 1, used to borrow values from next digit column of bigint
int borrowed = 0;
//Stores final value to subtract from
int temp;
for(int i = 0; i < DIGITS; --i) {
int n1_digit = n1.get(i);
int n2_digit = n2.get(i);
if(n1_digit < 0 || n1_digit > 9) {
n1_digit = 0;
}
if(n2_digit < 0 || n2_digit > 9) {
n2_digit = 0;
}
//Ensure we take into account borrowed values from previous digit subtractions
temp = n1_digit - borrowed;
//Reset borrowed
borrowed = 0;
//If n1 digit value < n2 digit value we need to borrow a 10 from next digit column
if(temp < n2_digit) {
//Borrow 10 and increment borrowed for next computation
temp = n1_digit + 10;
borrowed++;
}
//Store value
ret.set(i, temp - n2_digit);
}
return ret;
}
Bigint operator* (const Bigint& n1, const Bigint& n2)
{
return n1; // Only correct when n2 equals 1.
}
Bigint operator/ (const Bigint& n1, const Bigint& n2)
{
return n1; // Only correct when n2 equals 1.
}
int Bigint::get(int pos) const {
int ret = digits_[pos];
return ret;
}
void Bigint::set(int pos, int val) {
this->digits_[pos] = val;
}
int Bigint::getCarry(int val) {
return val/10;
}
int Bigint::getDigitValue(int val) {
return val % 10;
}
头文件:
#ifndef BIGINT_H_
#define BIGINT_H_
#define DIGITS 256
class Bigint
{
public:
/**
* Creates a Bigint initialised to 0.
*/
Bigint();
/**
* Inserts n into stream or extracts n from stream.
*/
friend std::ostream& operator<< (std::ostream &out, const Bigint& n);
friend std::istream& operator>> (std::istream &in, Bigint& n);
/**
* Returns the sum, difference, product, or quotient of n1 and n2.
*/
friend Bigint operator+ (const Bigint& n1, const Bigint& n2);
friend Bigint operator- (const Bigint& n1, const Bigint& n2);
friend Bigint operator* (const Bigint& n1, const Bigint& n2);
friend Bigint operator/ (const Bigint& n1, const Bigint& n2);
int get(int pos) const;
void set(int pos, int val);
static int getCarry(int val);
static int getDigitValue(int val);
private:
int digits_[DIGITS];
};
#endif // BIGINT_H_
主.cpp
#include <iostream>
#include "Bigint.h"
using namespace std;
int main(int argc, char *argv[])
{
Bigint n1, n2;
char op;
while (cin >> n1 >> op >> n2) {
switch (op) {
case '+' :
cout << n1 + n2 << endl;
break;
case '-' :
cout << n1 - n2 << endl;
break;
case '*' :
cout << n1 * n2 << endl;
break;
case '/' :
cout << n1 / n2 << endl;
break;
}
}
return 0;
}
问题出在您的构造函数中:
Bigint::Bigint()
{
digits_[DIGITS] = { 0 };
}
此处digits_[DIGITS] = { 0 };
的语法并未将digits_
的所有元素初始化为0
。它访问第DIGITS
个元素(一个超过末尾 - 这是索引越界(并设置它0
.这是未定义的行为,并且程序可以以任何方式表现出行为 - 预期或意外。
修复非常简单。同样的语法(digits_[DIGITS] = { 0 };
(可以用来初始化所有要0
的元素,但它必须在声明中使用。因此,为了解决此问题,您必须:
- 摆脱上面的构造函数
- 将头文件中的
int digits_[DIGITS];
替换为int digits_[DIGITS] = {0};
。
编辑:
看来您有另一个错误 - 在您的operator >>
中.该行:
n.digits_[i] = s[s.length() - 1 - i] - '0';
还调用未定义的行为,除非s
的length()
正好DIGITS
。输入00000
时,s.length() == 5
。现在,您的i
范围是从0
到DIGITS
(255
(。比方说,i == 100
时会发生什么?执行以下内容:
n.digits_[100] = s[-96] - '0';
这不是我们想要的。您需要为此添加一个警卫。例如:
n.digits_[i] = i < s.length() ? s[s.length() - 1 - i] - '0' : 0;
- Mongodb c++驱动程序:如何查询元素的数组
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 整数不会重复超过随机数
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 如何在C中检查随机数列表中的元素
- 如何在随机数列表中查找大于或小于的元素
- 数组初始化为所有元素为零,吐出随机数
- 如何检查所有随机数组元素是否不同
- 我将如何打印随机数组元素
- 为数组元素生成随机数
- 如何生成不会产生超过 X 个连续元素的随机数序列