WHILE演算子の妙な挙動 - ページ 2

 

これだと違いがないと思います。IF( StringHighStatus == "True" || SwingHighShift > SwingBarcount ) EndCycle = TRUE と書くこともできますね。

要は、IFが終了条件を検出して、WHILEがbool変数に反応するのに対して、WHILEの中に同じ条件を入れても終了しないのはなぜか、ということです。

 
lord_hiro:

これだと違いがないと思います。IF( StringHighStatus == "True" || SwingHighShift > SwingBarcount ) EndCycle = TRUE と書くこともできますね。

ポイントは、IFが終了条件を検出し、WHILEがbool変数に反応するのに対し、WHILEの中に同じ条件を入れても終了しないのはなぜか、という点です。


私にはこれが動作しているように見えます

while (StringHighStatus == "False" &&  SwingHighShift <= SwingBarCount)

として

while (!EndCycle)
   {
   
  ...
      if( StringHighStatus == "True" ) EndCycle = TRUE;
      if( SwingHighShift > SwingBarCount ) EndCycle = TRUE;
   }
 
そう、時には論理を逆転させることで、実現したいことが得られることもあるのです。
 

deVriesさん、もしかしたら間違っているかもしれませんが、一連のIFは論理和のようにブール値をTRUEにするのだと思います。

最初の条件が一致すればEndCycleはTRUEになり、2番目の条件が一致しなければTRUEのままです。

逆に、1つ目の条件を満たさず、2つ目の条件を満たした場合は、TRUEになります。

このとき、WHILEは終了条件を認識します。

つまり、2つのIFが連続すると論理和になり、IF...ELSE IFが連続しても同じように動作するのです。

そして、ORでなければならず、ANDでなければWHILEは動かなくなります(文字列の条件がいつまでも偽のままである可能性があります)。

なぜ、WHILEはサイクル内で設定される一つのブール変数を管理する一方で、条件定義内で同じ論理のOR操作の結果を決定することができないのでしょうか?

このEAは、過去、ビルド600以前、500以前と、多くの人に使われてきました。誰も文句を言いません。

そこで質問ですが、ビルド600以降にWHILE演算子でトラブルを経験された方はいらっしゃいますか?

 
答えはイエスです......しかし、それはビルドとは関係なく、コーディングに大きく関係しているのかもしれません......笑
 
So my question is: is there anyone experiencing troubles with the WHILE operator after build 600? 
ごく基本的なWhileロジックの 操作を、問い合わせるのではなく、その通りに動いているかどうかを確認するためだけに試したことがありますか?
 
lord_hiro:

deVriesさん、もしかしたら間違っているかもしれませんが、一連のIFは論理和のようにブール値をTRUEにするのだと思います。

最初の条件が一致すればEndCycleはTRUEになり、2番目の条件が一致しなければTRUEのままです。

逆に、1つ目の条件を満たさず、2つ目の条件を満たした場合は、TRUEになります。

このとき、WHILEは終了条件を認識します。

つまり、2つのIFが連続すると論理和になり、IF...ELSE IFが連続しても同じように動作するのです。

そして、ORでなければならず、ANDでなければWHILEは動かなくなります(文字列の条件がいつまでも偽のままである可能性があります)。

なぜ、WHILEはサイクル内で設定される一つのブール変数を管理する一方で、条件定義内で同じ論理のOR操作の結果を決定することができないのでしょうか?

このEAは、過去、ビルド600以前、500以前と、多くの人に使われてきました。誰も文句を言いません。

そこで質問ですが、ビルド600以降でWHILE演算子でトラブルが発生した方はいらっしゃいますか?

私は、あなたがこれを参照していると思います。

while (StringHighStatus == "False" || SwingHighShift <= SwingBarCount)

あなたのコードは、もし投稿されたとおりのものであれば、どのビルドでもあなたの期待通りにはならないでしょうから、何かを変更したのでしょう。

   while(StringHighStatus=="False" || SwingHighShift<=SwingBarCount)
     {

      if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)==iHigh(NULL,0,SwingHighShift) && iFractals(NULL,0,MODE_UPPER,SwingHighShift)>Close[0])
        {
         //IF THIS CONDITION IS TRUE AT, FOR EXAMPLE SwingHighShift=10
         StringHighStatus="True";
         SwingHigh=SwingHighShift;
         ObjectDelete("SwingHigh");
         ObjectCreate("SwingHigh",OBJ_VLINE,0,Time[SwingHigh],0);
         ObjectSet("SwingHigh",OBJPROP_COLOR,Red);
         //THEN StringHighStatus="True" BUT SwingHighShift IS NOT INCREASED IN THIS BLOCK OF CODE
         //SO WHEN CONTROL IS HANDED BACK TO THE WHILE OPERATOR, SwingHighShift WILL REMAIN UNCHANGED AT 10
         //SO THIS BLOCK OF CODE WILL BE REPEATED OVER AND OVER CHECKING BAR SHIFT 10, BECAUSE THERE IS NO WAY OUT!
         //HOW TO RESOLVE? SIMPLY USE         
         break;
        }
      else
        {
         SwingHighShift++;
        }

     }
 
deysmacro:
質問ではなく、ごく基本的なwhileロジックの操作だけ で、その通りに動いているかどうか確認したことはありますか?


私の投稿は、今議論しているEAの塊と非常に似た異常な動作を返すと思われるWHILEの例から始まりましたので、まず試してみてから質問しました。

そのごく簡単なデバッグの解釈が間違っていることが判明し、議論はEAそのものに移りました。

 

GumRaiさん、ありがとうございます。

私が間違っていて頭が固いのかもしれませんが、論理が理解できません...。

最初のIFで、ご指摘のようにSwinghHighShift=10で文字列を「真」にすると、そのサイクルではカウントは増えません。その後、制御は WHILEに戻ります。WHILEには論理和があり、その条件の1つが満たされているので、この時点でサイクルが終了するはずです。

逆に、変数がfalseのままなら、カウンタが最大値に達し、再び終了条件となるはずです。

AND演算子であれば、あなたの考察は正しいと思います。

あなたの解釈に従えば、WHILEの中のORをスキップして、最初のIF条件を文字列の上に置くことができます:もし "true "になったらWHILEを終了し、さもなければカウンターは最大値になるまで進みます。

そうでなければ、カウンタは最大値まで進みます。

   while(SwingHighShift<=SwingBarCount)
     {

      if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)==iHigh(NULL,0,SwingHighShift) && iFractals(NULL,0,MODE_UPPER,SwingHighShift)>Close[0])
        {
         
         StringHighStatus="True";
         SwingHigh=SwingHighShift;
         ObjectDelete("SwingHigh");
         ObjectCreate("SwingHigh",OBJ_VLINE,0,Time[SwingHigh],0);
         ObjectSet("SwingHigh",OBJPROP_COLOR,Red);
        
         break;
        }
      else
        {
         SwingHighShift++;
        }

     }


しかし、これはまだ回避策であり、悲しいかな、なぜWHILEがORを処理しないのか(私には)説明できません。

 
lord_hiro:


最初のIFで、例えばSwinghHighShift=10で文字列を「真」にすると、そのサイクルではカウントは増えません。その後、制御はWHILEに戻ります。WHILEには論理和があり、その条件の1つが満たされるので、サイクルはこの時点で終了するはずです。

確かにwhileの条件の1つは満たされていますが、この場合コードは終了せず、forに移行して無限ループに入っています。