I'm trying to convert RGB to HSL with this article http://130.113.54.154/~monger/hsl-rgb.html as a guide. The second step is to find the min and max values in the R, G, and B channels.
So my question is, if I have three values, how do I determine which is the biggest and which is the smallest?
Compare the first two values. Decide which is larger. Is that value larger than the 3rd value? If so, it is the largest of the three. If not, the 3rd value is the largest of the three.
int max3(int a, int b, int c)
{
int maxguess;
maxguess = max(a,b); // biggest of A and B
maxguess = max(maxguess, c); // but maybe C is bigger?
return(maxguess);
}
No, that's no macro, this is regular C syntax. Andrew is using the conditional operator ?: which is basically an if inside a calculation
You should look it up, it's not that complicated and help with understanding C programming.
And just for the reference, max is defined this way:
#define max(a,b) ((a)>(b)?(a):(b))
So Andrew's proposal is exactly the same as writing:
max (max (R, G), B)
Which is by the way a lot better than the code from westfw, because it'll work on all numeric and other comparable types correctly and you don't have to pray the the optimiser removes all the cruft introduced by the function.
You should look it up, it's not that complicated and help with understanding C programming.
I hear you. I have tried to decode some obfuscation some have posted in the past. Sometime I can even figure it out with proper references, but my problem usually is that I would never actually be able to remember and use it without again looking it up.
Peoples brains are wired differently and some have no problems with understanding and retaining weird C usage, but not me. My background and experience is on the hardware side of things and I'm just satisfied if I can get my code to compile and perform what I need doing.
Now, max (max (R, G), B), makes perfect sense to me even on first reading, why would someone chose to use (R>G?R:G)>B?(R>G?R:G):B instead?
Another part of C that has almost been forgotten is that it can take a variable number of variables. In fact this link is a max() example where you can pass in 1 or more integers and it returns the largest one.
Andrew is using the conditional operator ?: which is basically an if inside a calculation
Actually - its called the "ternary operator":
Quite common to use, but Andrew's version has to be one of the more obfuscated-looking uses of it I have seen in a while...
:o
Generally - if you need or want to use a ternary operator in such a fashion, it is best to put a comment above it that explains -exactly- in detail what it is doing.
Now, max (max (R, G), B), makes perfect sense to me even on first reading, why would someone chose to use (R>G?R:G)>B?(R>G?R:G):B instead?
Well - what is max() doing inside the function? What does the ternary operator do? More importantly, what does the resulting assembler code look like between them?
I would imagine (but I could be wrong - optimization by the compiler and such may negate the following) that the ternary operator would be faster in certain situations, because there wouldn't be any stack/heap operations needed to push/pop arguments and data (arguments and return values), plus the jumps to the function calls, etc...
That would be one argument for using it vs using the max() construct (assuming I am not wrong regarding the compiler optimizing things, of course). Use of it vs. max() would need to be thought about carefully; in a tight loop doing such comparisons, the ternary operator might be the better choice (with a comment detailing the code, of course) - in other situations where it isn't called as often, the max() construct version might be better from a code maintenance standpoint (and clarity of code).
Well - what is max() doing inside the function? What does the ternary operator do? More importantly, what does the resulting assembler code look like between them?
Crosh, Check my post #6 in this thread, it's all answered there. The assembly code is even without optimisation identical.
Now we're getting real low level, as readability would knock out both arguments presented as 'pro ternary' before the match even started.
Nope, max() is just a macro, same code, no difference. Min also, in case you wonder.
I have no objections to max(a, max(b, c));
Even if it does use the ternary operator internally.
(I was wondering if anyone would point out that max() usually (always?) is implemented with the ternary operator.) (R>G?R:G)>B?(R>G?R:G):B is still evil, though.
[...]max() is just a macro, same code, no difference.
If you're trying to say that there is no incentive to use code that helps readability I feel like we're going to have a discussion If you agree that one should make code readable, I suggest that you read my post again before you say 'Nope'...
Just to make it clear, I would never in a million years recommend using that expression, even if it did shave a few nanoseconds off execution time. At least for the stuff I do, being able to read and understand it in a year's time is far more important than absolute speed.
Basically I just like neat things, and the ternary operator is kind of neat. As is my favourite equation of all time:
If you're trying to say that there is no incentive to use code that helps readability I feel like we're going to have a discussion
Sorry, my quote wasn't that good. The "nope" was about ternary being in any way faster than the max macro. If you need the max function, use it instead of ternary without any penalty.
@Korman but there IS a penalty using the macro if you always test with B being the greatest. And as such, some situations will perform better by using the nested ternary