什么是0到1之间的最大和最小数字,C ++可以在内部表示而不进行舍入?

时间:2015-08-27 15:24:25

标签: c++ machine-learning double rounding probability

我有一个C ++函数,它根据一个简单的模型计算概率。似乎C ++倾向于将非常小的概率舍入为0,将非常大的概率舍入为1.这导致后续计算中的问题(采用log(p)和log(1-p))。

有没有办法明确表示小于1的最大数字,C ++可以在内部表示而不进行舍入?同样,最小的数字大于0?

我可以这样做:

if (probability == 1) 
    probability = 0.999999999;
else if (probability == 0) 
    probability = 0.000000001;

但这导致其他数字问题(与累积数字有关)。是否有更原则的方式,也许使用numeric_limits?

3 个答案:

答案 0 :(得分:4)

虽然它的名字可能会有些误导,std::numeric_limits<T>::min正是您所寻找的。对于浮点类型,它将为您提供大于零的最小值。

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

代码

#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

答案 1 :(得分:0)

C ++ <body onload = "getSeconds()"> <div id="littlespoon" align ="center"> <span id="countdown" style="color:black; font-size: 50px; font-weight: bold"></span> <button onclick=" countdownTimer = setInterval('secondPassed()', 1000)">Start</button> <button onclick="stopTimer()">Stop</button> </div> <div id="bigfuckingspoon"> <asp:Image ID="Image1" runat="server" ImageUrl="\\scnas1\dev\vbdev\Time\skull.gif" />&nbsp; </div> </body>变量是双精度浮点数。 IEEE 754标准将binary64指定为具有:

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

这给出了15-17个有效小数位数精度。如果具有最多15位有效数字的十进制字符串转换为IEEE 754双精度表示,然后转换回具有相同有效位数的字符串,则最终字符串应与原始字符串匹配。查看this document了解详情。

答案 2 :(得分:-1)

您可以根据您的数据类型使用<cfloat>(或DBL_EPSILON)来使用FLT_EPSILON标头:

DBL_EPSILON被定义为最小值,1.0 + DBL_EPSILON != 1.0应符合您的要求。

#include <cfloat>

if (probability == 1.0)
  probability = 1.0 - DBL_EPSILON;
else if (probability == 0.0f)
  probability = DBL_EPSILON;

或者您可以使用<limits>标头并可能在浮点类型上对其进行参数化:

#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();

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