3

这可能是一个非常奇特的问题。

我的问题如下:

TI 83+ 图形计算器允许您使用汇编和连接到计算机的电缆或其内置的 TI-BASIC 编程语言对其进行编程。

根据我的发现,它只支持 16 位整数和一些模拟浮点数。

但是,我想使用更大的数字(大约 64 位),因此我使用了一个包含单个数字的数组:

{1, 2, 3, 4, 5}

将是十进制 12345。

在二进制中,即 110000 00111001,或者作为二进制数字数组:

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

这就是计算器的显示方式。

我将如何将这个十进制数字数组(对于计算器来说太大而无法将其显示为本机类型)转换为十进制数字数组?

效率不是问题。这不是家庭作业。

这将使我可以自由地为此类数组等实施加法。

谢谢!

4

3 回答 3

2

想了想,我想我会用下面的“算法”来做

  • 检查最后一位数字(示例中为 5)
  • 如果它是奇数,则(从相反的顺序)在二进制数组中存储 1

  • 现在通过以下方法将数字除以2:

  • 从第一个数字开始并清除“进位”变量。
  • 除以 2 并添加“进位”变量。如果余数为 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 (注意我们从右到左填充二进制字符串)

ETC

你最终得到一个二进制文件

编辑:只是为了澄清上面:我所做的只是古老的算法:

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

除了在您的示例中,我们没有一个 int 而是一个表示(10 base) int 的数组;^)

于 2009-11-01T13:02:52.533 回答
1

方法是将十进制表示中的每个数字转换为其二进制表示,然后添加所有数字的二进制表示:

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

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

C# 中的概念证明:

转换为二进制数字数组、数组相加和数组乘以十的方法:

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

编辑:
添加了将数组乘以十的方法。不是在将数字转换为二进制数组之前将其相乘,而是必须对数组进行。

于 2009-11-01T13:23:18.637 回答
0

这里的主要问题是您要在不是彼此倍数的基础之间进行,因此输入数字和输出数字之间没有直接的隔离映射。您可能必须从最低有效数字开始,在需要查询下一个数字之前尽可能多地输出输出的最低有效数字,依此类推。这样,您只需要在任何给定时间点检查最多 2 个输入数字。

您可能会发现在处理顺序方面以相反的形式存储您的数字是有利的(这样最低有效数字在数组中排在第一位)。

于 2009-11-01T12:19:32.637 回答