3

これはおそらく非常に風変わりな質問です。

私の問題は次のとおりです。

TI 83+ グラフ電卓を使用すると、アセンブリとコンピュータへのリンク ケーブル、または組み込みの TI-BASIC プログラミング言語を使用してプログラミングできます。

私が見つけたものによると、16 ビット整数といくつかのエミュレートされた浮動小数点のみがサポートされています。

ただし、少し大きい数値 (約 64 ビット) で作業したいので、そのために 1 桁の配列を使用します。

{1, 2, 3, 4, 5}

10 進数の 12345 になります。

2 進数では 110000 00111001、または 2 進数配列として:

{1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1}

これは、電卓がそれを表示する方法です。

この 10 進数の配列 (電卓がネイティブ型として表示するには大きすぎる) を 10 進数の配列に変換するにはどうすればよいでしょうか?

効率は問題ではありません。これは宿題ではありません。

これにより、そのような配列などの加算を自由に実装できます。

ありがとう!

4

3 に答える 3

2

それについて考えてみると、次の「アルゴリズム」でそれを行うと思います

  • 最後の桁を確認します (この例では 5)
  • 奇数の場合、バイナリ配列に 1 を (逆の順序で) 格納します。

  • 次に、次の方法で数値を 2 で割ります。

  • 最初の桁から始めて、'carry' 変数をクリアします。
  • それを 2 で割り、'carry' 変数を追加します。余りが 1 の場合 (and&1 で割る前にこれを確認してください)、キャリーに 5 を入れます。
  • すべての数字が終わるまで繰り返す

全体の数値が 0 になるまで、両方の手順を繰り返します。

バイナリ配列の数値はバイナリ表現です

あなたの例: 1,2,3,4,5

  • 5 は奇数なので、バイナリ配列に 1 を格納します: 1
  • 次のアルゴリズムを使用して、配列を 2 で除算します。
  • 0,2,3,4,5 => 0,1+5,3,4,5 => 0,6,1,4,5 => 0,6,1,2+5,5 => 0, 6,1,7,2

そして繰り返す:

0,6,1,7,2 の最後の桁は偶数なので、0: 0,1 を格納します (バイナリ文字列を右から左に埋めることに注意してください)

あなたはバイナリで終わる

編集:上記を明確にするために:私がやっているのは古いアルゴリズムだけです:

 int value=12345;
 while(value>0)
 {
      binaryArray.push(value&1);
      value>>=1;     //divide by 2
 }

あなたの例を除いて、intはありませんが、(10ベース)intを表す配列があります; ^)

于 2009-11-01T13:02:52.533 に答える
1

途中で、10 進数表現の各桁を 2 進数表現に変換してから、すべての桁の 2 進数表現を追加します。

5 = 101
40 = 101000
300 = 100101100
2000 = 11111010000
10000 = 10011100010000

             101
          101000
       100101100
     11111010000
+ 10011100010000
----------------
  11000000111001

C# での概念実証:

2 進数の配列に変換し、配列を加算し、配列を 10 倍するメソッド:

private static byte[] GetBinary(int value) {
  int bit = 1, len = 1;
  while (bit * 2 < value) {
    bit <<= 1;
    len++;
  }
  byte[] result = new byte[len];
  for (int i = 0; value > 0;i++ ) {
    if (value >= bit) {
      value -= bit;
      result[i] = 1;
    }
    bit >>= 1;
  }
  return result;
}

private static byte[] Add(byte[] a, byte[] b) {
  byte[] result = new byte[Math.Max(a.Length, b.Length) + 1];
  int carry = 0;
  for (int i = 1; i <= result.Length; i++) {
    if (i <= a.Length) carry += a[a.Length - i];
    if (i <= b.Length) carry += b[b.Length - i];
    result[result.Length - i] = (byte)(carry & 1);
    carry >>= 1;
  }
  if (result[0] == 0) {
    byte[] shorter = new byte[result.Length - 1];
    Array.Copy(result, 1, shorter, 0, shorter.Length);
    result = shorter;
  }
  return result;
}

private static byte[] Mul2(byte[] a, int exp) {
  byte[] result = new byte[a.Length + exp];
  Array.Copy(a, result, a.Length);
  return result;
}

private static byte[] Mul10(byte[] a, int exp) {
  for (int i = 0; i < exp; i++) {
    a = Add(Mul2(a, 3), Mul2(a, 1));
  }
  return a;
}

配列の変換:

byte[] digits = { 1, 2, 3, 4, 5 };

byte[][] bin = new byte[digits.Length][];
int exp = 0;
for (int i = digits.Length - 1; i >= 0; i--) {
  bin[i] = Mul10(GetBinary(digits[i]), exp);
  exp++;
}
byte[] result = null;
foreach (byte[] digit in bin) {
  result = result == null ? digit: Add(result, digit);
}

// output array
Console.WriteLine(
  result.Aggregate(
    new StringBuilder(),
    (s, n) => s.Append(s.Length == 0 ? "" : ",").Append(n)
  ).ToString()
);

出力:

1,1,0,0,0,0,0,0,1,1,1,0,0,1

編集:
配列に 10 を掛けるメソッドを追加しました。数字をバイナリ配列に変換する前に乗算する代わりに、配列に対して行う必要があります。

于 2009-11-01T13:23:18.637 に答える
0

ここでの主な問題は、互いに倍数ではないベース間を移動しているため、入力桁と出力桁の間に直接分離されたマッピングがないことです。おそらく、最下位桁から始めて、次の桁を参照する必要がある前に、できるだけ多くの最下位桁を出力する必要があります。そうすれば、任意の時点で調べられる入力数字は最大 2 つだけで済みます。

数値を逆の形式 (配列内で最下位桁が最初になるように) で格納すると、処理順序が有利になる場合があります。

于 2009-11-01T12:19:32.637 に答える