Precedence of operators in C - operators

I know that suffix and postfix increment (decrement) have higher predence vs comparison (==) in C.
But I'm running into confusion right now, if I have 2 conditional loops like while (0 != i--)
and while (0!= --i) , so what is the difference there? Because due to precedence the decrement should always be executed first then do the comparision?

i-- "uses" the value of i and then decrements it.
--i decrements i and then "uses" the value of i.
So if i=4 then while(0 != i--){ printf("%d\n", i); } would show 3 (because i is now decremented), 2, 1, 0 (because i was 1 when the check was done).
In the while(0 != --i) { printf("%d\n", i); } you'd get 3 (i is still decremented), 2, 1 but not 0.i` was 0 when the check was performed because it was PREdecremented.

Related

java method: java.lang.Integer.numberOfLeadingZeros(int) can be optimized

the origin code is :
public static int numberOfLeadingZeros(int i) {
// HD, Figure 5-6
if (i == 0)
return 32;
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
I think it can be optimized ,should add following condition:
if (i < 0)
return 0;
the fully optimized code is :
public static int numberOfLeadingZeros(int i) {
if(i<=0) {
return i < 0 ? 0 : 32;
}
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
In theory yes, your suggestion makes sense.
In practice, unless you use an exotic JVM, it will not make any difference because the method is intrinsic, so the code that is executed is not the code you can find in the Java class.
For example on x86/64 cpus, the code is here and uses the bsrl CPU instruction, which is as fast as you can hope for.
Besides the fact that this method will likely get replaced by an intrinsic operation for hot spots, this check for negative numbers is only an improvement, if the number is negative. For positive numbers, it is just an additional condition to be evaluated.
So the worth of this optimization depends on the likelihood of negative arguments at this function. When I consider typical use cases of this function, I’d consider negative values a corner case rather than typical argument.
Note that the special handling of zero at the beginning is not an optimization, but a requirement as the algorithm wouldn’t return the correct result for zero without that special handling.
Since your bug report yield to finding an alternative (also shown in your updated question) which improves the negative number case without affecting the performance of the positive number case, as it fuses the required zero test and the test for negative numbers into a single pre-test, there is nothing preventing the suggested optimization.
Bug has been created on oracle bug database: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8189230

Trouble Understanding Fork Logic

Can someone help me understand what is happening in this segment of code? I am having trouble understanding why the output is how it is. Output is:
0 1 2 3 4
3
2
1
0
int main() {
int i;
for (i = 0; i < 5 && !fork(); i++) {
fflush(stdout);
printf("%d ", i);
}
wait(NULL);
printf("\n");
return 0;
}
Two things here:
First, fork() return 0 in child process while it returns a non zero pid to the parent process.
Second, short circuit of &&.
So in the beginning of the first process (p0), it runs to i < 5 && !fork(). Now i = 0 and another process created (p1). Now for p0, test !fork() fails, it ends the for loop and waiting for child to end. For p1, the test succeeds, and print out 0, then increment i to 1, then it will create process p2 and itself goes out the for loop as p0 did.
Because of short circuiting, when i equals 5, no more fork will be called.

Code for factorials in objective C

Using only for or while statements, I'm trying to come up with a program to generate and print a table of the first 10 factorials. Here's my code:
for (count = 1; count<=10; ++count)
{
n = count;
while (n > 0){
count *= (count-1);
n -= 1;
}
NSLog(#" %2g %3g", count, factorial);
}
I don't understand why this is not working. It never gets out of the loop and goes on forever. What's the correction? Thank you!
The reason:
count *= (count-1);
Since count starts at 1, it will always be reset to 0, so the count <= 10 condition of the outer loop will always be true, hence the infinite looping.
And you're overcomplicating it anyway.
for (int i = 1; i <= 10; i++) {
int r = 1, n = i;
while (n)
r *= n--;
printf("%d! = %d\n", i, r);
}
In Math, n! is the same thing as Γ(n+1) (see: http://en.wikipedia.org/wiki/Gamma_function)
So just use:
-(float)factorial:(float)number1 {
return tgammaf(++number1);
}
This will even work for floats and negative numbers,
other solutions posted are long and extraneous and only work with
positive integers.
During the first loop iteration count is 1 and so also n is 1, then you enter the while and you set count to zero (count-1), and decrease n which becomes zero and you exit the while. So during the second loop iteration count will be zero. You keep decreasing count and it never gets increased, so you never exit the loop until a numeric overflow occurs.
You're doing it harder that what it is (and also inefficient) . Is enough that you keep multiplying n for count to get the factorial:
int n=1;
for (count = 1; count<=10; ++count)
{
n*= count;
NSLog(#"%d",n);
}

Objective C, difference between n++ and ++n

In Objective-C, is there any difference between n++ and ++n (eg. used in a for loop)?
++n; increments the value of n before the expression is evaluated.
n++; increments the value of n after the expression is evaluated.
So compare the results of this
int n = 41;
int o = ++n; //n = 42, o = 42
with the results of this:
int n = 41;
int o = n++; //n = 42, o = 41
In the case of loops:
for (int i = 0; i < j; i++) {/*...*/}
however it doesn't make any difference, unless you had something like this:
for (int i = 0; i < j; x = i++) {/*...*/}
or this:
for (int i = 0; i < j; x = ++i) {/*...*/}
One could say:
It doesn't matter whether to use n++ or ++n as long as no second (related) variable is modified (based on n) within the same expression.
The same rules apply to --n; and n--;, obviously.
++n increments the value before it's used (pre-increment) and n++ increments after (post-increment).
In the context of a for loop, there is no observable difference, as the increment is applied after the code in the loop has been executed.
++n and n++ differ in what the expression evaluates to. An example:
int n = 0;
NSLog(#"%d", n); // 0
NSLog(#"%d", n++); // still 0, increments afterwards
NSLog(#"%d", n); // 1
NSLog(#"%d", ++n); // 2, because it increments first
NSLog(#"%d", n); // 2
In a loop it wont make a difference. Some people say ++n is faster though
In Scott Meyers "More Effective C++" Book he makes a very rational case for preferring prefix increment to postfix increment. In a nutshell, in that language due to operator overloading facilities prefix increment is almost always faster. Objective C doesn't support overloaded operators but if you have or ever will do any C++ or Objective-C++ programming then preferring prefix increment is a good habit to get into.
Remember that most of the time ++n looks like:
n = n + 1
[do something with n]
Whereas n++ looks like (if used as intended):
register A = n; // copy n
[do something with n]
n = A + 1;
As you can see the postfix case has more instructions. In simple for loops most compilers are smart enough to avoid the copy if it's obvious that the pre-increment n isn't going to be used but that case devolves to the prefix case.
I Hope this makes sense. In summary you should use prefix unless you really want the "side-effect" behavior of evaluate then increment that you get from the postfix version.
As stated above,
--n decrements the value of n before the expression is evaluated.
n--; decrements the value of n after the expression is evaluated.
The thing here to note is when using while loops
For example:
n = 5
while(n--) #Runs the loop 5 times
while(--n) #Runs the loop 4 times
As in n-- the loop runs extra time while n = 1
But in --n 1 is first decremented to 0, and then evaluated. This causes the while loop to break.

Given 4 objects, how to figure out whether exactly 2 have a certain property

I have another question on how to make most elegant solution to this problem, since I cannot afford to go to computer school right so my actual "pure programming" CS knowledge is not perfect or great. This is basically an algorhythm problem (someone please correct me if I am using that wrong, since I don't want to keep saying them and embarass myself)
I have 4 objects. Each of them has an species property that can either be a dog, cat, pig or monkey. So a sample situation could be:
object1.species=pig
object2.species=cat
object3.species=pig
object4.species=dog
Now, if I want to figure out if all 4 are the same species, I know I could just say:
if ( (object1.species==object2.species)
&& (object2.species==object3.species)
&& (object3.species==object4.species)
) {
// They are all the same animal (don't care WHICH animal they are)
}
But that isn't so elegant right? And if I suddenly want to know if EXACTLY 3 or 2 of them are the same species (don't care WHICH species it is though), suddenly I'm in spaghetti code.
I am using Objective C although I don't know if that matters really, since the most elegant solution to this is I assume the same in all languages conceptually? Anyone got good idea?
Thanks!!
You can use a hash table (or dictionary in objective-C) with the key on the species, incrementing the count every time.
For clarity (pseudo-code):
// N is 4 for your particular case
for ( int i = 0; i < N; i++ )
hashtable[ object[i].species ]++;
hashtable[ Species.PIG ]; // number of pigs (constant)
or if you want to unroll it manually:
hashtable[ object1.species ]++;
hashtable[ object2.species ]++;
hashtable[ object3.species ]++;
hashtable[ object4.species ]++;
now you can check through the species to see the count:
for each key in hashtable
if ( hashtable[ key ] == 3 ) // species "key" has 3 items
/* Code */
of course, "hashtable" can be just a simple array if species is just a simple enum/integer. The above should be the same theory in either case.
This is precisely what sets and counted sets are for.
BOOL allSameSpecies(NSArray *animals) {
NSSet *speciesSet = [NSSet setWithArray:[animals valueForKey:#"species"]];
return [[speciesSet] count] == 1;
}
BOOL sameSpeciesNumber(NSArray *animals, NSUInteger targetCount) {
NSCountedSet *speciesCounts = [NSCountedSet setWithArray:[animals valueForKey:#"species"]];
for (id species in speciesCounts) {
if ([speciesCounts countForObject:species] == targetCount)
return YES;
}
return NO.
}
You can count how many comparisons match of all possible comparisons. If exactly 1 comparison is true, then exactly 2 items are the same, if 3 comparisons match, exactly 3 items are the same. This example is in C, you'll have to convert it to objective-C on your own.
int count = 0;
count += object1.species == object2.species;
count += object1.species == object3.species;
count += object1.species == object4.species;
count += object2.species == object2.species;
count += object2.species == object3.species;
count += object3.species == object4.species;
// count 0 - all different
// count 1 - exactly 2 are the same
// count 2 - two pairs of 2
// count 3 - exactly 3 are the same
// count 6 - all are the same
The counting can also be implemented as a loop:
for (int i = 0; i < 4; i++)
for (int j = i + 1; j < 4; j++)
count += objects[i].species == objects[j].species;
This approach only works if the amount of objects is 5 or less. Because of this and the fact that the amount of comparisons scales quadratically, it's better to use a hashtable if the amount of objects is larger.