将 ceil 函数的结果转换为整数是安全的吗?

7

C语言中的ceil函数被声明为double ceil(double)。将该函数的返回值强制转换为int类型是安全的吗?我的意思是是否有任何保证以下情况永远不会发生(下面的示例只是为了说明我的意思)?

double r = ceil(234235.53453);
// imagine r = 234235.9999999 due to round errors or
// due to the peculiarities of the machine arithmetics, etc.
int i = (int)r;
// i = 234235, but must be 234236

当然,我知道double的范围比int要大,所以转换可能会失败。但我的问题不是这个,而是关于四舍五入误差或机器算术副作用的。

它可能会被截断,但我想不到任何危险。虽然我不是这方面的专家。 - Iharob Al Asimi
@iharob:使用 long long 可能不行,但使用 int 很好。 - too honest for this site
2个回答

10

一个 64 位的 double 可以精确表示最多 2^53 的整数。当以 double 表示更大的整数时,它们没有任何小数部分。

换句话说,只要所得整数值不超出其可承载的范围,您可以安全地将 ceilfloor 的结果转换为整数。


1
不需要让“double”仅具有64位。 - too honest for this site

6
假设ceil的结果适合于int范围内(或者转换后的类型可能是什么),那么这个强制转换是安全的。只有当被问到的数字不能以二进制精确表示时,舍入误差才会出现。例如,0.5可以作为一个二进制数精确地表示,但是0.1不行。
由于ceil的结果是一个整数,它可以在二进制中被精确表示,所以没有舍入误差,因此是安全的进行转换。
通过将数字表示为约分分数并查看分母,可以确定一个数是否可以表示为终止值或非终止值。如果分母只包含所问的基数的因素,则可以精确表示,否则它是一个无限重复的数字。
回到0.5和0.1的例子,这些数字的约分分数表示是1/21/10。这两个数字都可以在十进制中精确地表示,因为2和10都只包含10的因数。然而只有第一个数可以在二进制中表示,因为10有5作为因子,而2没有。
对于整数,它们都可以表示为一个分母为1的分数。由于1是所有整数的因子,任何整数都可以在任何基数(包括2)下精确地表示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接