所以,假設我已經創建了一個3位32位整數的結構,它可以作爲一個96位整數。C:大整數的表示
typedef struct {
unsigned int x, y, z;
} Int96;
我們認爲int x是第一個要填充的整數。在溢出之前,y遞增,並且x被刷新回0. z的功能類似,但是負責y的溢出。
我該如何去打印存儲在這個結構中的值?當然,我不能直接打印出完整的值,而不會導致系統溢出。
所以,假設我已經創建了一個3位32位整數的結構,它可以作爲一個96位整數。C:大整數的表示
typedef struct {
unsigned int x, y, z;
} Int96;
我們認爲int x是第一個要填充的整數。在溢出之前,y遞增,並且x被刷新回0. z的功能類似,但是負責y的溢出。
我該如何去打印存儲在這個結構中的值?當然,我不能直接打印出完整的值,而不會導致系統溢出。
的第一步是寫的通用運算程序爲您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對於漂亮的'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
小心 - 這是否算作一個答案?十六進制很簡單;八進制和十進制更難。 – 2014-09-29 17:59:49
不,你需要手動實現添加,減去等,並自己轉換爲字符串。您需要實現這些功能才能正確處理數據。 – 2014-09-29 18:00:05
你可能不會喜歡這個答案,但最簡單的方法(不涉及使用另一個庫)是首先實現除以10的分割和模數(假設你想以10爲底進行打印) – Mysticial 2014-09-29 18:01:14