It may be instructive to learn why you're seeing those exact numbers: the type double is a binary type that has 53 bits of precision:
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
When you're very close to 0.0, stepping from one double to the next (incrementing the 53rd bit) results in very small steps. When you're dealing with very large numbers, incrementing the 53rd bit produces huge steps, much larger than 1.0
The number 10^22 happens to be a valid double with value 10000000000000000000000 (hex 0x1.0f0cf064dd592p+73). If you increment the last bit by one (hex 0x1.0f0cf064dd593p+73), your value will be 10000000000000002097152.
There is no such thing as a double with value 10000000000000000000001 or the double with value 10000000000000000000002, ... or the double with value 10000000000000002097151. There is only 10000000000000000000000 and then, right after it, 10000000000000002097152. There is nothing inbetween those two numbers.
The number 10^23 does not exist in double notation. It lies between
99999999999999991611392 (hex 0x1.52d02c7e14af6p+76)
and
100000000000000008388608 (hex 0x1.52d02c7e14af7p+76)
It happens to be *exactly* between those two numbers, in which case the little-known "halfway to even" rounding rule kicks in, making the first one the correct value of pow(10,23) (the first one ends in hex 6, the second one ends in hex 7)
The number 10^24 also does not exist in double notation. It lies between
999999999999999983222784 (hex 0x1.a784379d99db4p+79)
and
1000000000000000117440512 (hex 0x1.a784379d99db5p+79)
Here it is a lot closer to the first one (by about a 100 mil), which is why that is the correct answer.
it takes a lot of difficult math to program a precise pow() (where "precise" means it always gives the one double value that is the closest to the mathematically-correct answer according to standard rounding rules). As you can see, your function failed to give the expected answer for 10^23, but worked for 10^22 and for 10^24. If you want to see (and be intimidated by) a production-level pow() implementation, take a look at
https://bitbucket.org/MDukhan/crlibm/src/30bc7f5a18b8acacea71407709e039e701561bfa/pow.c