1

我发现有两种方法可以从 C++ 中的除法中获取整数

问题是哪种方式更有效(更快)

第一种方式:

Quotient = value1 / value2;  // normal division haveing splitted number

floor(Quotient);             // rounding the number down to the first integer

第二种方式:

Rest = value1 % value2;             // getting the Rest with modulus % operator

Quotient = (value1-Rest) / value2;  // substracting the Rest so the division will match

还请演示如何找出哪种方法更快

4

2 回答 2

5

如果您正在处理整数,那么通常的方法是

Quotient = value1 / value2;

就是这样。结果已经是一个整数。无需使用floor(Quotient);语句。无论如何它没有任何效果。如果需要,您会想使用Quotient = floor(Quotient);它。

如果你有浮点数,那么第二种方法根本不起作用,因为%它只为整数定义。但是从实数的除法中得到一个整数是什么意思呢?将 8.5 除以 3.2 得到什么整数?问这个问题有意义吗?

作为旁注,你称之为“休息”的东西通常被称为“提醒”。余。

于 2011-07-23T08:37:08.393 回答
1

使用这个程序:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#ifdef DIV_BY_DIV
#define DIV(a, b) ((a) / (b))
#else
#define DIV(a, b) (((a) - ((a) % (b))) / (b))
#endif

#ifndef ITERS
#define ITERS 1000
#endif

int main()
{
    int i, a, b;

    srand(time(NULL));
    a = rand();
    b = rand();

    for (i = 0; i < ITERS; i++)
        a = DIV(a, b);

    return 0;
}

你可以定时执行

mihai@keldon:/tmp$ gcc -Wall -Wextra -DITERS=1000000 -DDIV_BY_DIV 1.c && time ./a.out 

real    0m0.010s
user    0m0.012s
sys     0m0.000s
mihai@keldon:/tmp$ gcc -Wall -Wextra -DITERS=1000000 1.c && time ./a.out 

real    0m0.019s
user    0m0.020s
sys     0m0.000s

或者,您查看汇编输出:

mihai@keldon:/tmp$ gcc -Wall -Wextra -DITERS=1000000 -DDIV_BY_DIV 1.c -S; mv 1.s 1_div.s 
mihai@keldon:/tmp$ gcc -Wall -Wextra -DITERS=1000000 1.c -S; mv 1.s 1_modulus.s 
mihai@keldon:/tmp$ diff 1_div.s 1_modulus.s 
24a25,32
>   movl    %edx, %eax
>   movl    24(%esp), %edx
>   movl    %edx, %ecx
>   subl    %eax, %ecx
>   movl    %ecx, %eax
>   movl    %eax, %edx
>   sarl    $31, %edx
>   idivl   20(%esp)

如你所见,只做除法更快。

编辑以修复代码、格式和错误差异中的错误。

更多编辑(解释程序集差异):在第二种情况下,首先进行取模时,程序集显示需要两个idivl操作:一个用于获取结果,%一个用于实际除法。上面的差异显示了减法和第二次除法,因为第一个在两个代码中完全相同。

编辑:更多相关时间信息:

mihai@keldon:/tmp$ gcc -Wall -Wextra -DITERS=42000000 -DDIV_BY_DIV 1.c && time ./a.out 

real    0m0.384s
user    0m0.360s
sys     0m0.004s
mihai@keldon:/tmp$ gcc -Wall -Wextra -DITERS=42000000 1.c && time ./a.out 

real    0m0.706s
user    0m0.696s
sys     0m0.004s

希望能帮助到你。

-O0编辑:有和没有装配之间的差异。

mihai@keldon:/tmp$ gcc -Wall -Wextra -DITERS=1000000 1.c -S -O0; mv 1.s O0.s
mihai@keldon:/tmp$ gcc -Wall -Wextra -DITERS=1000000 1.c -S; mv 1.s noO.s
mihai@keldon:/tmp$ diff noO.s O0.s 

由于默认的优化级别gccO0(请参阅本文解释优化级别的文章gcc),结果是预期的。

编辑:如果您-O3按照建议的评论之一进行编译,您将获得相同的程序集,在该优化级别,两种选择都是相同的。

于 2011-07-23T08:16:12.803 回答