首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言有符號加法與無符號減法溢出檢測:條件編譯防重複包含與 extern "C++" 兼容

     編輯:程式設計綜合問答

實驗要求

  • 實現 sat_add(有符號飽和加法)與 sat_sub(無符號飽和減法)。
  • 使用 stdint.h 固定寬度類型,條件編譯防重複包含,extern "C" 支持 C++ 調用。
  • 小端系統運行。

頭文件 sat_math.h


#ifndef SAT_MATH_H
#define SAT_MATH_H

#include 

#ifdef __cplusplus
extern "C" {
#endif

#define TMAX_INT32  ((int32_t)0x7FFFFFFF)
#define TMIN_INT32  ((int32_t)0x80000000)

/* 有符號飽和加法
 * 返回值:運算結果
 * *flag:0=正常, 1=正溢出(TMAX), -1=負溢出(TMIN)
 */
int32_t sat_add(int32_t x, int32_t y, int *flag);

/* 無符號飽和減法
 * 返回值:運算結果
 * *flag:0=正常, -1=溢出(借位)
 */
uint32_t sat_sub(uint32_t x, uint32_t y, int *flag);

#ifdef __cplusplus
}
#endif

#endif /* SAT_MATH_H */

實現文件 sat_math.c


#include "sat_math.h"

int32_t sat_add(int32_t x, int32_t y, int *flag) {
    int32_t res = x + y;
    if (flag) {
        // 正溢出:兩正相加得負
        if (x > 0 && y > 0 && res < 0) {
            *flag = 1;
            return TMAX_INT32;
        }
        // 負溢出:兩負相加得正
        if (x < 0 && y < 0 && res > 0) {
            *flag = -1;
            return TMIN_INT32;
        }
        *flag = 0;
    }
    return res;
}

uint32_t sat_sub(uint32_t x, uint32_t y, int *flag) {
    // 無符號減法溢出等價於 x < y (產生借位)
    if (flag) {
        *flag = (x < y) ? -1 : 0;
    }
    return x - y; // 硬件自動模 2^32 環繞,符合飽和語義下的「截斷」行為
    // 若需飽和到 0:return (x < y) ? 0 : x - y;
}

關鍵點說明

  1. #ifndef/#define/#endif 防止重複包含。
  2. extern "C" 禁用 C++ 名字修飾,使 C++ 可直接鏈接。
  3. 使用 int32_t/uint32_t 保證跨平台固定寬度。
  4. 溢出判斷利用補碼特性,無需大數庫。

最佳回答代碼


//第二個函數的flag參數類型應該是指針或者引用吧,不然沒意義了,寫個引用的算了,如果是指針就照第一個改
//extern沒太搞懂,這兩個函數用不上這個啊,一般用C++寫全局變量時就是那種定義在cpp中但是其他.h .cpp也要用時聲明
//ooxx.h
#ifdef OOXX_H
#else
#define OOXX_H
#define i32 int
#define ui32 unsigned int
#define TMax 1
#define TMin -1
#define NULL 0
i32 sat_add( i32 x, i32 y, i32* flag );
ui32 sat_sub( ui32 x, ui32 y, ui32& flag );
#endif
//ooxx.c
#include "ooxx.h"
i32 sat_add( i32 x, i32 y, i32* flag ) {
    i32 r = x + y;
    if( flag && x > 0 && y > 0 && r < 0 ) { *flag = TMax; }
    else if( flag && x < 0 && y < 0 && r > 0 ) { *flag = TMin; }
    else { *flag = NULL; }
    return r;
}
ui32 sat_sub( ui32 x, ui32 y, ui32& flag ) {
    ui32 r = x - y;
    if( x - r != y || y + r != x ) flag = -1;
    else flag = NULL;
    return r;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved