我必须实现任何精度的浮点库,因此指数和尾数必须为无限大的正整数。稍后,我必须使用处理器的x86功能来创建加减函数等。我必须使用C ++ / C(我可以使用程序集插入),也可以使用现成的库。
一开始我遇到了问题: 1.使用什么类型来存储无限大的正整数? 2.什么库/函数可以让我使用处理器的功能,并且可以与上述数据类型一起使用?
答案 0 :(得分:3)
- 使用哪种类型存储无限大的正整数?
一个整数向量。就像固定大小的整数由字节组成-本身就像较小的整数一样,此大整数也由较小的部分组成。但是,与固定大小的整数不同,向量可以任意增大(直到内存用完)。
您可以在C ++中将向量包装为自定义类型,以提供面向对象的接口。
2。哪些库/函数可以让我使用处理器的功能,并且可以使用上述数据类型?
如果创建自定义类型,则其他库将不直接支持它。但是,如果您的类提供兼容的接口,则可以使用通用模板库。
例如,如果您提供比较运算符和赋值运算符,则使用标准库中的std::sort
对自定义类对象进行排序应该没有问题。
我可以使用现成的库。
这通常是个好主意。我推荐。
答案 1 :(得分:0)
一个重要的考虑因素是您将使用什么基础表示内部单位。正如其他人所说,这可能是单个单元的向量,然后您可以使用在小学学习的“纸上”操作来处理这些单元。也许是一个结构,其中包含mantassa和指数的单独向量,以及每个向量的符号的标志。但是这些单独的单位会发生什么呢?
选择这些选项可以提高这些操作的效率。
您可能会决定使用字符和10为基数是对此进行编码的最简单方法,并且读写功能非常简单!但是实际上处理器在十进制一次处理一个字节的效率很低。不过,它非常适合读取数字!例如,执行56 * 37将需要在“十进制”架构上执行以下操作:
其中有很多乘法和除法运算,仅2位!
您可能会决定使用整个字节0-255效率更高,而执行基于256的数学运算则简单得多。尤其是当数字分割/ 10和%10步成为简单的移位和掩码时!但是,用十进制在显示屏上读写任意长度的数字要困难得多,而且要决定以2为底的指数甚至更困难!
在base 65536中执行相同的数学运算效率更高,而在64位处理器上运行base 4G则数学效率更高,而打印则复杂得多。使用汇编器,您甚至可以使用64位存储和128位乘法运算!
每次将内部字长加倍时,将用于乘法的部分运算次数减少4,对于除法运算,减少的次数甚至更大!
提高打印效率并保持数学效率合理的一种欺骗方法是在每个存储单元中实际存储许多二进制数字。一个32位存储区实际上可以在每个单元中保存一个最大9位数字的整数。通过以10亿为基数进行数学运算,您只需完成每9位上面显示的所有额外的位拆分操作!
读取数字字符串涉及一次将9位数字读入存储,然后固定指数,我建议仍然使用10的幂。数字应始终内部存储为规范化的浮点格式,其中只有一个小数点后的数字(或始终为0)。如果输入字符串在其他位置包含小数点,或者实际上是整数值,则可以通过摆弄指数值来对其进行修复。数字始终以该格式或整数打印。这样,未使用的数字始终位于最低有效单位的底部,如果它们为零,则它们可以正常工作。
在此方案中,将两个具有不同指数的数字相加或相减需要做一些额外的工作,因为其中一个数字必须先分解为另一个数字的十亿对齐方式,然后才能将它们相加,但是加法仍然非常比乘法或除法更便宜。
将指数值本身读取到保持向量中是很棘手的,但是也许您可以使用限制在64位范围内的指数,这意味着您不必对指数数本身进行多字节操作吗?这样一来,数字就可以达到0.99E10sextillion(仅是指数的19位数字),对于大多数用途来说应该足够了。假设指数仍然代表10的幂,这使值的存储变得方便,或者您可以数十亿的幂来进行存储,“以指数方式”增大范围,但随后文本数字的读取变得更加困难,因为读取数字必须重新对齐(与加/减预对齐类似的操作),但是不必做加/减预对齐也可以从中受益。