If you are interested in how the pow function can be implemented in practice, you can look at the source code. There is a kind of โabilityโ to search through unfamiliar (and large) codebases to find the section you are looking for, and it would be nice to get some practice.
One implementation of the C library is glibc, which has mirrors on GitHub. I did not find an official mirror, but an unofficial mirror is located at https://github.com/lattera/glibc
First, consider the math/w_pow.c , which has a promising name. It contains the __pow function, which calls __ieee754_pow , which we can find in sysdeps/ieee754/dbl-64/e_pow.c (remember that not all IEEE-754 systems, so it makes sense that the IEEE-754 math code is in its own catalog).
It begins with several special cases:
if (y == 1.0) return x; if (y == 2.0) return x*x; if (y == -1.0) return 1.0/x; if (y == 0) return 1.0;
A little further you will find a comment thread
/* if x<0 */
What brings us to
return (k==1)?__ieee754_pow(-x,y):-__ieee754_pow(-x,y); /* if y even or odd */
So you can see that for negative x and integer y version of glibc pow will calculate pow(-x,y) and then make the result negative if y is odd.
This is not the only way to do something, but I assume this is common to many implementations. You can see that pow filled with special cases. This is often found in library math functions, which should work correctly with unfriendly inputs such as denormals and infinity.
The pow function is especially difficult to read because it is highly optimized code that performs bit-twisting floating point numbers.
Standard c
The C standard (n1548 ยง7.12.7.4) refers to pow :
A domain error occurs if x is finite and negative, and y is finite, not an integer value.
So, according to the C standard, negative x should work.
There is also Appendix F, which gives much more stringent restrictions on how pow works on IEEE-754 / IEC-60559 systems.