分解浮点数

Dav*_*ght 4 c c# floating-point

给定一个浮点数,我想将它分成一个部分之和,每个部分都有给定的位数.例如,给定3.1415926535并告诉它将其分成10个基本的10个部分,每个4位数,它将返回3.141 + 5.926E-4 + 5.350E-8.实际上,我想将一个double(具有52位精度)分成三个部分,每个部分具有18位精度,但是使用base-10示例更容易解释.我不一定反对使用标准双精度IEEE浮点数的内部表示的技巧,但我真的更喜欢纯粹保留在浮点范围内的解决方案,以避免任何与字节序相关或非标准的问题浮点表示.

不,这不是一个家庭作业问题,是的,这有实际用途.如果要确保浮点乘法是精确的,则需要确保乘以的任何两个数字永远不会超过浮点类型中有空格的数字的一半.从这种分解开始,然后将所有部分相乘并进行卷积,就是这样做的一种方法.是的,我也可以使用任意精度的浮点库,但只涉及几个部分时,这种方法可能会更快,而且它肯定会更轻.

Pas*_*uoq 7

如果要确保浮点乘法是精确的,则需要确保乘以的任何两个数字永远不会超过浮点类型中有空格的数字的一半.

究竟.这种技术可以在Veltkamp/Dekker乘法中找到.虽然可以像在其他答案中一样访问表示的位,但您也可以仅使用浮点运算.这篇博文中有一个例子.您感兴趣的部分是:

Input: f; coef is 1 + 2^N
 p = f * coef;
 q = f - p;
 h = p + q;  // h contains the 53-N highest bits of f
 l = f - h;  // l contains the N lowest bits of f
Run Code Online (Sandbox Code Playgroud)

*,-并且+必须完全符合IEEE 754操作的精度f才能使其工作.在英特尔架构上,这些操作由SSE2指令集提供.Visual C在其编译的C程序的前奏中将历史FPU的精度设置为53位,这也有帮助.

  • 为了完整性:必须使用舍入到最近(通常是默认的舍入模式)执行操作.如果`f*coef`没有溢出,则其他操作不会溢出.如果`f`是低于正常或正常,则此方法有效.这适用于十进制算术或任何基数.(All per Muller et al,*Handbook of Floating-Point Arithmetic*,2010,page 133.) (2认同)