简体   繁体   English

寻找安西C89任意精度数学库

[英]Looking for Ansi C89 arbitrary precision math library

I wrote an Ansi C compiler for a friend's custom 16-bit stack-based CPU several years ago but I never got around to implementing all the data types. 几年前我为朋友的自定义16位堆栈CPU编写了一个Ansi C编译器,但我从来没有实现所有数据类型。 Now I would like to finish the job so I'm wondering if there are any math libraries out there that I can use to fill the gaps. 现在我想完成这项工作,所以我想知道是否有任何数学库可供我填补空白。 I can handle 16-bit integer data types since they are native to the CPU and therefore I have all the math routines (ie. +, -, *, /, %) done for them. 我可以处理16位整数数据类型,因为它们是CPU的原生数据,因此我为它们完成了所有的数学例程(即。+, - ,*,/,%)。 However, since his CPU does not handle floating point then I have to implement floats/doubles myself. 但是,由于他的CPU不处理浮点数,所以我必须自己实现浮点数/双精度数。 I also have to implement the 8-bit and 32-bit data types (bother integer and floats/doubles). 我还必须实现8位和32位数据类型(烦恼整数和浮点数/双精度数)。 I'm pretty sure this has been done and redone many times and since I'm not particularly looking forward to recreating the wheel I would appreciate it if someone would point me at a library that can help me out. 我很确定这已经完成并重做多次,因为我不是特别期待重新创建轮子,如果有人能指出我可以帮助我的图书馆,我会很感激。

Now I was looking at GMP but it seems to be overkill (library must be absolutely huge, not sure my custom compiler would be able to handle it) and it takes numbers in the form of strings which would be wasteful for obvious reasons. 现在我正在考虑GMP,但它似乎有点过分(库必须绝对巨大,不确定我的自定义编译器能够处理它)并且它需要字符串形式的数字,这显然是浪费。 For example : 例如 :

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

This seems simple enough, I like the api... but I would rather pass in an array rather than a string. 这看起来很简单,我喜欢api ...但我宁愿传入数组而不是字符串。 For example, if I wanted to multiply two 32-bit longs together I would like to be able to pass it two arrays of size two where each array contains two 16-bit values that actually represent a 32-bit long and have the library place the output into an output array. 例如,如果我想将两个32位长整数相加,我希望能够传递两个大小为2的数组,其中每个数组包含两个实际上代表32位长的16位值并具有库位输出到输出数组。 If I needed floating point then I should be able to specify the precision as well. 如果我需要浮点数,那么我也应该能够指定精度。

This may seem like asking for too much but I'm asking in the hopes that someone has seen something like this. 这可能看起来要求太多,但我要求有人见过这样的东西。

Many thanks in advance! 提前谢谢了!

Let's divide the answer. 让我们分开答案。

8-bit arithmetic 8位算术

This one is very easy. 这个很容易。 In fact, C already talks about this under the term "integer promotion". 事实上,C已经在“整数推广”这个术语下讨论过这个问题。 This means that if you have 8-bit data and you want to do an operation on them, you simply pad them with zero (or one if signed and negative) to make them 16-bit. 这意味着,如果你有8位数据,你想用做对他们的操作,您只需垫它们(如果签署或一个和负面的),使他们16位。 Then you proceed with the normal 16-bit operation. 然后继续正常的16位操作。

32-bit arithmetic 32位算术

Note: so long as the standard is concerned, you don't really need to have 32-bit integers. 注意:只要涉及标准,您实际上不需要具有32位整数。

This could be a bit tricky, but it is still not worth using a library for. 这可能有点棘手,但仍然不值得使用库。 For each operation, you would need to take a look at how you learned to do them in elementary school in base 10, and then do the same in base 2 16 for 2 digit numbers (each digit being one 16-bit integer). 对于每个操作,您需要看一下您在小学10年级中如何学习它们,然后在基数2 16中对2位数字(每个数字是一个16位整数)进行相同操作。 Once you understand the analogy with simple base 10 math (and hence the algorithms), you would need to implement them in assembly of your CPU. 一旦你理解了简单的基数10数学(以及算法)的类比,你就需要在CPU的汇编中实现它们。

This basically means loading the most significant 16 bit on one register, and the least significant in another register. 这基本上意味着在一个寄存器上加载最高有效16位,在另一个寄存器中加载最低有效位。 Then follow the algorithm for each operation and perform it. 然后按照每个操作的算法进行操作。 You would most likely need to get help from overflow and other flags. 您很可能需要从溢出和其他标志获得帮助。

Floating point arithmetic 浮点运算

Note: so long as the standard is concerned, you don't really need to conform to IEEE 754. 注意:只要涉及标准,您就不需要符合IEEE 754。

There are various libraries already written for software emulated floating points. 已经为软件模拟浮点编写了各种库。 You may find this gcc wiki page interesting: 你可能会发现这个gcc wiki页面很有趣:

GNU libc has a third implementation, soft-fp. GNU libc有第三个实现,soft-fp。 (Variants of this are also used for Linux kernel math emulation on some targets.) soft-fp is used in glibc on PowerPC --without-fp to provide the same soft-float functions as in libgcc. (其中的变体也用于某些目标上的Linux内核数学仿真。)soft-fp用于PowerPC上的glibc --without-fp,以提供与libgcc相同的软浮点函数。 It is also used on Alpha, SPARC and PowerPC to provide some ABI-specified floating-point functions (which in turn may get used by GCC); 它也用于Alpha,SPARC和PowerPC,以提供一些ABI指定的浮点函数(反过来可能被GCC使用); on PowerPC these are IEEE quad functions, not IBM long double ones. 在PowerPC上,这些是IEEE四核功能,而不是IBM长双功能。

Performance measurements with EEMBC indicate that soft-fp (as speeded up somewhat using ideas from ieeelib) is about 10-15% faster than fp-bit and ieeelib about 1% faster than soft-fp, testing on IBM PowerPC 405 and 440. These are geometric mean measurements across EEMBC; 使用EEMBC进行的性能测量表明,在IBM PowerPC 405和440上进行测试时,soft-fp(有点使用来自ieeelib的想法加速)比fp-bit和ieeelib快约10-15%,比soft-fp快约1%。是EEMBC的几何平均测量值; some tests are several times faster with soft-fp than with fp-bit if they make heavy use of floating point, while others don't make significant use of floating point. 一些测试使用soft-fp比使用fp-bit快几倍,如果他们大量使用浮点,而其他测试没有大量使用浮点。 Depending on the particular test, either soft-fp or ieeelib may be faster; 根据具体测试,soft-fp或ieeelib可能更快; for example, soft-fp is somewhat faster on Whetstone. 例如,soft-fp在Whetstone上有点快。

One answer could be to take a look at the source code for glibc and see if you could salvage what you need. 一个答案可能是看看glibc的源代码,看看你是否可以挽救你需要的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM