首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

大整數算法系列(八):有符號加法與減法完整實現

     編輯:關於C語言

前言

承接前文「比較操作、絕對值加法、絕對值減法」,本文將這些基礎組件組裝,實現完整的有符號大整數加減法。核心思想是「分類討論,化繁為簡」。

有符號加法邏輯

設兩數為 x、y,結果為 z。

1. 同號(符號相同)

  • 執行 絕對值加法:|z| = |x| + |y|
  • 結果符號 = 原符號(同為正則結果正,同為負則結果負)

2. 異號(符號不同)

  • 執行 絕對值減法:|z| = ||x| - |y||,用大減小
  • 結果符號 = 絕對值較大者的符號
  • 特殊情況:|x| = |y| 時結果為 0,但可能出現 -0,需強制修正符號為正

核心代碼實現

int bn_add_bn(bignum *z, const bignum *x, const bignum *y) {
    int ret, sign = x->sign;
    if (x->sign == y->sign) {                 // 同號
        BN_CHECK(bn_add_abs(z, x, y));
        z->sign = sign;
    } else {                                  // 異號
        if (bn_cmp_abs(x, y) >= 0) {          // |x| >= |y|
            BN_CHECK(bn_sub_abs(z, x, y));
            z->sign = sign;
        } else {                              // |x| < |y|
            BN_CHECK(bn_sub_abs(z, y, x));
            z->sign = -sign;
        }
    }
    if (BN_IS_ZERO(z)) z->sign = 1;           // 消除 -0
    return ret;
}

有符號減法邏輯

減法可轉化為加法:x - y = x + (-y),但直接實現更高效。

1. 異號 → 絕對值加法

x - (-y) = x + y,結果符號同 x。

2. 同號 → 絕對值減法

大減小,結果符號由絕對值大小決定,同樣需處理 -0。

int bn_sub_bn(bignum *z, const bignum *x, const bignum *y) {
    int ret, sign = x->sign;
    if (x->sign != y->sign) {                 // 異號
        BN_CHECK(bn_add_abs(z, x, y));
        z->sign = sign;
    } else {                                  // 同號
        if (bn_cmp_abs(x, y) >= 0) {
            BN_CHECK(bn_sub_abs(z, x, y));
            z->sign = sign;
        } else {
            BN_CHECK(bn_sub_abs(z, y, x));
            z->sign = -sign;
        }
    }
    if (BN_IS_ZERO(z)) z->sign = 1;
    return ret;
}

單精度數加減法

將單精度數 y 封裝為臨時 bignum,複用上述邏輯:

int bn_add_int(bignum *z, const bignum *x, bn_sint y) {
    bignum t; bn_digit p[1];
    p[0] = (y >= 0) ? y : -y;
    t.used = (y != 0) ? 1 : 0;
    t.sign = (y >= 0) ? 1 : -1;
    t.dp = p; t.alloc = 1;
    return bn_add_bn(z, x, &t);
}

關鍵宏定義

#define BN_IS_ZERO(x)  ((x->used == 0) ? 1 : 0)

總結

有符號加減法的本質是「符號分類 + 絕對值運算」。通過復用 bn_add_abs、bn_sub_abs、bn_cmp_abs 三大基石,結構清晰、邊界處理完善。下一步將進入更複雜的乘法優化領域。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved