今日の呟き

今日の呟き

アバター
V30
記事: 21
登録日時: 11年前
住所: 岡山県

今日の呟き

投稿記事 by V30 » 10年前

CODE:

0以上のint型の値を返す関数が3つあります。

int Func1();
int Func2();
int Func3();

この関数全ての返り値が0である場合に真となる条件式を使った条件判断文を、if文とwhile文で3個ずつ作ります。

if文1:		if (Func1() == 0 && Func2() == 0 && Func3() == 0) {}
if文2:		if (Func1() + Func2() + Func3() == 0) {}
if文3:		if ((Func1() | Func2() | Func3()) == 0) {}
while文1:	while (Func1() == 0 && Func2() == 0 && Func3() == 0) { break; }
while文2:	while (Func1() + Func2() + Func3() == 0) { break; }
while文3:	while ((Func1() | Func2() | Func3()) == 0) { break; }

DXライブラリを使い、上記条件判断文6つの処理速度を個々にGetNowHiPerformanceCount()で計測した所、処理時間の値[マイクロ秒]が概ね

if文1:		200
if文2:		  0
if文3:		200
while文1:	  0
while文2:	200
while文3:	  0

になりました。



if文を使用する際はif文2を、while文を使用する際はwhile文1またはwhile文3を採用すれば良いのが結果として現れていますが、同じ条件式でもif文とwhile文で真逆の結果になるのは理解に苦しみます。

コンパイラ依存と考え、取り敢えずは単純に速そうなのを使う事に決めました。
最後に編集したユーザー V30 on 2014年9月28日(日) 23:27 [ 編集 1 回目 ]

zxc
記事: 79
登録日時: 13年前

Re: 今日の呟き

投稿記事 by zxc » 10年前

CODE:

if (Func1() == 0 && Func2() == 0 && Func3() == 0) {}
if (Func1() + Func2() + Func3() == 0) {}
 この二つの条件式は意味合いが違うような気がします。
 (負の値がどうやっても返ってこないとして、)下は全てが0でないとtrueは得られませんが、上では「A: 2つの関数が0を返すか否か」と「B: もう一つの関数が0と等しいかどうか」の論理積(?)になるような気がします。要するに上の関数では、AとBが両方ともtrueもしくはfalseを返すことでAとBが等しいような状況であっても条件を満たすのではないでしょうか。
  参考
  

アバター
みけCAT
記事: 6734
登録日時: 14年前

Re: 今日の呟き

投稿記事 by みけCAT » 10年前

if/while文2の撃墜例を置いておきますね。(環境依存:Ideone.comでは成功する)

CODE:

#include 

int Func1() {return 1500000000;}
int Func2() {return 1400000000;}
int Func3() {return 1394967296;}

int main(void) {
	printf("Func1() = %d\n", Func1());
	printf("Func2() = %d\n", Func2());
	printf("Func3() = %d\n", Func3());

	if (Func1() == 0 && Func2() == 0 && Func3() == 0) {
		puts("Func1() == 0 && Func2() == 0 && Func3() == 0 (puttern 1)");
	}
	if (Func1() + Func2() + Func3() == 0) {
		puts("Func1() == 0 && Func2() == 0 && Func3() == 0 (puttern 2)");
	}
	return 0;
}

ISLe
記事: 2650
登録日時: 14年前

Re: 今日の呟き

投稿記事 by ISLe » 10年前

短絡評価(ショートサーキット)は言語仕様で規定されています。

文1では、Func1()の戻り値が0でないとき、Func2(),Func3()は呼び出されません。
Func1()の戻り値が0であったとき、Func2()の戻り値が0でないとき、Func3()は呼び出されません。

文2,文3では、常にFunc1(),Func2(),Func3()すべて呼び出されます。

なので、時間計測の結果が信頼できないですね。

アバター
みけCAT
記事: 6734
登録日時: 14年前

Re: 今日の呟き

投稿記事 by みけCAT » 10年前

失礼します。
zxc さんが書きました:

CODE:

if (Func1() == 0 && Func2() == 0 && Func3() == 0) {}
if (Func1() + Func2() + Func3() == 0) {}
 この二つの条件式は意味合いが違うような気がします。
確かにそうですね。下の条件式に対する撃墜例を投稿しました。
また、短絡評価の観点でも意味合いが違います。
zxc さんが書きました:(負の値がどうやっても返ってこないとして、)下は全てが0でないとtrueは得られませんが、
下は自分が投稿した撃墜例にあるように、全てが正であってもtrueが得られます。
「上は全てが0でないと~」の間違いではないでしょうか?
zxc さんが書きました:上では「A: 2つの関数が0を返すか否か」と「B: もう一つの関数が0と等しいかどうか」の論理積(?)になるような気がします。
「A:Func1()とFunc2()の戻り値が両方0であるか否か」と「B:Func3()の戻り値が0であるかどうか」と補正すれば、正しいと思います。
【訂正】「A:Func1()とFunc2()の戻り値が両方0である」と「B:Func3()の戻り値が0である」と補正すれば、正しいと思います。
zxc さんが書きました:要するに上の関数では、AとBが両方ともtrueもしくはfalseを返すことでAとBが等しいような状況であっても条件を満たすのではないでしょうか。
「上の関数」というのがよくわかりませんが、AとBの論理積は、AとBが両方trueである場合のみtrueです。
(AとBが両方ともtrue)もしくは(AとBが両方ともfalse)のときtrue、それ以外の時falseになるのは、
論理積ではなくて双条件文だと思います。
zxc さんが書きました:  参考
  
このサイトにも
3 論理演算子 さんが書きました:&& 論理積(かつ) 両方とも1(真)のときのみ1(真) 
という記述がありますね。
最後に編集したユーザー みけCAT on 2014年9月29日(月) 00:47 [ 編集 1 回目 ]
理由: 論理積を取る対象の命題に「かどうか」という謎表現が入っているのはよくない

zxc
記事: 79
登録日時: 13年前

Re: 今日の呟き

投稿記事 by zxc » 10年前

 そうですね。上下と論理積その他諸々の記述について私が間違っていたようです。失礼しました。