0

I have an integer parameter which is supposed to control how many times in a particular run an event occurs.

For example, if the number of iterations for each run is 1000, then the parameter FREQ would be 5, if I wanted to have the event occur every 200 iterations. However, I want to be able to change the number of iterations, but keep the ratio the same, and also to be able to set the FREQ parameter to 0 if I don't want the event to occur at all.

Here is what I am currently using:

int N_ITER = 1000;
int FREQ = 5;

void doRun(){
    int count = 0;
    for (int i = 0; i < N_ITER; ++i){
        if (FREQ > 0){
            if (count < N_ITER/FREQ){
                doSomething();
                count++;
            }
            else{
                doSomethingElse();
                count = 0;
            }
        }
        else{
            doSomething();
        }            
    }
}

This works fine, but it doesn't sit right with me having the nested conditionals, especially when I have two lots of doSomething(), I feel like it should be able to be accomplished more easily than that.

I tried making the one conditional if (FREQ > 0 && count < N_ITER/FREQ) but obviously that threw a Floating point exception because of the divide by zero.

I also tried using a try/catch block, but it really was no different, in terms of messiness, to using the nested conditionals. Is there a more elegant solution to this problem?

guskenny83
  • 1,321
  • 14
  • 27
  • 2
    *"I tried making the one conditional `if (FREQ > 0 && count < N_ITER/FREQ)` but obviously that threw a Floating point exception because of the divide by zero."* That's impossible. `&&` would've short-circuited and prevented evaluation of `N_ITER/FREQ` if `FREQ > 0` was false. – HolyBlackCat Nov 03 '18 at 09:03
  • `continue` helps reduce nesting – Mateen Ulhaq Nov 03 '18 at 09:04
  • @HolyBlackCat: thats what i thought too, but it did, i will check to see if anything else could be throwing the exception, but i don't think so – guskenny83 Nov 03 '18 at 09:05
  • 1
    Also, note that despite the name "floating point exception", it's not actually an exception and you can't `catch` it. Rather, it's a [signal](https://en.cppreference.com/w/cpp/utility/program/signal). – HolyBlackCat Nov 03 '18 at 09:07
  • @guskenny83 This code is only using integers. If you're getting a floating point exception the problem is likely to be somewhere else. – janm Nov 03 '18 at 09:08
  • 1
    @janm Integral division by zero can raise `SIGFPE`. Demo: http://coliru.stacked-crooked.com/a/3b7791e2684a52a2 – HolyBlackCat Nov 03 '18 at 09:09
  • umm, sorry to bother you, but it just turns out i had my "greater than" symbol around the wrong way so it wasnt causing the short circuit.. :-$ ergh, i guess that is what happens when you are staring at the same code for ages, you miss stupid things like that.. – guskenny83 Nov 03 '18 at 09:12
  • 1
    @HolyBlackCat Fascinating. And a floating division by zero is probably returning NaN in this case. – janm Nov 03 '18 at 09:14

1 Answers1

1

How about rearranging the condition? Instead of count < N_ITER/FREQ, use count*FREQ < N_ITER. If FREQ = 0, the expression will still be true.

int N_ITER = 1000;
int FREQ = 5;

void doRun() {
    int count = 0;
    for (int i = 0; i < N_ITER; ++i) {
        if (count*FREQ < N_ITER) {
            doSomething();
            count++;
        } else {
            doSomethingElse();
            count = 0;
        }
    }
}
Nelfeal
  • 12,593
  • 1
  • 20
  • 39
  • This may cause a different kind of UB due to signed integer overflow though. – user7860670 Nov 03 '18 at 09:56
  • @VTT Well, that all depends on the maximum value of `N_ITER+FREQ`, which is far from a large enough value in OP's example. Plus, the type can always be changed to something larger like `unsigned long`. – Nelfeal Nov 03 '18 at 10:16