Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.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++函数,它根据一个简单的模型计算概率。似乎C++趋向于将非常小的概率舍入到0,而非常大的概率趋向于1。这会导致在以后的计算中出现问题(取对数(p)和对数(1-p)) 有没有一种方法能显式地表示C++中可以不表示舍入的1个最大数?同样,最小的数字大于0_C++_Machine Learning_Double_Rounding_Probability - Fatal编程技术网

C++;是否可以在不舍入的情况下表示内部? 我有一个C++函数,它根据一个简单的模型计算概率。似乎C++趋向于将非常小的概率舍入到0,而非常大的概率趋向于1。这会导致在以后的计算中出现问题(取对数(p)和对数(1-p)) 有没有一种方法能显式地表示C++中可以不表示舍入的1个最大数?同样,最小的数字大于0

C++;是否可以在不舍入的情况下表示内部? 我有一个C++函数,它根据一个简单的模型计算概率。似乎C++趋向于将非常小的概率舍入到0,而非常大的概率趋向于1。这会导致在以后的计算中出现问题(取对数(p)和对数(1-p)) 有没有一种方法能显式地表示C++中可以不表示舍入的1个最大数?同样,最小的数字大于0,c++,machine-learning,double,rounding,probability,C++,Machine Learning,Double,Rounding,Probability,我可以这样做: if (probability == 1) probability = 0.999999999; else if (probability == 0) probability = 0.000000001; 但这会导致其他数字问题(与数字累积有关)。是否有一种更具原则性的方法,可能是使用数字限制?您可以通过使用DBL\u EPSILON来使用标题(或者根据您的数据类型使用FLT\u EPSILON): DBL\u EPSILON被定义为最小值,使得1.0+DB

我可以这样做:

if (probability == 1) 
    probability = 0.999999999;
else if (probability == 0) 
    probability = 0.000000001;
但这会导致其他数字问题(与数字累积有关)。是否有一种更具原则性的方法,可能是使用数字限制?

您可以通过使用
DBL\u EPSILON
来使用
标题(或者根据您的数据类型使用
FLT\u EPSILON
):

DBL\u EPSILON
被定义为最小值,使得
1.0+DBL\u EPSILON!=1.0
这应该适合您的要求

#include <cfloat>

if (probability == 1.0)
  probability = 1.0 - DBL_EPSILON;
else if (probability == 0.0f)
  probability = DBL_EPSILON;
#包括
如果(概率==1.0)
概率=1.0——DBL_ε;
否则如果(概率==0.0f)
概率=DBL_ε;
或者您可以使用
标题,并可能在浮点类型上对其进行参数化:

#include <limits>
if (probability == 1.0)
  probability = 1.0 - std::numeric_limit<double>::epsilon();
else if (probability == 0.0f)
  probability = std::numeric_limit<double>::epsilon();
#包括
如果(概率==1.0)
概率=1.0-std::numeric_limit::epsilon();
否则如果(概率==0.0f)
概率=标准::数值极限::ε();

实际上,后者返回由第一种方法定义的值,因此在实现上没有区别。

C++
double
变量是双精度浮点数。IEEE 754标准规定二进制64具有:

  • 符号位:1位
  • 指数宽度:11位
  • 有效位精度:53位(显式存储52位)

这将提供15–17位有效十进制数字的精度。如果将最多具有15个有效数字的十进制字符串转换为IEEE 754双精度表示,然后再转换回具有相同有效数字数的字符串,则最终字符串应与原始字符串匹配。查看更多信息。

虽然它的名称可能有点误导,但这正是您要查找的。对于浮点类型,它将为您提供大于零的最小值

对于仍然小于
1
的最大数字,如果使用C++11,则可以使用:

代码
#包括
#包括
#包括
int main(){
printf(“近0:%1.20e\n近1:%1.20e\n”,
标准::数值限制::最小(),
标准:下一步(1.0,0.0)
);
返回0;
} 
结果 接近0:2.2250738585850720138309E-308 近1:9.999999999888978E-01
数值限制应该告诉你
epsilon
rounding\u error
应该特别引起您的兴趣,您也可能喜欢使用
log1p
表示“log(1-p)”。当p接近于零时更准确。请注意,最小的数字是非规范化的,这可能会导致问题。你可能想使用最小的非非正规化的数字。@ RCGLDR,你能详细说明吗?为什么不<代码> STD::EnthimuleBuff:<代码> >代码>::MIN < /C> > zeta:因为他没有指定C++ 11标签。C++之前,C++都是C++的。他们刚刚在C++11中得到了
constexpr
。@Zeta:编辑以反映这两种解决方案,但我没有得到
::min
要求,请澄清一下,“如果您有权访问
”是误导性的。自1998以来,它是标准库的一部分。C++不需要IEEE 754兼容性。它当然不需要现在已经过时的80位扩展双精度类型。@AlanStokes,但Intel编译器和GCC都实现了它。虽然longdouble只需要和double一样珍贵,这是在visualc++中完成的,但它存在于一些平台上。默认情况下,x64、x86上较新版本的gcc以及任何32位版本的Visual Studio都不使用它。而且它一直是英特尔特有的。@AlanStokes OK。我明白了,很有趣。这些值似乎比DBL_ε更极端。有一个问题,根据运行代码的平台,数值_限制是否给出不同的值?是的,因为“[t]这里有三种浮点类型:float、double和long double。double类型提供的精度至少与float相同,long double类型提供的精度至少与double相同。float类型的值集是double类型的值集的子集;double类型的值集是long double类型的值的集合。浮点类型的值表示是实现定义的。“该标准将类型的实际实现留给编译器/平台。
#include<cstdio>
#include<cmath>
#include<limits>

int main(){
  printf("Near 0: %1.20e\nNear 1: %1.20e\n",
    std::numeric_limits<double>::min(),
    std::nexttoward(1.0, 0.0)
  );
  return 0;
} 
Near 0: 2.22507385850720138309e-308 Near 1: 9.99999999999999888978e-01