首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在c++中对双精度或浮点数的尾数和指数部分进行(快速)运算?

如何在c++中对双精度或浮点数的尾数和指数部分进行(快速)运算?
EN

Stack Overflow用户
提问于 2016-01-10 03:40:57
回答 3查看 1.4K关注 0票数 2

我使用c++来计算各种类型的特殊函数(例如,Lambert函数,求逆的迭代方法等)。在许多情况下,有一种明显更好的方法来直接使用尾数和指数。

我找到了很多关于如何提取尾数和指数部分的答案,但是所有这些都是“计算速度不是很有效的学术案例”,对我来说有点无用(我使用尾数和指数运算的动机是为了提高计算速度)。有时我需要调用一些特定的函数大约十亿次(非常昂贵的计算),所以每一次节省的计算工作都是很好的。使用"frexp“将尾数作为双精度返回是不太合适的。

我的问题是(对于使用IEEE754浮点的c++编译器):

1)如何读取float/double尾数的特定位?

2)如何将整个尾数读入float/double的整型/字节?

3)与1),2)指数相同的问题。

4)与1),2),3)写作相同的问题。

考虑到我的动机是更快的计算,如果我直接使用尾数或指数。我想一定有一个非常简单的解决方案。

EN

回答 3

Stack Overflow用户

发布于 2016-01-10 03:48:13

在许多情况下,有一种明显更好的方法来直接处理尾数和指数。

我知道从我的信号处理工作中感觉太好了,但事实是指数和尾数不是简单地作为单独的数字使用;IEEE754指定了相当特殊的情况,以及偏移量等。

我想肯定有一个非常简单的解决方案。

工程经验告诉我:通常情况下,以“简单的解决方案”结尾的句子是不正确的。

“学术案例”

然而,这绝对不是真的(我会在最后提到一个例子)。

在IEEE754浮点数上有非常扎实的优化使用。然而,我发现由于后来的x86处理器具有执行单指令多数据(单指令,多数据)的能力,而且浮点运算的速度与大多数“位移位”操作一样快,我通常怀疑您自己尝试在位级别上执行此操作是不明智的。

通常,由于IEEE754是一种标准,因此到处都可以找到有关如何将其存储在特定体系结构上的文档。如果你已经看过了,你至少应该找到维基百科的文章,解释如何做1)和2) (它并不像你想象的那样是静态的)。

更重要的是:不要试图比你的编译器更聪明。您可能不会,除非您明确知道如何向量化多个相同的操作。

尝试特定编译器的数学优化。正如前面提到的,现在它们通常不会做太多事情;CPU进行浮点计算的速度并不比处理整数的速度慢。

我更愿意看看你的算法,并在那里寻找优化的可能性。

同时,让我们介绍VOLK (Vector Optimized Library of Kernels),这是一个主要用于信号处理的数学库。http://libvolk.org有一个概述。查看以32f开头的kernels,例如32f_expfast。您将注意到,每个SIMD指令集都有不同的实现,即通用的和针对CPU优化的实现。

票数 6
EN

Stack Overflow用户

发布于 2016-01-10 03:51:03

您可以将fp值的地址复制到unsigned char*中,并将结果指针视为覆盖fp值的数组的地址。

票数 1
EN

Stack Overflow用户

发布于 2016-01-30 16:29:51

在C或C++中,如果x是IEEE双精度型,那么如果L是64位长的整型,则表达式

L = *((long *) &x);

将允许直接访问比特。如果s是表示符号的字节(0 = '+',1= '-'),则e是表示无偏指数的整数,而f是表示小数位的长整型

s = (byte)(L >> 63);

e = ((int)(L >> 52) & 0x7FF) - 0x3FF;

f = (L & 0x000FFFFFFFFFFFFF);

(如果f是一个规格化数字,即不是0、非规格化、inf或NaN,则最后一个表达式应添加0x0010000000000000,以支持IEEE双精度格式的隐式高位1位。)

将符号、指数和分数重新打包为双精度类似:

L= (s << 63) + ((e + 0x3FF) << 52) + (f &0x000FFFFFFFFFFFFFFF);

X=*((双倍*) &L);

上面的代码在用64位代码编译的64位机器上只生成几条机器指令,没有子例程调用。对于32位代码,有时会调用执行64位算术,但一个好的编译器通常会生成内联代码。无论哪种情况,这种方法都是非常快的。

一种类似的方法适用于使用L = bitConverter.DoubleToInt64Bits(x);x = BitConverter.Int64BitsToDouble(L);的C#,如果允许使用不安全代码,则与上面完全相同。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34698067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档