0

几年前,我为一个朋友定制的基于堆栈的 16 位 CPU 编写了一个 Ansi C 编译器,但我一直没有时间实现所有数据类型。现在我想完成这项工作,所以我想知道是否有任何数学库可以用来填补空白。我可以处理 16 位整数数据类型,因为它们是 CPU 原生的,因此我为它们完成了所有的数学例程(即 +、-、*、/、%)。但是,由于他的 CPU 不处理浮点数,所以我必须自己实现浮点数/双精度数。我还必须实现 8 位和 32 位数据类型(整数和浮点数/双精度数)。我很确定这已经完成并重做了很多次,因为我并不特别期待重新创建轮子,如果有人能指点我一个可以帮助我的图书馆,我将不胜感激。

现在我在看 GMP,但它似乎有点矫枉过正(库必须绝对巨大,不确定我的自定义编译器是否能够处理它)并且它需要字符串形式的数字,由于显而易见的原因,这将是浪费的。例如 :

mpz_set_str(x, "7612058254738945", 10);
mpz_set_str(y, "9263591128439081", 10);
mpz_mul(result, x, y);

这看起来很简单,我喜欢 api……但我宁愿传入一个数组而不是一个字符串。例如,如果我想将两个 32 位 long 相乘,我希望能够将两个大小为 2 的数组传递给它,其中每个数组包含两个 16 位值,它们实际上代表一个 32 位 long 并具有库位置输出到输出数组。如果我需要浮点,那么我也应该能够指定精度。

这似乎要求太多,但我希望有人看到这样的东西。

提前谢谢了!

4

1 回答 1

2

让我们来划分答案。

8 位算术

这很容易。事实上,C 已经在“整数提升”一词下谈到了这一点。这意味着如果您有 8 位数据并且想要对它们进行操作,您只需用(如果有符号和负数则为1)填充它们以使它们成为 16 位。然后继续进行正常的 16 位操作。

32 位算术

注意:只要涉及标准,您实际上并不需要 32 位整数。

这可能有点棘手,但仍然不值得使用库。对于每个操作,你需要看看你是如何在小学以 10 为基数学习的,然后在以 2 16为基数的 2 位数字(每个数字是一个 16 位整数)中做同样的事情。一旦您理解了与简单的以 10 为基数的数学(以及算法)的类比,您就需要在 CPU 的汇编中实现它们。

这基本上意味着将最高有效 16 位加载到一个寄存器中,并将最低有效位加载到另一个寄存器中。然后按照每个操作的算法并执行它。您很可能需要从溢出和其他标志中获得帮助。

浮点运算

注意:只要是标准,你并不需要符合 IEEE 754。

已经为软件模拟浮点编写了各种库。您可能会发现这个gcc wiki 页面很有趣:

GNU libc 有第三个实现,soft-fp。(它的变体也用于某些目标上的 Linux 内核数学仿真。)在 PowerPC 上的 glibc 中使用 soft-fp --without-fp 来提供与 libgcc 中相同的 soft-float 函数。它还用于 Alpha、SPARC 和 PowerPC 以提供一些 ABI 指定的浮点函数(反过来可能会被 GCC 使用);在 PowerPC 上,这些是 IEEE quad 函数,而不是 IBM long double 函数。

使用 EEMBC 进行的性能测量表明,在 IBM PowerPC 405 和 440 上进行的测试表明,soft-fp(使用 ieeelib 的想法有所加快)比 fp-bit 快 10-15%,ieeelib 比 soft-fp 快约 1%。这些是跨 EEMBC 的几何平均测量值;如果大量使用浮点,则使用 soft-fp 的某些测试比使用 fp-bit 的测试快几倍,而其他测试则没有大量使用浮点。根据特定的测试,soft-fp 或 ieeelib 可能更快;例如,soft-fp 在 Whetstone 上要快一些。

一个答案可能是查看 glibc 的源代码,看看你是否可以挽救你需要的东西。

于 2013-07-23T09:20:58.200 回答