ビットバッファが長い場合、アルゴリズムはあまり良くありません。これは、各出力トリットが のより小さい値にも必要なすべての除算を繰り返すためですn
。したがって、このアルゴリズムを「bignum」算術に変換することは、あなたが望むものではありません。
別のアプローチ: ビットを左から右にスキャンし、新しいビットごとに以前の値を更新します。
val = val * 2 + bit
n
トリットを含む 3進数t[i]
の値は
sum(i = 0 .. n-1) t[i] * 3^i
したがって、val
新しくスキャンされたビットの更新済みの 3 進数表現は、次のようになります。
[ 2 * sum(i = 0 .. n-1) t[i] * 3^i ] + bit
= bit + sum(i = 0 .. n-1) 2 * t[i] * 3^i
= 2 * t[0] + b + sum(i = 1 .. n) 2 * t[i] * 3^i
コードを単純にするために、符号なし文字の配列でトリットを計算してみましょう。完成後、好きな方法で再梱包できます。
#include <stdio.h>
// Compute the trit representation of the bits in the given
// byte buffer. The highest order byte is bytes[0]. The
// lowest order trit in the output is trits[0]. This is
// not a very efficient algorithm, but it doesn't use any
// division. If the output buffer is too small, high order
// trits are lost.
void to_trits(unsigned char *bytes, int n_bytes,
unsigned char *trits, int n_trits)
{
int i_trit, i_byte, mask;
for (i_trit = 0; i_trit < n_trits; i_trit++)
trits[i_trit] = 0;
// Scan bits left to right.
for (i_byte = 0; i_byte < n_bytes; i_byte++) {
unsigned char byte = bytes[i_byte];
for (mask = 0x80; mask; mask >>= 1) {
// Compute the next bit.
int bit = (byte & mask) != 0;
// Update the trit representation
trits[0] = trits[0] * 2 + bit;
for (i_trit = 1; i_trit < n_trits; i_trit++) {
trits[i_trit] *= 2;
if (trits[i_trit - 1] > 2) {
trits[i_trit - 1] -= 3;
trits[i_trit]++;
}
}
}
}
}
// This test uses 64-bit quantities, but the trit
// converter will work for buffers of any size.
int main(void)
{
int i;
// Make a byte buffer for an easy to recognize value.
#define N_BYTES 7
unsigned char bytes [N_BYTES] =
{ 0xab, 0xcd, 0xef, 0xff, 0xfe, 0xdc, 0xba };
// Make a trit buffer. A 64 bit quantity may need up to 42 trits.
#define N_TRITS 42
unsigned char trits [N_TRITS];
to_trits(bytes, N_BYTES, trits, N_TRITS);
unsigned long long val = 0;
for (i = N_TRITS - 1; i >= 0; i--) {
printf("%d", trits[i]);
val = val * 3 + trits[i];
}
// Should prinet value in original byte buffer.
printf("\n%llx\n", val);
return 0;
}