Member 13041326 Ответов: 2

Реализация класса bignumber


Я пытаюсь реализовать класс BigNumber, который хранит неотрицательные целые числа с числом до 1000 цифр, хранящихся в виде элемента массива в обратном порядке.

Следующая программа имеет странную проблему. Второе число (m) имеет дополненные 0 в конце.

напр.


1234

4567000000000000000000000000000000000000

число не равно нулю
n меньше m
n не больше, чем равно m
n меньше, чем равно m
n не равно m
n не равно m
Программа завершилась кодом выхода: 0
Не могу понять почему

Что я уже пробовал:

#include<iostream>
#include<fstream>
using namespace std;
 
class BigNumber
{
    friend ostream &operator<<(ostream &, const BigNumber &); // stream insertion operator
    // output the number as we would normally read it e.g. output 17 means the number seventeen.
private:
    char digits[100]; // to hold the digits with digits[i] representing the 10^i's place.
    int numDigits; // number of digits in the number, e.g 5 has one digit but 45 has two. ZERO should have zero digits
public:
    BigNumber(int value = 0); // default constructor.
    
    int getNumDigits() const; // return numDigits
    bool isZero() const; // return true iff *this is equal to ZERO
    bool operator< (const BigNumber & c) const; // less than
    bool operator>= (const BigNumber & c) const; // greather than or equal
    bool operator<= (const BigNumber & c) const; // less than or equal
    bool operator== (const BigNumber & c) const; // equal
    bool operator!= (const BigNumber & c) const; // not equal
    BigNumber & operator++(); //preincremental
    BigNumber operator++(int dummy);//postincremental
    BigNumber operator+(const BigNumber & c) const; //plus
    BigNumber& operator+=(const BigNumber & c) const; //plus equals
    BigNumber& operator* (const BigNumber &c) const; //times
    BigNumber& operator*=(const BigNumber &c); //times equal
};
 
//BigNumber.cpp
 
//#include "BigNumber.h"
 
BigNumber::BigNumber(int val)
{
    numDigits = 0;
    int i = 0,rem;
    char str[100];
    
    do
    {
        rem = val % 10;
        str[i++] = rem;
        
    } while ((val = val / 10));
    //reverse the string str ans assign to digits array
    for (int j = 0,k = i-1; j < i; j++)
    {
        digits[j] = str[k--];
    }
    i = 0;
    while ((int)digits[i] >= 0)
    {
        ++i;
    }
    numDigits = i;
}
 
int BigNumber::getNumDigits() const
{
    cout << numDigits;
    return numDigits;
}
 
bool BigNumber::isZero() const
{
    if (numDigits == 0)
        return true;
    else
        return false;
}
 
bool BigNumber::operator< (const BigNumber & c) const
{
    if (numDigits < c.numDigits)
        return true;
    if ((int)digits[0] >= (int)c.digits[0])
        return false;
    for (int i = 1; i < numDigits; i++)
    {
        
        if ((int)digits[i] >=(int)c.digits[i])
            return false;
        continue;
    }
    return true;
}
 
bool BigNumber:: operator>= (const BigNumber & c) const
{
    if (numDigits < c.numDigits)
        return false;
    if ((int)digits[0] < (int)c.digits[0])
        return false;
    for (int i = 0; i < numDigits; i++)
    {
        if (digits[i] >= c.digits[i])
            continue;
        else
            return false;
    }
    return true;
}
 
bool BigNumber:: operator<= (const BigNumber & c) const
{
    if (numDigits > c.numDigits)
        return false;
    if ((int)digits[0] > (int)c.digits[0])
        return true;
    for (int i = 0; i < numDigits; i++)
    {
        if (digits[i] <= c.digits[i])
            continue;
        else
            return false;
    }
    return true;
}
 
bool BigNumber:: operator== (const BigNumber & c) const
{
    if (numDigits != c.numDigits )
        return false;
    for (int i = 0; i < numDigits; i++)
    {
        if (digits[i] != c.digits[i])
            return false;
    }
    return true;
}
 
bool BigNumber:: operator!= (const BigNumber & c) const
{
    if (numDigits != c.numDigits)
        return true;
    for (int i = 0; i < numDigits; i++)
    {
        if ( digits[i] !=c.digits[i] )
            return true;
    }
    return false;
}
 
ostream &operator<<(ostream &out, const BigNumber &Int)
{
    for (int i = 0; i < Int.numDigits; i++)
        out << (int)(Int.digits[i]);
    cout << endl;
    return out;
}
 
//main.cpp
 
//#include "BigNumber.h"
#include<iostream>
using namespace std;
 
int main()
{
    BigNumber n(1234);
    cout << n << endl;
    //getNumDigits();
    // (etc.)test operator overloading
    BigNumber m(4567);
    cout << m << endl;
    
    if (n.isZero())
    {
        cout << "number is zero" << endl;
    }
    else
    {
        cout << "number is not zero" << endl;
    }
    //test < operator
    if ( n < m )
    {
        cout << "n is less than m" << endl;
    }
    else
    {
        cout << "n is not less than m" << endl;
    }
    //test >= operator
    if (n >= m)
    {
        cout << "n is greater than equal to m" << endl;
    }
    else
    {
        cout << "n is not greater than equal to m" << endl;
    }
    //test <= operator
    if (n <= m)
    {
        cout << "n is less than equal to m" << endl;
    }
    else
    {
        cout << "n is not less than equal to m" << endl;
    }
    //test == operator
    if (n == m)
    {
        cout << "n is equal to m" << endl;
    }
    else
    {
        cout << "n is not equal to m" << endl;
    }
    
    //test != operator
    if (n != m)
    {
        cout << "n is not equal to m" << endl;
    }
    else
    {
        cout << "n is equal to m" << endl;
    }
    return 0;
}

[no name]

"Не могу понять почему", вы не можете понять что? Это потому, что n меньше m, не больше или равно, или любое другое ваше условие, которое в значительной степени самоочевидно.

Member 13041326

Мой вопрос таков

для первого вызова BigNumber n (1234)
Я понимаю, 1234, которая является правильной
но для второго звонка
BigNumber m (4567)

Я получаю

4567000000000000000000000000000000000000

Почему нули дополняются только моим вторым звонком, а не первым.
Когда я попытался использовать отладчик, для
цифры char[100];

Я получаю фактическое

digits = char [100] для первого вызова .
Но за второй звонок я получаю
цифры = char [100] " "

Patrice T

Воспользуйся Улучшить вопрос чтобы обновить ваш вопрос.
Чтобы каждый мог обратить внимание на эту информацию.

2 Ответов

Рейтинг:
20

Jochen Arndt

Проблема находится в вашем BigNumber::BigNumber(int val) конструктор:

i = 0;
while ((int)digits[i] >= 0)
{
    ++i;
}
numDigits = i;
Вы подсчитываете количество цифр, проверяя содержимое вашего digits массив. Но не все члены массива были инициализированы. Неиспользуемые члены имеют случайное содержимое, которое может быть больше или равно нулю. Вы должны инициализировать все члены перед тем, как убедиться, что неиспользуемые из них отрицательны:
memset(digits, 0xff, sizeof(digits));

Но есть и более простое решение. У вас уже есть номера цифр в вашем i переменная. Поэтому просто замените приведенный выше код на
/* Special case zero: i == 1 and array[0] == 0 */
if (i > 1 || digits[0] > 0)
    numDigits = i;
else
    numDigits = 0;
Обратите внимание, что вышеизложенное также правильно обрабатывает ноль, в то время как ваш код всегда будет установлен numDigits к ненулевому.


CPallini

5. извините, по ошибке я действительно дал вам 4 звезды (и я не могу это исправить).

Jochen Arndt

Спасибо, Карло.
Никаких проблем с 4.

Рейтинг:
1

Patrice T

Когда вы не понимаете, что делает ваш код или почему он делает то, что делает, ответ таков: отладчик.
Используйте отладчик, чтобы увидеть, что делает ваш код. Просто установите точку останова и посмотрите, как работает ваш код, отладчик позволяет вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения, это невероятный инструмент обучения.

Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010-YouTube[^]

Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.