Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何(快速)操作c+处双精度或浮点的尾数和指数部分+;? < >我用C++来计算各种特殊函数(例如Lambert函数,迭代法求逆等)。在许多情况下,直接使用尾数和指数显然是更好的方法_C++_Ieee 754_Exponent_Numerical Computing_Mantissa - Fatal编程技术网

如何(快速)操作c+处双精度或浮点的尾数和指数部分+;? < >我用C++来计算各种特殊函数(例如Lambert函数,迭代法求逆等)。在许多情况下,直接使用尾数和指数显然是更好的方法

如何(快速)操作c+处双精度或浮点的尾数和指数部分+;? < >我用C++来计算各种特殊函数(例如Lambert函数,迭代法求逆等)。在许多情况下,直接使用尾数和指数显然是更好的方法,c++,ieee-754,exponent,numerical-computing,mantissa,C++,Ieee 754,Exponent,Numerical Computing,Mantissa,我找到了许多关于如何提取尾数和指数部分的答案,但所有这些答案都只是“计算速度不是很有效的学术案例”,对我来说没有什么用处(我使用尾数和指数操作的动机是提高计算速度)。有时我需要调用一些特定的函数,调用次数约为10亿次(非常昂贵的计算),所以每次节省的计算工作都很好。而使用“frexp”将尾数返回为双精度并不十分合适 我的问题是(对于IEEE 754浮点的C++编译器): 1) 如何读取浮点/双精度尾数的特定位 2) 如何将整个尾数读入浮点/双精度的整数/字节 3) 对于指数,问题与1)、2)相同

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

我的问题是(对于IEEE 754浮点的C++编译器):

1) 如何读取浮点/双精度尾数的特定位

2) 如何将整个尾数读入浮点/双精度的整数/字节

3) 对于指数,问题与1)、2)相同

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

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

在许多情况下,直接使用尾数和指数显然是更好的方法

从我的信号处理工作中,我非常清楚这种感觉,但事实是,指数和尾数不能简单地用作单独的数字;IEEE754规定了相当多的特殊情况和偏移量等

我想一定有一个非常简单的解决办法

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

“学术案例”

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

IEEE754浮动上的优化在现实世界中有非常可靠的使用。然而,我发现,随着后来x86处理器执行SIMD(单指令多数据)的能力以及浮点运算与大多数“位移位”运算一样快的总体事实,我通常怀疑您自己尝试在位级别上执行此操作是不明智的

一般来说,由于IEEE754是一个标准,您可以在任何地方找到关于它如何存储在特定体系结构上的文档。如果你看过,你至少应该找到维基百科上的文章,解释如何做1)和2)(它不像你想象的那样是静态的)

更重要的是: 不要尝试比你的编译器更聪明。除非您明确知道如何将多个相同的操作矢量化,否则您可能不会这样做

尝试特定编译器的数学优化。如前所述,如今他们通常做得不多;CPU进行浮点计算的速度不一定比处理整数的速度慢

我宁愿看看你们的算法,并在那里寻找优化的潜力


另外,在我做这件事的时候,让我们来介绍一下VOLK(向量优化内核库),这是一个主要用于信号处理的数学库。有一个概述。例如,查看以32f开头的屏幕。您会注意到有不同的实现,一种是通用的,一种是CPU优化的,对于每一个SIMD指令集,

< P>可以将FP值的地址复制到<代码>未签名的CHAR*<代码>中,并将得到的指针作为覆盖FP值的数组的地址。< /P> < P> C或C++,如果<代码> x>代码>是IEEE双,那么如果<代码> L>代码>是一个64位长的int,表达式

L=*((长*)&x)

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

s=(字节)(L>>63)

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

f=(L&0x000FFFFFFFFFFFFF)

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

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


L=(让我们看一看网络上的IEE754,每件事都有详细的解释。我严重怀疑你真的需要这样的东西……有一个非常简单的,不可移植的解决方案。如果我可以这么说的话,你会做一些奇怪的事情。我不会去那里。用
浮点
/
双精度
编写高效的代码,让编译器和FPU来完成其余的工作。下面是一个众所周知的例子,直接计算位,以便快速计算平方根倒数。这可能会激励你的工作:这显示了位模式:我建议使用浮点处理器或浮点硬件辅助来加速运算。否则,请考虑使用不动点符号。这会导致U。n定义的行为。有一种方法可以做到这一点,以避免与标准中的类型双关规则相冲突:@Novelocrat问题是严格的别名,这里不适用。
char*
unsigned char*
是允许别名任何其他类型的例外,特别是用于检查对象表示。如果你真的要做那些低级的黑客,它们是最好的方法。有一节是关于别名规则的。@RaphaelAddile仍然没有定义行为。机器可能是big-endian、little-endian或mixed-endian。@MarkWeston没有定义。endian是实现定义的。这意味着我们不使用它来调用恶魔。我们只是我可以很容易地查看实现文档(或者编程的测试性,这是很容易的)。我同意C++编译器可能比我聪明的论点,但是这里是一个简单的快速日志ALG的例子。