большое сложение и вычитание

В настоящее время я выполняю школьное задание (извините, что мой вопрос касается моего задания, но я не спрашиваю об алгоритмах, используемых в кодах). Сейчас я занимаюсь арифметической частью, сложением и вычитанием. Поскольку есть только два оператора, есть 8 комбинаций операций. В моей программе я могу выполнить эти четыре случая:

(+a)+(+b)
(-a)+(-b)
(-a)-(+b)
(+a)-(-b)

Тем не менее, я не могу понять, как сделать другие четыре случая,
То есть

(+a)+(-b)
(-a)+(+b)
(-a)-(-b)
(+a)-(+b)

Я искренне надеюсь, что вы, ребята, сможете дать предложения и советы о том, как справиться с этими четырьмя случаями.

Вот мой код:

linkedListType.h:
Это обычный заголовочный файл связанного списка, поэтому я не публикую здесь весь код.

bigInteger.h:
Функции в этом довольно длинные. Поэтому я пропустил их публикацию.

#ifndef BIG_INTEGER_H
#define BIG_INTEGER_H

#include <stack>
#include <iostream>
#include "linkedListType.h"
using namespace std;

class bigInteger
{
private:
int sign;                       // set 0 for positive, 1 for negative
linkedListType<int> digits;     // internal linked-list for storing digits in reverse order

public:
bigInteger();                           // default constructor
bigInteger(const bigInteger& other);    // copy constructor

// Overload constructor
// Use an numerical string to construct this bigInteger
// For negative number, the first char in the string is '-'
// e.g. "-12345"bigInteger(const string& number);

// overload the assignment operator
const bigInteger& operator= (const bigInteger& other);

// Return a new bigInteger that is equal to *this + other
// The contents of this and other should not be modified
bigInteger& operator+ (bigInteger& other);

// Return a new bigInteger that is equal to *this - other
// The contents of this and other should not be modified
bigInteger& operator- (bigInteger& other);

// Print a big integer
// Since the digits are stored in reverse order in the internal
// list, you should print in reverse order
// Print "undefined" if the digits list is empty
friend ostream& operator<<(ostream& os, bigInteger& n);
};

0

Решение

хорошо, все комментарии обрабатывают вещи перегрузки оператора, но я подозреваю, что OP — о том, как вычислить все комбинации знаков операндов для сложения и вычитания.

  1. дополнение двух

    ну большинство HW реализации целых ALU использовать два дополнения для представления чисел со знаком. Это означает:

    -X = (X^0xFFFFFFFF)+1; // 32 bit example
    

    это отрицательное значение, полученное путем инвертирования всех битов и увеличения результата. Таким образом, вы можете использовать архитектуру с одним сумматором для всех комбинаций добавления / подписи и знака, пока бит знака еще MSB. Эта кодировка обрабатывает подписанные и неподписанные операции одинаково, поэтому для сложения у вас нет никаких проблем (ничего не нужно делать, просто добавьте), а для вычитания просто инвертируйте знак второго операнда и добавьте.

    Реализация C ++ выглядит так:

    bool bigInteger::sign() { return MSB_of_this; }
    bigInteger bigInteger::operator+ () { bigInteger z=*this; return z; }
    bigInteger bigInteger::operator- () { bigInteger z=*this; /* here negate all bits and increment z*/ return z' |z; }
    bigInteger bigInteger::operator+ (bigInteger& y)
    {
    bigInteger z;
    // here do z = *this + y as if all operands were positive
    return z;
    }
    
    bigInteger bigInteger::operator- (bigInteger& y0)
    {
    bigInteger z;
    y=-y0; // invert sign in temp variable to avoid changing input operand value !!!
    // here do z = *this + y as if all operands were positive
    return z;
    }
    

    обратите внимание, что я не изменяю входной операнд, и все возвращаемые значения являются отдельной переменной (не использую это даже для унарного +). Это связано с цепочкой операндов. Некоторым компиляторам трудно объединить более 3 операторов в одну строку, если они не закодированы таким образом, что означает, что вы не можете компилировать такие строки, как

    c=a+b-c*a*b/(s-d)+(23*q);
    

    вместо этого вам придется разбить его на более простые термины …

  2. В случае, если вы не используете два дополнения

    Затем вы должны обработать знаки входного операнда. Наиболее распространенным случаем является то, что у вас есть флаг знака как отдельная переменная, а не внутри битов числа. В этом случае вам понадобятся некоторые функции, которые вообще не учитывают знак

    bigInteger uadd(bigInteger &a,bigInteger &b); //=|a|+|b|
    bigInteger usub(bigInteger &a,bigInteger &b); //=|a|-|b| but operands must be: |a|>|b|
    bool        ugeq(bigInteger &a,bigInteger &b); //=|a|>=|b| Unsigned Greater or EQual
    

    из этого легко

    прибавление

    • Вы можете добавлять числа, только если они имеют одинаковый знак, если не конвертировать его в вычитание

    Substraction

    • Вы можете добавлять числа только в том случае, если они имеют одинаковый знак и первый операнд больше или равен второму.

    Так было бы что-то вроде этого:

    bigInteger bigInteger::operator+ (bigInteger& y)
    {
    bigInteger z;
    bool sx,sy;
    sx=sign();
    sy=y.sign();
    if (sx==sy) z=uadd(*this,y);  // same signs is add
    else                            // not then first operand for (a-b) is the positive one
    {
    if (sx) return y-(*this);
    else    return (*this)-y;
    }
    // here set the sign to the same as operands
    z.set_sign(sx);
    return z;
    }
    

    так как это задание, я оставлю - оператор без кода.

    Это будет очень похоже на + оператор, но вам нужно отсортировать входные операнды по абсолютному размеру (используя ugeq) и установите результат sign от абс больше. если вы поменяли местами операнды, инвертируйте знак результата. Вычитать только, если операнды на стенде совпадают с тем же знаком (a+b)

Надеюсь, это поможет немного

0

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector