how to use or ||

Started by
12 comments, last by Khatharr 9 years, 9 months ago

Hi

this seem to be the trouble:

if (rainP <= 0.3 || temperatureC < 0 || cloudAlt <= altibaro){
alSourceStop(Sources[0]);
}else{
alSourcePlay(Sources[0]);
}

I want to stop the sound if either rain is less 0.3 or temp below zero or cloud altitude is below.

But the sound keeps playing even if temp is below zero. Am I doing something wrong and

how to write the above?

Thanks

Advertisement

Not sure if it's the problem, but always collect boolean terms in parentheses:


if ( (rainP <= 0.3) || (temperatureC < 0) || (cloudAlt <= altibaro) ){ ...

Calculation order depends on operator priority. That is, if " || " has a higher priority precedence than " <= ," you'll get strange results.

EDIT: Taking a second look, what values are you getting for those terms when you debug? Perhaps a better approach if your code appears correct: if you're not getting the results you think you should, you should look at the actual data, rather than guessing/hacking at code. If the data is correct, then fix the code. I.e.,


bool rain = rainP <= 0.3;
bool temp = temperatureC < 0;
bool cloud = cloudAlt <= altibaro;
if( ... ) { ... }

Ninja'd by (of course) unbird. biggrin.png

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

That should actually work (with the operator precedence there should be no confusion, so no brackets needed).

There must be something else off (maybe the sound switch off?). Go through with your debugger and inspect those values.

As a general hint: If you don't know/trust what's going on, declare a couple of temporary variables (or even functions), and inspect those, e.g:


bool b1 = rainP <= 0.3;
bool b2 = temperatureC < 0;
bool b3 = cloudAlt <= altibaro;
bool b = b1 || b2 || b3;

Edit: Thinking about it, using parentheses explicitly (even if not needed) isn't that bad. Not only for readability.

Edit2: @Buckeye: Question now is rather who has ninja'd whom ? wink.png
Do you run this code repeatedly while the sound is playing?

Check your values like Buckeye and unbird suggests, also Wooh is hinting at something here:

Why don't you make a flag, a boolean telling if the sound is playing or not, and track state changes rather than be calling playsound or stopsound on every iteration?

But the sound keeps playing even if temp is below zero.

Are you 100% sure the temperature actually goes below zero? Does the code work as expected with the other conditions?

That should actually work (with the operator precedence there should be no confusion, so no brackets needed).

There must be something else off (maybe the sound switch off?). Go through with your debugger and inspect those values.

As a general hint: If you don't know/trust what's going on, declare a couple of temporary variables (or even functions), and inspect those, e.g:


bool b1 = rainP <= 0.3;
bool b2 = temperatureC < 0;
bool b3 = cloudAlt <= altibaro;
bool b = b1 || b2 || b3;
Edit: Thinking about it, using parentheses explicitly (even if not needed) isn't that bad. Not only for readability.

Edit2: @Buckeye: Question now is rather who has ninja'd whom ? wink.png

This is a fantastic idea. In fact, const bools are often used in UE4 for readability purposes. Variables and constants may be self-documenting by themselves, but you can take it a step further as in the below example. For example:


// Before:
if (someDescriptiveVariable < someDescriptiveNumber) {
    // Do stuff
}

// After:
const bool bSomeDescriptiveBool = (someDescriptiveVariable < someDescriptiveNumber);
if (bSomeDescriptiveBool) {
    // Do stuff
}

It may seem unnecessary to some, but let me tell you that it makes for very clean and self-documenting code that other people (not just yourself) can read. I also agree that expressions are generally cleaner when they're surrounded by parentheses.

As for the actual topic, the best thing to do here (as previously mentioned) is to display the values in one way or another.

It should be noted that performing your comparisons using multiple Boolean variables means that you cannot take advantage of short-circuit evaluation.

Thanks. || was ok but a displaced clamp. Below seems fine:

if(state != AL_PLAYING)
{
SourcesPos[0][0] = 0.0;
SourcesPos[0][1] = 0.0;
SourcesPos[0][2] = 0.0;

alSourcefv(Sources[0], AL_POSITION, SourcesPos[0]);
}
if (rainP <= 0.3 || temperatureC < 0 || cloudAlt <= altibaro){
alSourceStop(Sources[0]);
}else if(state != AL_PLAYING){
alSourcePlay(Sources[0]);
}

It should be noted that performing your comparisons using multiple Boolean variables means that you cannot take advantage of short-circuit evaluation.

VS2012, compiled with default release mode settings:


#include <random>
#include <chrono>
#include <iostream>

int main() {
  std::srand(time(NULL));
  int val = rand(); //prevent compiler from just generating the result at compile time

  bool a = val < 10;
  bool b = val > 100;
  bool c = val > 50;
  bool d = val < 60;
  bool result = a || b || (c && d);

  std::cout << result << std::endl; //prevent compiler from skipping process due to unused result
  return 0;
}

Resulting disassembly:


#include <random>
#include <chrono>
#include <iostream>

int main() {
002F1270  push        ebp  
002F1271  mov         ebp,esp  
002F1273  push        ecx  
  std::srand(time(NULL));
002F1274  push        0  
  std::srand(time(NULL));
002F1276  call        dword ptr ds:[2F30BCh]  
002F127C  push        eax  
002F127D  call        dword ptr ds:[2F30C8h]  
002F1283  add         esp,8  
  int val = rand();
002F1286  call        dword ptr ds:[2F30CCh]  
  bool a = val < 10;
002F128C  lea         ecx,[eax-0Ah]  
002F128F  cmp         ecx,5Ah  

  bool result = a || b || (c && d);
002F1292  ja          main+34h (02F12A4h)  
  bool b = val > 100;
  bool c = val > 50;
002F1294  cmp         eax,32h  

  bool result = a || b || (c && d);
002F1297  jle         main+2Eh (02F129Eh)  
  bool d = val < 60;
002F1299  cmp         eax,3Ch  

  bool result = a || b || (c && d);
002F129C  jl          main+34h (02F12A4h)  
002F129E  mov         byte ptr [result],0  
002F12A2  jmp         main+38h (02F12A8h)  
002F12A4  mov         byte ptr [result],1  

  std::cout << result << std::endl;
002F12A8  push        dword ptr ds:[2F3024h]  
002F12AE  mov         ecx,dword ptr ds:[2F303Ch]  
002F12B4  push        dword ptr [result]  
002F12B7  call        dword ptr ds:[2F302Ch]  
002F12BD  mov         ecx,eax  
002F12BF  call        dword ptr ds:[2F3028h]  

  return 0;
002F12C5  xor         eax,eax  
}
002F12C7  mov         esp,ebp  
002F12C9  pop         ebp  
002F12CA  ret  

Compilers are very, very smart.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

This topic is closed to new replies.

Advertisement