4pi*_*ie0 0 c++ math floating-point boost floating-point-precision
在Boost中实现了erf功能

<boost/math/special_functions/erf.hpp>我们有一个标题
result = z * 1.125 + z * 0.003379167095512573896158903121545171688L;
Run Code Online (Sandbox Code Playgroud)
在下面附带的代码段中.我的问题是:为什么没有
大号
这个加法的第一个组成部分中的长后缀,而第二个中有一个?它背后的理由是什么?它带来了什么影响?
template <class T, class Policy>
T erf_imp(T z, bool invert, const Policy& pol, const mpl::int_<113>& t)
{
BOOST_MATH_STD_USING
BOOST_MATH_INSTRUMENT_CODE("113-bit precision erf_imp called");
if(z < 0){
if(!invert)
return -erf_imp(-z, invert, pol, t);
else if(z < -0.5)
return 2 - erf_imp(-z, invert, pol, t);
else
return 1 + erf_imp(-z, false, pol, t);
}
T result;
// Big bunch of selection statements now
if(z < 0.5){
// We're going to calculate erf:
if(z == 0){
result = 0;
}else if(z < 1e-20){
result = z * 1.125 + z * 0.003379167095512573896158903121545171688L;
^^^ no L? ^^^
Run Code Online (Sandbox Code Playgroud)
如果z已经是a long double,则乘法z * 1.125已经是long double乘法.常量1.125可以完全表示为a double,它的类型.事实上,它可以完全代表一个float.因此,无需指明long double此常量的类型.如果z具有更宽的浮点类型,则在乘法之前提升常量.
相比之下,以十进制写的实数0.003379167095512573896158903121545171688在任何二进制浮点精度中都无法准确表示.如果在程序0.003379167095512573896158903121545171688L中写入0.003379167095512573896158903121545171688,它将表示最接近double所指示的十进制序列,这与最近的序列不同long double,并且远离实际值.
您可以通过以下C程序观察其差异:
#include <stdio.h>
int main(int c, char **v)
{
printf("%s\n%.24Lf\n%.24Lf\n\n%La\n%La\n",
"0.003379167095512573896158903121545171688",
(long double) 0.003379167095512573896158903121545171688,
0.003379167095512573896158903121545171688L,
(long double) 0.003379167095512573896158903121545171688,
0.003379167095512573896158903121545171688L);
}
Run Code Online (Sandbox Code Playgroud)
结果:
0.003379167095512573896158903121545171688
0.003379167095512573739530
0.003379167095512573896231
0xd.d750429b6d118p-12
0xd.d750429b6d11ae4p-12
Run Code Online (Sandbox Code Playgroud)