【发布时间】:2016-07-08 04:07:44
【问题描述】:
我知道,我知道,人们可能会说“只是切换到浮点”,但由于我正在从事的项目的性质,目前这不是一个选项。我正在帮助用 C++ 编写编程语言,我目前很难获得一个非常准确的乘法算法,我有一个 VM,主要是 mod/smod、div/sdiv 的操作(即有符号的数字在这里不是问题), mul, 全小数的减半数和我乘除以创建我的移位的推送移位数。为简单起见,假设我正在使用 32 字节空间。我的算法几乎适用于涉及整数的任何事情,只是当我的小数部分超过 16 个字节时,我遇到了精度问题,如果我要对其进行四舍五入,这个数字会相当准确,但我希望它为尽可能准确,甚至愿意为它牺牲一点性能,只要它保持一个固定点并且不进入浮点领域。我关心的算法我会用一种伪代码来绘制。希望能深入了解如何让这件事变得更好,或者想知道为什么根据计算科学定律,我所要求的只是徒劳的努力。
对于完全小数(所有字节都是小数):
A = num1 / halfShift //truncates the number down to 16 so that when multiplied, we get a full 32 byte num
B = num2 / halfShift
finalNum = A * B
对于大于 16 字节的其余数字,我使用此算法:
this algorithm can essentially be broken down into the int.frac form
essentially A.B * C.D taking the mathematic form of
D*B/shift + C*A*shift + D*A + C*B
if the fractional numbers are larger than the integer, I halve them, then multiply them together in my D*B/shift
just like in the fully fractional example above
我应该注意某种“神奇”的舍入方法吗?请告诉我。
【问题讨论】:
-
算法。这个词是“算法”。这是某人的名字。
-
A = num1 / halfShift //truncates the number down to 16- 一旦你降低了输入的“精度”(分辨率,真的)(这里是 16,单位(字节/数字/位/字...)就更不重要了), 没有量的精确算术可以恢复/增加它。取而代之的是,选择您需要多少个“保护位置”(例如 2 个)并计算到所选精度(在这种情况下为 32+2=34)。在乘法的情况下,这允许丢弃几乎一半的部分乘积。四舍五入到最终精度。 -
@greybeard 你说的“守卫地方”是什么意思?
-
您可能已经被打扰使用wikipedia on guard digits 或搜索引擎来查找What Every Computer Scientist Should Know About Floating-Point Arithmetic。 (我避免使用 guard bits 或 digits 以免暗示基数。无论如何,命名不是标准化的:一位作者的 rounding bit 是另一位作者的第一个保护位。)(如果您希望使用浮点表示来为实际问题产生结果,请务必消化“戈德堡论文” - FP is evil魔法。)
-
(不客气(实际接受提示:-)。如果您希望有人没有发布问题(或者,如果有答案,答案)得到通知,请提及她的名字介绍
@(你会得到建议)。)
标签: c++ algorithm multiplication fixed-point