The C language lacks an operator that squares a value or, more generally, raises a value to a specific power. To do so, use the pow() function. Yet I’m finding the need for a square() function as I explore some interesting and obscure mathematical thingies.
In my digital travels, I’ve seen a few “square” or “power” operators. Perhaps the most common is the caret, ^
, as in 2^5
which raises two to the fifth power. Remember that in C, the ^
is the bitwise exclusive OR operator.
Another exponent operator I’ve seen is **
as in 2**5
, which raises two to the fifth. In C, **
is used to identify a pointer to a pointer (an array of pointers).
The lack of an exponent operator in C means that programmers use the pow() function to raise a value to a specific power:
pow(2,5);
The above statement raises two to the fifth power. It requires that you include the math.h
header file. On some systems, you must also remember to link in the math library (-lm
) on the command line.
Squaring a value happens frequently in math. The way I often code it in C is to write alpha*alpha
as opposed to pow(alpha,2);
I would guess that alpha*alpha
probably calculates faster internally.
The following code demonstrates both methods to square a value:
2024_03_16-Lesson-a.c
#include <stdio.h> #include <math.h> int main() { int alpha = 5; printf("Alpha = %d\n",alpha); printf("Alpha squared is %d\n",alpha*alpha); printf("Alpha squared is %.f\n",pow(alpha,2) ); return 0; }
Here is the output:
Alpha = 5
Alpha squared is 25
Alpha squared is 25
If I’m desperate for a square() function, I could write one. But instead, I think it would be better and more nerdy to code a macro, as shown in this update to the code:
2024_03_16-Lesson-b.c
#include <stdio.h> #include <math.h> #define squared(a) a*a int main() { int alpha = 5; printf("Alpha = %d\n",alpha); printf("Alpha squared is %d\n",alpha*alpha); printf("Alpha squared is %.f\n",pow(alpha,2) ); printf("Alpha squared is %d\n",squared(alpha) ); return 0; }
The squared() “function” is really a macro. It accepts an argument, represented as a
in the definition, then replaces it with a*a
:
#define squared(a) a*a
In the code, the final printf() statement is translated by the precompiler to this:
printf("Alpha squared is %d\n",squared(alpha*alpha) );
The output is the same as the first printf() statement. I don’t think the macro saves any time, but it does add to readability, which is what I wanted.
Well, what I’d really want is an exponent operator, but that’s never going to happen in the C language.
Pow always makes me think of a Roy Lichtenstein cartoon.
I agree that calling pow is probably slower, firstly just because it’s a function call and secondly because the function needs to allow for fractional and negative powers (roots and reciprocals) so needs to check for those before simply multiplying in a loop. I think modern compilers convert stuff like this to bit shifts where possible.
Maybe you could write a couple of tests to time pow and multiplication over, say, a million times to see what the performance difference is.
Your wish is granted!
At one million spins, using pow() to calculate 5 squared ran in 0.032s.
At one million spins, using 5*5 to calculate 5 squared ran in 0.007s.
On modern systems, this isn’t much of a different, but I believe you’re correct in that the overhead required for pow() to provide for all exponentiation makes a huge difference in performance.
The problem with macros, as I see it, is that one has to take extra care to make sure they donʼt leak⁽¹⁾.
Now I realize this is a blog for newcomers to the language… but to make the above less leaky one would have, as youʼre surely aware, surround every use of macro arguments with extra parentheses. (Or even go one step further, and use typeof in conjunction with GNU Cʼs Statements and Declarations in Expressions.)
The upshot of all of this is that I truly think inline functions are the better choice most of the time.
That being said… relying on not too complicated macro trickery I came up with the following, to allow for compile time expansion of literal exponent values for pow():
#include <stdio.h> /* (f)printf() */
#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */
#define POW_0(x) 1
#define POW_1(x) (x)
#define POW_2(x) ((x) * POW_1(x))
#define POW_3(x) ((x) * POW_2(x))
#define POW_4(x) ((x) * POW_3(x))
#define POW_5(x) ((x) * POW_4(x))
//… should probably go higher, the above only supports up to POW_5() for now.
#define POW_EXPAND_N(x, N) POW_##N(x)
#define POW_N(x, N) POW_EXPAND_N(x, N)
#define EXP 5
int main (void)
{ int x = 2;
int result = POW_N(x, EXP);
fprintf (stdout, "%d^%d == %d\n", x, EXP, result);
return (EXIT_SUCCESS);
}
Admittedly, such a POW() macro is probably of no value in real code… at least I had some fun writing it up ☺
⁽¹⁾ Referencing Joel Spolskyʼs essay on the Law of Leaky Abstractions, Peter Seibel gives a good (Lisp-based) example of a “leaky macro” (do-primes) in chapter 8 of his classic book Practical Common Lisp.
Excellent point! I’ve written about that before, so I just slipped here with the macro example. Thanks!
I’m probably completely misunderstanding all this but I threw together a bit of code which breaks the squared macro by preceding it with a division, thus losing the precedence of exponentiation over multiplication/division. The problem is then fixed by including brackets in a separate macro.
#include <stdio.h>
#include <math.h>
#define squared(a) a*a
#define squared_b(a) (a*a)
int main()
{
// 12 / 2² = 3
// BUT
// this precompiles to
// 12 / 2 * 2
// which evaluates to 12
int a = 12 / squared(2);
printf(“12 / squared(2) = %d\n”, a);
// This precompiles to
// 12 / (2 * 2)
// which is much nicer 🙂
int b = 12 / squared_b(2);
printf(“12 / squared_b(2) = %d\n”, b);
return 0;
}
Awesome example, Chris.