bigInt加法和减法很重要

时间:2014-10-29 04:34:57

标签: c++ math bigint

我目前正在完成学校作业(对不起,我的问题是关于我的作业,但我不是在询问代码中使用的算法)。我现在正在做算术部分,加法和减法。由于只有两个运算符,因此有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);
};

1 个答案:

答案 0 :(得分:0)

所有评论都是处理操作符过载的东西,但我怀疑OP是关于如何计算加法和减法操作数的所有符号组合。

  1. 两个补充

    整数 ALU 的大多数 HW 实现使用二进制补码表示有符号数字。这意味着:

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

    通过反转所有位获得的负值并递增结果。因此,您可以对所有添加/子和符号组合使用单加法器架构,而符号位仍然是 MSB 。这个编码处理有符号和无符号的操作相同,所以为了添加你没有任何问题(无需添加)和减法只是反转第二个操作数的signum并添加。

    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
    

    从这很容易

    <强>加成

    • 只有在符号相同的情况下才能添加数字(如果不是将其转换为减法)

    <强>减法

    • 只有当符号相同且第一个操作数大于或等于第二个操作数时,才能使用子编号。

    所以它会是这样的:

    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设置为更大的abs。如果你交换了操作数,则反转结果的符号。仅当展位操作数是相同符号时才进行减法,否则转换为(a+b) ...

  3. 希望它有所帮助