数组初始化为所有元素为零,吐出随机数

Array initialised with all elements as zero is spitting out random numbers

本文关键字:随机数 元素 初始化 数组      更新时间:2023-10-16

因此,对于我的作业,我必须创建一个适用于长度不超过 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的元素,但它必须在声明中使用。因此,为了解决此问题,您必须:

  1. 摆脱上面的构造函数
  2. 头文件中int digits_[DIGITS];替换为int digits_[DIGITS] = {0};

编辑

看来您有另一个错误 - 在您的operator >>中.该行:

n.digits_[i] = s[s.length() - 1 - i] - '0';

还调用未定义的行为,除非slength()正好DIGITS。输入00000时,s.length() == 5。现在,您的i范围是从0DIGITS(255(。比方说,i == 100时会发生什么?执行以下内容:

n.digits_[100] = s[-96] - '0';

这不是我们想要的。您需要为此添加一个警卫。例如:

n.digits_[i] = i < s.length() ? s[s.length() - 1 - i] - '0' : 0;