1

C ++で除算から整数を取得する方法が2つあります

問題は、どちらの方法がより効率的(より高速)であるかです

最初の方法:

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

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

2番目の方法:

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);必要に応じて使用したいと思います。

%浮動小数点数がある場合、整数に対してのみ定義されているため、2 番目の方法はまったく機能しません。しかし、実数の除算から整数を得るとはどういう意味ですか? 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)

ご覧のとおり、除算のみを行う方が高速です。

コード、フォーマット、間違った差分のエラーを修正するために編集されました。

詳細編集 (アセンブリ diff の説明): 2 番目のケースでは、モジュラスを最初に実行するときに、アセンブリは 2 つのidivl操作が必要であることを示してい%ます。上記の diff は、減算と 2 番目の除算を示しています。最初の除算は両方のコードでまったく同じです。

編集:より関連するタイミング情報:

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 

のデフォルトの最適化レベル ( の最適化レベルについて説明してgccいるこの記事をO0参照) であるため、結果は予期されたものです。gcc

編集:-O3コメントの1つが示唆するようにコンパイルすると、同じアセンブリが得られます。そのレベルの最適化では、両方の選択肢が同じです。

于 2011-07-23T08:16:12.803 に答える