Circular increase: which is better?

When you have a circular buffer represented as an array and you need an index to traverse (i.e. when you reach the highest possible index and increase it), is this better:

return (++i == buffer.length) ? 0: i;

Or

return ++i % buffer.length;

Does the modulo operator exploit any flaws? Is it less readable than the first solution?

EDIT:

Of course, it should be ++ i instead of i ++, it changed.

EDIT 2:

One interesting note: I found the first line of code in the implementation of ArrayBlockingQueue by Doug Lee.

+5
source share
12 answers

: OP , - . . , : , .

:

return (i == buffer.length-1) ? 0 : i+1;

++ ( , , pre-increment )

? , ?

return (i++ == N) ? 0 : i; // OP original, slightly rewritten

, , :

  • i - post -incremented, , i == N-1 return, N 0
    • ? , N
  • i , ?
    • , , -

:

return (i == N-1) ? 0 : i+1; // proposed alternative

, :

  • i , ,
  • i == N-1, 0,

%

% :

return (i+1) % N;

%? , , , , ! (JLS 15.17.3). . :

boolean isOdd(int n) {
   return (n % 2) == 1; // does this work???
}

!!! false ! , -1 % 2 == -1, -1 = 1 (mod 2).

% , . .

.

+10

, (*), . "".

(*) : .

+5

i++ % buffer.length , i, - max_int/max_long/max_whatever limit?

,

i = (i++ == buffer.length) ? 0 : i;
return i;

.

+3

, , . modulo ,

:

255 % 7 == 3

, ( char), , 255 (.. ), 4. 4 ( 256% 7), , (if ternary operator)


, 2 (.. 2, 4, 8, 16, 32, 64,...), &.

, 16, :

n & 15

64, 63:

n & 63

, . , 2, / , .. . , & , %.

+3

ArrayIndexOutOfBoundsException, reset 0.

() ( ), == Integer.MAX_VALUE ( , , IMHO).

, , " ", - :

i = (i+1) % buffer.length;
return i;

, .

, , ( ) . (? ! !)

public class asdf {

    static int i=0;
    static int[] buffer = {0,1,2};

    public static final void main(String args[]){
        for(int j=0; j<5; j++){
            System.out.println(buffer[getIndex()]);
        }
    }

    public static int getIndex(){
//      return (++i == buffer.length) ? 0: i;
//      return ++i % buffer.length;

//      i = (i++ == buffer.length) ? 0 : i;
//      return i;

//      i++;
//      if (i >= buffer.length) 
//      {
//        i = 0;
//      }
//      return i;

//      return (i+1 == buffer.length) ? 0 : i+1;

        i = (i+1) % buffer.length;
        return i;
    }

}

: 1 2 0 1 2

, , -! x.x

PS: +1 , post-increment ( upmod posts =/)

+3

, , , - . , i , buffer.length, i reset.

modulo .

+2

, . , , , .. , reset 0. - , modulo ( , !:)

+1

, if if:

i++;
if (i >= buffer.length) 
{
  i = 0;
}
return i;

, buffer.length - .

+1

. modulo, , , , , . , , , .

. Modulo , , . , Java, , .

, - ( !) ( , ), . , - . #codingbydemocracy

+1

modulo , . , , .

0

, 2, :

idx = (idx + 1) & (length - 1)
0

:

idx = idx & ((idx-length)>>31)

, if- .

#:

Stopwatch sw = new Stopwatch();
long cnt = 0;
int k = 0;
int modulo = 10;

sw.Start();
k = 0;
cnt = 0;
for ( int j=0 ; j<100000000 ; j++ ) {
    k = (k+1) % modulo;
    cnt += k;
}
sw.Stop();
Console.WriteLine( "modulo cnt=" + cnt.ToString() + "     " + sw.Elapsed.ToString() );
sw.Reset();


sw.Start();
k = 0;
cnt = 0;
for (int j = 0; j < 100000000; j++) {
    if ( ++k == modulo )
        k = 0;
    cnt += k;
}
sw.Stop();
Console.WriteLine( "if     cnt=" + cnt.ToString() + "     " + sw.Elapsed.ToString() );
sw.Reset();

sw.Start();
k = 0;
cnt = 0;
for (int j = 0; j < 100000000; j++) {
    ++k;
    k = k&((k-modulo)>>31);
    cnt += k;
}
sw.Stop();
Console.WriteLine( "bit    cnt=" + cnt.ToString() + "     " + sw.Elapsed.ToString() );

:

modulo cnt=450000000     00:00:00.6406035
if     cnt=450000000     00:00:00.2058015
bit    cnt=450000000     00:00:00.2182448
0
source

All Articles