【问题标题】:Why is the return type of the "ceil()" function "double" instead of some integer type?为什么“ceil()”函数的返回类型是“double”而不是某个整数类型?
【发布时间】:2017-06-07 23:10:02
【问题描述】:

我刚刚实现了一行代码,其中两个数字需要相除,结果需要四舍五入到下一个整数。我开始很天真:

i_quotient = ceil(a/b);

由于数字 ab 都是整数,所以这不起作用:除法作为整数除法执行,默认情况下四舍五入,所以我需要强制除法为浮点数点操作:

i_quotient = ceil((double) a / b);

现在这似乎可行,但它留下一个警告说我正在尝试将双精度分配给一个整数,实际上,在头文件“math.h”之后,ceil() 函数的返回类型是“双”,现在我迷路了:舍入函数返回双精度是什么意思?有人能告诉我吗?

【问题讨论】:

  • 如果参数太大而无法用整数类型表示,您将如何指定ceil?例如。 1E500?
  • 你为什么不做i_quotient = (a + b - 1) / b;

标签: c types type-conversion


【解决方案1】:

double 的范围可以大于任何整数类型。 返回double 是确保结果类型具有可以处理所有可能输入的范围的唯一方法。

【讨论】:

  • 抛开一个实现可以提供比double可以表示的位数更多的整数,double的精度可能低于long long
  • @Olaf:即使在整数类型的位数超过 double 可以表示的那些极其罕见的实现中,无限值仍然超出整数类型的范围。
  • @chqrlie:你应该专注于我评论的后半部分。在所有具有 64 位 double(x86/x86/ARM 等)的架构上,long long 始终具有更高的有效位。对于 LP64(例如 POSIX 64),这也适用于 long。我并没有说它们可以代表相同的范围,也不使用double 是一个好主意。
  • @Olaf:好吧,你的措辞有点混乱,double 可以表示大于 64 位的值,但可能会降低精度。这都是一个有争议的问题。为double 类型的所有值定义了返回doubleceil()。如果返回整数类型,很多情况下结果会不正确。
  • @chqrlie:“...... double 的精度可能低于 long long” 听起来很清楚。我从来没有写过范围。前半部分是指整数类型的宽度没有上限。但我同意这是一个更深奥的选择。
【解决方案2】:

ceil()double 作为参数。那么,如果要返回一个整数,您会选择哪种整数类型仍然可以表示其上限值? 无论类型是什么,它都应该能够表示所有可能的双精度值。

可以容纳最高可能值的整数类型是uintmax_t。 但这并不能保证它可以保存所有 double 值,即使在某些实现中它也可以。

因此,为ceil() 返回一个double 值是有意义的。如果需要整数值,则调用者始终可以将其转换为所需的整数类型。

【讨论】:

    【解决方案3】:

    OP 以两个整数 a,b 开头,并质疑为什么采用 double 的函数 double ceil(double) 不返回某些整数类型。

    大多数浮点数学函数采用浮点参数并返回相同的类型。

    double ceil(double) 不返回整数类型的一个重要原因是很少需要有限的功能。整数类型具有(或几乎总是具有)比double 更有限的范围。 ceil(DBL_MAX) 不适合整数类型。


    几乎不需要使用double 数学来解决整数问题。

    如果代码需要对整数进行除法并对商进行四舍五入,请使用以下代码。参考:@mch

    i_quotient = (a + b - 1) / b;
    

    a >= 0b > 0 时,上面将处理大部分OP 的情况。当ab 为负数或a + b - 1 可能溢出时,需要考虑其他因素。

    【讨论】:

      【解决方案4】:

      因为为什么要呢?在 int 和 double 之间转换需要时间。这种开销可能会变得很大。如果您想将 double 转换为 int,请明确这样做:

      i_quotient = (int)ceil((double) a / b);
      

      如果您想了解有关此延迟的更多信息,请查看this answer。你必须考虑到 C 已经过时了,可实现的性能是首要任务之一。但即使是 C# 和其他现代语言,通常也会为 ceil 返回一个浮点值,只是为了保持一致性。

      【讨论】:

        【解决方案5】:

        抛开技术讨论,不能只是为了保持一致性吗?

        如果函数采用双精度类型,它应该返回相同类型的结果,如果没有特殊原因返回不同类型。 如果需要,用户可以将其转换为整数。 毕竟,您可能只在应用程序中使用双打。

        虽然ceil的意思是四舍五入到下一个整数,但严格来说并不意味着它是一个整数,很明显整数是一个整数,但这并不影响我们的想法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-01-06
          • 1970-01-01
          • 2016-04-05
          • 1970-01-01
          • 2014-04-09
          • 1970-01-01
          • 2012-03-14
          相关资源
          最近更新 更多