Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.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++_Floating Point - Fatal编程技术网

C++ 将浮点向上舍入为整数,这有多可靠?

C++ 将浮点向上舍入为整数,这有多可靠?,c++,floating-point,C++,Floating Point,我看过static_cast(std::ceil(floatValue))之前 但我的问题是,我能绝对相信这不是“不必要的”取整吗?我已经读到一些整数不能用浮点表示,所以我担心这个微小的“错误”会欺骗ceil(),使其在逻辑上不应该向上舍入。不仅如此,一旦四舍五入,我担心表示中的一个小“错误”可能会导致数字略小于一个整数,从而导致强制转换为int将其截断 这种担心是没有根据的吗?我记得不久前,python中的一个例子,在这个例子中,打印一个特定的整数会导致打印的内容稍微少一些(比如x.999,尽

我看过
static_cast(std::ceil(floatValue))之前

但我的问题是,我能绝对相信这不是“不必要的”取整吗?我已经读到一些整数不能用浮点表示,所以我担心这个微小的“错误”会欺骗
ceil()
,使其在逻辑上不应该向上舍入。不仅如此,一旦四舍五入,我担心表示中的一个小“错误”可能会导致数字略小于一个整数,从而导致强制转换为int将其截断

这种担心是没有根据的吗?我记得不久前,python中的一个例子,在这个例子中,打印一个特定的整数会导致打印的内容稍微少一些(比如x.999,尽管我记不起确切的数字)

我需要确定的原因是,我正在写一个纹理缓冲区。常见的情况是将整数作为浮点,但它偶尔会在需要四舍五入到包含它们的最接近的整数宽度和高度的值之间出现。它以2次方的步长递增,因此不必要的四舍五入成本可能会导致原本只需要256x256纹理的纹理需要512x512纹理

范围为0.0至~1024.0

这个范围内的所有整数都可以精确地表示为
float
,这样就可以了


只有在超出了
浮点值

所能提供的范围后,才会出现问题。如果
浮点值
是精确的,那么代码中的舍入就没有问题。唯一可能的问题是溢出(如果结果不适合
int
)。当然,对于如此大的值,
float
通常没有足够的精度来区分相邻的整数

然而,危险通常在于
floatValue
本身不准确。例如,如果它是某个精确答案为整数的计算结果,则由于计算中的浮点舍入错误,它可能最终比整数大一小部分

因此,您是否有问题取决于如何获得
floatValue

我能绝对相信这不是“不必要的”取整吗?我读到一些整数不能用浮点表示,所以我担心这个微小的“错误”会欺骗ceil()

是的,有些大数字不可能精确地表示为浮点数。在发生这种情况的区域中,所有浮点数都是整数。错误并不是很小:用浮点表示整数的错误(如果有错误的话)至少有一个。显然,在某些整数不能表示为浮点且所有浮点数都是整数的区域,
ceil(f)=f

对于IEEE 754单精度,该区域为| f |>224(16*1024*1024),对于IEEE 754双精度,该区域为| f |>253

您更可能遇到的问题不是无法用浮点格式表示整数,而是舍入错误的累积影响。如果您的编译器提供IEEE 754(由现代和不太现代的英特尔处理器的SSE2指令完全实现的浮点标准)语义,则任何产生可精确表示为浮点的数字的+、-、*、/和sqrt操作都保证产生该结果,但是,如果应用的几个操作没有可精确表示的结果,则浮点计算可能会偏离数学计算,即使最终结果是整数且可精确表示。然后,您可能会得到略高于目标整数的浮点结果,并导致
ceil()
返回与精确数学计算不同的结果


有些方法可以确保某些浮点运算是精确的(因为结果总是可以表示的)。例如
(double)float1*(double)float2
,其中
float1
float2
是两个单精度变量,总是精确的,因为两个单精度数字相乘的数学结果总是可以表示为
double
。通过以“正确”的方式进行计算,可以最小化或消除最终结果中的误差。

这取决于
floatValue
的范围。范围是什么?范围是0.0到~1024.0(我不认为我需要担心超出该范围的值)。不能表示为浮点数的整数将舍入到另一个整数(二的某个幂的倍数),而不是略低于或高于该整数的某个分数。但是,某些(对于实数)会产生整数的算术可能会产生略小于或大于整数的结果。然而,这与你如何绕过它无关,因为它是事先发生的。@delnan-我根本不知道这一点。在常见情况下,浮点数的来源是从
int
强制转换而来。知道这些小错误来源于算术,而不仅仅是它们的表示方式,让我对它们更加放心,但这些问题将围绕着整数转换成其他整数,而不是50亿变成50亿,再等等。