c++内部可以表示的0到1之间不舍入的最大和最小的数是什么?
what are the largest and smallest numbers between 0 and 1 that C++ can represent internally without rounding?
我有一个基于简单模型计算概率的c++函数。c++似乎倾向于将非常小的概率舍入为0,而将非常大的概率舍入为1。这将导致在以后的计算中出现问题(取log(p)和log(1-p))。
是否有一种方法可以显式地表示c++内部可以不舍入表示的小于1的最大数字?同样,大于0的最小数是多少?
我可以这样做:
if (probability == 1)
probability = 0.999999999;
else if (probability == 0)
probability = 0.000000001;
,但这会导致其他数值问题(与累积数字有关)。是否有一个更有原则的方法,也许使用numeric_limits?
虽然它的名字可能有点误导,但std::numeric_limits<T>::min
就是您要找的。对于浮点类型,它将为您提供大于零的最小值。
对于仍然小于1
的最大数字,如果使用c++ 11,则可以使用std::nexttoward
:
#include<cstdio>
#include<cmath>
#include<limits>
int main(){
printf("Near 0: %1.20enNear 1: %1.20en",
std::numeric_limits<double>::min(),
std::nexttoward(1.0, 0.0)
);
return 0;
}
结果<>之前接近0:2.22507385850720138309e-308近1:9 . 99999999999999999999888978e -01 c++ double
变量为双精度浮点数。IEEE 754标准指定binary64具有:
- 符号位:1位
- 指数宽度:11位
- 有效精度:53位(52显式存储)
给出15-17位有效十进制数字的精度。如果将最多包含15位有效数字的十进制字符串转换为IEEE 754双精度表示,然后再转换回具有相同有效数字数量的字符串,则最终字符串应与原始字符串匹配。
您可以通过使用DBL_EPSILON
(或FLT_EPSILON
根据您的数据类型)来使用<cfloat>
头:
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();
实际上后者返回由第一种方法定义的值,因此在实现上没有区别。
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++将浮点指针值舍入为小数位数
- C++从另一个类访问公共静态向量的正确方法是什么
- 将一系列整数放入类的最佳方法是什么?
- 根据浮点符号对浮点进行舍入的最简单方法是什么
- 将随机数放入缓冲区以写入文件的有效方法是什么?
- 读取四个数据文件并使用函数将它们放入结构数组的最佳方法是什么
- 是整数舍入规则决定了 C++、python3 和 python2.7 之间的 % 操作差异吗?
- 实现整数除法向上舍入的正确方法是什么?
- 对应该返回的双精度变量进行舍入,而不是打印
- 受保护成员辅助功能额外签入C++的原因是什么?
- 将 8 位整数放入 16 位整数数组的最快方法是什么
- 将大型对象放入堆中的最佳方式是什么
- 将一些数据放入std::vector的最佳方式是什么?
- c++内部可以表示的0到1之间不舍入的最大和最小的数是什么?
- 将jpeg放入MySQL表所需的基本c++代码是什么?
- 将双精度值舍入到(稍微)较低精度的好方法是什么?