划分两个整数并舍入结果,而不使用浮点

时间:2013-06-09 00:49:40

标签: c++

我需要将两个数字分开并将其四舍五入。有没有更好的方法呢?

int myValue = (int) ceil( (float)myIntNumber / myOtherInt );

我发现不得不投两个不同的时间。 (extern int cast只是为了关闭警告)

注意我必须内部转换才能浮动

int a = ceil(256/11); //> Should be 24, but it is 23
              ^example

7 个答案:

答案 0 :(得分:18)

假设myIntNumbermyOtherInt都是正数,您可以这样做:

int myValue = (myIntNumber + myOtherInt - 1) / myOtherInt;

答案 1 :(得分:9)

在DyP的帮助下,提出了以下无分支公式:

int idiv_ceil ( int numerator, int denominator )
{
    return numerator / denominator
             + (((numerator < 0) ^ (denominator > 0)) && (numerator%denominator));
}

它避免了浮点转换,并通过了一套基本的单元测试,如下所示:


这是避免模运算符的另一个版本。

int idiv_ceil ( int numerator, int denominator )
{
    int truncated = numerator / denominator;
    return truncated + (((numerator < 0) ^ (denominator > 0)) &&
                                             (numerator - truncated*denominator));
}

第一个在IDIV返回商和余数的处理器上会更快(并且编译器足够聪明,可以使用它)。

答案 2 :(得分:1)

整数除法与整理。

每次通话只执行1个分区,没有%*或转换为/来自浮点,适用于正数和负数int。见注释(1)。

n (numerator) = OPs myIntNumber;  
d (denominator) = OPs myOtherInt;

以下方法很简单。 int分为0。对于负商,这是一个向上舍入,因此不需要特殊的东西。对于正商,添加d-1以实现向上舍入,然后执行无符号除法。

注意(1)通常除以0会导致事情发生,MININT/-1会失败,正如2恭维机器所预期的那样。

int IntDivRoundUp(int n, int d) {
  // If n and d are the same sign ... 
  if ((n < 0) == (d < 0)) {
    // If n (and d) are negative ...
    if (n < 0) {
      n = -n;
      d = -d;
    }
    // Unsigned division rounds down.  Adding d-1 to n effects a round up.
    return (((unsigned) n) + ((unsigned) d) - 1)/((unsigned) d);  
  }
  else {
    return n/d;
  }
}

[编辑:删除测试代码,根据需要参见之前的版本]

答案 3 :(得分:1)

只需使用

int ceil_of_division = ((dividend-1)/divisor)+1;

例如:

for (int i=0;i<20;i++)
    std::cout << i << "/8 = " << ((i-1)/8)+1 << std::endl;

答案 4 :(得分:1)

也许这样做更容易:

int result = dividend / divisor;
if(dividend % divisor != 0)
    result++;

答案 5 :(得分:0)

小黑客应该这样做:

int divideUp(int a, int b) {
    result = (a-1)/b + 1;
}
// Proof:
a = b*N + k (always)
if k == 0, then
  (a-1)       == b*N  - 1
  (a-1)/b     == N - 1
  (a-1)/b + 1 == N ---> Good !

if k > 0, then
  (a-1)       == b*N   + l
  (a-1)/b     == N
  (a-1)/b + 1 == N+1  ---> Good !

答案 6 :(得分:-1)

不是在转换为int之前使用ceil函数,而是可以添加一个非常接近(但不完全)等于1的常量 - 这样几乎任何东西(除了与实际完全或非常接近的值之外)在被截断之前,整数)将增加1。

示例:

#define EPSILON (0.9999)

int myValue = (int)(((float)myIntNumber)/myOtherInt + EPSILON);
编辑:在看到你对另一篇文章的回复之后,我想澄清一下,这将会向上舍入,而不是从零开始 - 负数将减少负数,正数将变得更加积极。