定数3による整除算
昨日のexactDivideBy3()の不具合はちゃんと調べたら修正できた.
ボローを伝搬させるところのif文に誤りがあった.
たとえば mag[0]=2, mag[1]=0,mag[2]=1 みたいな状況で間違えた答えになる.
正しいものに書き換えたので,Divide(3)をやめてExactDivideBy3()を呼ぶようにした.
/** * このインスタンスの定数 3 による整除算の商を返す. * 2**32 の法の下での 3 の乗法逆元は 0xaaaaaaab. */ private BigInteger ExactDivideBy3() { int length = magnitude.Length; int[] result = new int[length]; long x, w, q, borrow; borrow = 0L; for (int i = length - 1; i >= 0; i--) { x = magnitude[i] & LONG_MASK; // ボロー伝搬の処理 w = x - borrow; if (w < 0) borrow = 1; else borrow = 0; // 0xaaaaaaab ≡ 3**(-1) (mod 2**32) q = (w * 0xaaaaaaab) & LONG_MASK; result[i] = (int)q; // ボローを求める.値は 0,1,2 のいずれか // 割り切れることが保障されているので,勝手に借りて問題ない if (q >= 0x55555556) { borrow++; if (q >= 0xaaaaaaab) borrow++; } } result = TrustedStripLeadingZeroInts(result); return new BigInteger(result, sign); }