我有一个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?
答案 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"
/>
</div>
</body>
变量是双精度浮点数。 IEEE 754标准将binary64指定为具有:
这给出了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();
实际上后者返回第一种方法定义的值,因此实现没有区别。