2018年11月27日 星期二

長除法求商數及餘數

//pseudo code, 最高位數放在低位置(Most Significant Byte first, big-endian), 比較容易
int    *digit   = number.array ;   // 被除數, 例如  int a[4]  = { 3, 2, 5, 6 } 代表 10 進制  325610
int     length= number.length; // 被除數長度, 例如 10 進制 325610, 長度是 4
number divider = number.divider ; // 除數
number q; // 商數, 最高位數, 對齊被除數
number r;  // 餘數, 最低位數, 對齊除數
if (number(digit)  == divider)      { q = 1; r = 0; } // 如果被除數等於除數
else if (number(digit) < divider) { q = 0; r = number(digit); }// 如果被除數小於除數
else while (length --) {// 其它: 被除數大於除數, 一次處理一個數, 直到數量為 0 才結束
        r.push( *digit ) ; // 將被除數從陣列中取出放入餘數, 累積數值
        if (r  <  divider)  q.push(0) ; // 當累積的數值比除數小, 該位數的商等於 0, 直接推入商數
        else { // 否則當累積的數值大於或等於除數, 計算該位數的商
              int temp = 0;  // 初始為 0, 如果是 10 進位, 最多 9 次就可找到商
               do {
                       temp ++;       // 累加商
                       r  -= divider; // 使用最簡單的減法找商
               } while (!(r  < divider)); // 測試直到找出商, 也就是當餘數小於除數時
               q.push(temp) ; // 該位數的商推入商數, 餘數 r 會保留, 待後續處理
         }
         digit ++; // 被除數, 進展至下一位數
} //迴圈
// 商數 q 最後要把開頭多餘的 0 移除掉, 就是答案

如果只取餘數, 不要商數, 可以簡化流程:
if (number(digit)  == divider)           r = 0; // 如果被除數等於除數
else if (number(digit) < divider)  r = number(digit);// 如果被除數小於除數
else while (length --) {// 其它: 被除數大於除數, 一次處理一個數, 直到數量為 0 才結束
         r.push(*digit); // 將被除數從陣列中取出放入餘數, 累積數值
         while (r >= divider) r -= divider;//當累積數值大於或等於除數時, 直接刪掉除數因子
         digit ++; // 被除數, 進展至下一位數
} //迴圈
return r; // 剩下的就是餘數

沒有留言: