-
Optimized way of Checking Whether the Number is Multipleof 3 or Not
over 10 years ago
-
about 10 years ago
Hello dear, thanks for Replying. I would like to inform you that the code I had written is tested. You Can check the Performance of both methods.
public static void main(String[] args) { long start = System.nanoTime(); Processing ob=new Processing(); ob.multipleof3(1977); System.out.println((System.nanoTime() - start) / 1000000000.0); long start1 = System.nanoTime(); ob.multiple1of3(1977); System.out.println((System.nanoTime() - start1) / 1000000000.0); } public void multipleof3(int num) { int number=num,countereven=0,counterodd=0; int binary[] = new int[25]; int index = 0; while(number > 0){ binary[index++] = number%2; number = number/2; } for(int i=index-1;i>=0;i--) { if(i%2==0) { if(binary[i]==1) counterodd++; } else if(binary[i]==1) countereven++; } if((counterodd - countereven)%3==0) { System.out.println("Yes, the "+num+"is Divisible/Multiple of 3"); } else System.out.print("No, the "+num+"is Divisible/Multiple of 3"); } public void multiple1of3(int num) { if(num%3==0) { System.out.println("Yes, the "+num+"is Divisible/Multiple of 3"); } else System.out.print("No, the "+num+"is Divisible/Multiple of 3"); }OutPut :
Yes, the 1977is Divisible/Multiple of 3 1.84744E-4
Yes, the 1977is Divisible/Multiple of 3 3.8639E-5 -
-
about 10 years ago
OK; you tested it. But did you test it "enough?" >;->
(Now this might be a bit "unfair," as I'm an expert with many years of experience.)
Instead of 1977, let's try it with 5. I get this result:
Yes, the 5is Divisible/Multiple of 3 1.91338E-4 No, the 5is Divisible/Multiple of 32.3093E-5
That's not good. It contradicted itself.
Turns out that IntelliJ IDEA gives me a hint: On "while(number > 0) {" it says "Condition 'number > 0' is always 'false'". With a little inspection, I see that the input "num" is not used in the "int number=0" initialization. ("num" is only used in the print statements) So really, it's always determining if zero is divisible by three. Never executing the "while" loop could give it a performance advantage.
And on the timings... Doing only a single test call is really too small to time. And including the "System.out.println" calls in the timing can really throw off the numbers.
So, with a bit more testing... And changing "int binary[] = new int[31];" to better match Java "int" type size. (I have to wonder where the number 25 came from, in the original code.)
I get the code I put at http://pastebin.com/r8sGtRnE
Typical results:
Multiples1: 367 Multiples1: 447982408 Multiples2: 366 Multiples2: 5873935
This shows me that the Java native "(num % 3 == 0)" is about two orders of magnitude faster than the bit counting approach.
I can think of some ways to make the bit counting approach faster, using bit shift operations. But making it as fast as "(num % 3 == 0)" would be hard for me to believe.
-
-
about 10 years ago
You did not test this code, did you?
I see two significant errors in this code.
(Well, at least it always tells you that zero is evenly divisible by 3.)
Have you performance tested this code and determined that it is faster than "(num % 3 == 0)"?
-
-
about 10 years ago
It's raining, so I came up with a faster way:
private static int EVEN_BITS = 0xAAAAAAAA; private static int ODD_BITS = 0x55555555; public boolean isAMultipleOf3(int num) { int counterOdd = Integer.bitCount(num & ODD_BITS); int counterEven = Integer.bitCount(num & EVEN_BITS); return ((counterOdd - counterEven) % 3 == 0); }It's still about twice as slow than just doing "% 3 == 0" on the original number.
-

4 Comment(s)