2014-09-29 98 views
6

所以,假設我已經創建了一個3位32位整數的結構,它可以作爲一個96位整數。C:大整數的表示

typedef struct { 
    unsigned int x, y, z; 
} Int96; 

我們認爲int x是第一個要填充的整數。在溢出之前,y遞增,並且x被刷新回0. z的功能類似,但是負責y的溢出。

我該如何去打印存儲在這個結構中的值?當然,我不能直接打印出完整的值,而不會導致系統溢出。

+8

小心 - 這是否算作一個答案?十六進制很簡單;八進制和十進制更難。 – 2014-09-29 17:59:49

+1

不,你需要手動實現添加,減去等,並自己轉換爲字符串。您需要實現這些功能才能正確處理數據。 – 2014-09-29 18:00:05

+4

你可能不會喜歡這個答案,但最簡單的方法(不涉及使用另一個庫)是首先實現除以10的分割和模數(假設你想以10爲底進行打印) – Mysticial 2014-09-29 18:01:14

回答

4

的第一步是寫的通用運算程序爲您Int96

void Add96(Int96 *a, const Int96 *b) { 
    // add b to a 
    a->x += b->x; 
    a->y += b->y; 
    a->z += b->z; 
    if (a->y < b->y) a->z++; 
    if (a->x < b->x && ++a->y == 0) a->z++; } 
void Sub96(Int96 *a, const Int96 *b); 
void Mul96(Int96 *a, const Int96 *b); 
void Div96(Int96 *a, const Int96 *b); 
void Mod96(Int96 *a, const Int96 *b); 

有了這些,你可以這樣寫:

void print96(const Int96 *val) { 
    Int96 ten = { 10, 0, 0 }; 
    Int96 div = *val; 
    Int96 mod = *val; 
    Div96(&div, &ten); 
    Mod96(&mod, &ten); 
    if (div.x || div.y || div.z) print96(&div); 
    putchar('0' + mod.x); } 

你可以讓這個更高效的編寫一個DivMod96uint函數,它div和mod在一個步驟中,並且對第二個參數採用unsigned(而不是Int96)並返回該mod。您也可避免每位數的額外拷貝由具有print96destructive功能覆蓋它的參數,並有print96只是做一個副本,然後調用:

void print96destructive(Int96 *val) { 
    unsigned mod = DivMod96ui(val, 10); 
    if (val->x || val->y || val->z) print96destructive(val); 
    putchar('0' + mod); } 
void print96(const Int96 *val) { 
    Int96 v = *val; 
    print96destructive(&v); } 

unsigned DivMod96ui(Int96 *a, unsigned b) { 
    unsigned mod = a->z % b; 
    a->z /= b; 
    uint64_t y = a->y + ((uint64_t)mod << 32); 
    mod = y % b; 
    a->y = y/b; 
    uint64_t x = a->x + ((uint64_t)mod << 32); 
    mod = x % b; 
    a->x = x/b; 
    return mod; } 
+1

+1對於漂亮的'if(a-> x < b-> x && ++ a-> y == 0)a-> z ++; }'和'if(div.x || div.y || div.z)print96(&div);'。 – chux 2014-09-29 19:55:26