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.
: OP , - . . , : , .
:
return (i == buffer.length-1) ? 0 : i+1;
++ ( , , pre-increment )
++
? , ?
return (i++ == N) ? 0 : i; // OP original, slightly rewritten
, , :
i
i == N-1
return
N
return (i == N-1) ? 0 : i+1; // proposed alternative
, :
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).
false
-1 % 2 == -1
-1 = 1 (mod 2)
% , . .
, (*), . "".
(*) : .
i++ % buffer.length , i, - max_int/max_long/max_whatever limit?
i++ % buffer.length
,
i = (i++ == buffer.length) ? 0 : i; return i;
.
, , . modulo ,
255 % 7 == 3
, ( char), , 255 (.. ), 4. 4 ( 256% 7), , (if ternary operator)
if
ternary operator
, 2 (.. 2, 4, 8, 16, 32, 64,...), &.
&
, 16, :
n & 15
64, 63:
n & 63
, . , 2, / , .. . , & , %.
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 =/)
, , , - . , i , buffer.length, i reset.
buffer.length
modulo .
, . , , , .. , reset 0. - , modulo ( , !:)
, if if:
i++; if (i >= buffer.length) { i = 0; } return i;
, buffer.length - .
. modulo, , , , , . , , , .
. Modulo , , . , Java, , .
, - ( !) ( , ), . , - . #codingbydemocracy
modulo , . , , .
, 2, :
idx = (idx + 1) & (length - 1)
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