I think jonnin's point is that it still inevitably does floating-point arithmetic. It also is not constexpr, but many compilers often have built-in functions that check if the arguments are integral or not, and will optimize calls when appropriate.
it is just sluggish, is my point. x*x is a ton faster than pow(x,2), give it a try :)
yes, I know why. My point is the standard should overload a smart, hot integer powers only version; we did this a couple years back in the forum and just about anything we coded beat pow by a wide margin, whether a straight up loop or using the bits of the exponent.
Not necessarily; the standard library overload for integral exponents may be smart enough
(particularly when the exponent is 2).
See: https://gcc.godbolt.org/z/vGd54ev89
guys, i really feel very much stupid and feel like an idiot rn... this is probably the most embarrassing thread ever (but, i believe we also learned something even from the most ridiculous things tho)... i feel i just wanna delete this thread fr...
this probably bcoz i was quite sleepy when i write it... and also, probably, bcoz i was too much focus on the number's length...
so my code snippet was like this:
1 2 3 4 5 6 7 8
std::string num;
std::cout << "Enter: ";
std::cin >> num;
double len = num.size();
if (len == 7) {
std::cout << "million" /* bla bla bla */;
}
i probably was too focus on the length (i.e. 7), so when pow(10.00, 6) are the one that resulting 1 million, i thought it was wrong (coz i thought the right code should be pow(10.00, 7))
this is a very embarrassing thread (fr -_-) but, since i believe there's no stupid question, i believe we can also learned many things from this
the standard library overload for integral exponents may be smart enough
Sorry in advance for being pedantic :+)
Noted that you did say may, but I am wondering if this is an implementation dependent thing, see the code below from compiler explorer using MSVC 19.30.
Edit: I am aware the standard does not specify how things are done, just how they should behave.
I couldn't find much written about it on cppreference, or in the standard. The standard just has the function signature (none of them were int), which is probably why cppreference says the integer argument is converted to double. I was looking at the draft c++23 standard (N4901), presumably the same as the previous ones in this respect, because this is not a new feature in c++23.
g++ and clang++ produce identical code:
1 2 3 4 5 6
pow2_mul(double):
vmulsd xmm0, xmm0, xmm0
ret
pow2_lib(double):
vmulsd xmm0, xmm0, xmm0
ret
Converted to double for overload (7); not for overloads (4), (5), (6) which accept an exponent of type int
Overloads 4,5,6 are annotated "until c++11" , hopefully most of us are in the category of using something later than c++11 :+) . I have some bias, in that I am always using the latest of compilers and standards, and am always viewing things through that lens. However, I do realise that some are forced to still use old compilers / standards.
Thanks for your always expert advice; with a positive and polite attitude. Cheers :+)
pow() seems to be capable of recognising where the exponent is sufficiently close to an integer ... even if that exponent is a double.
Not sure that I'd rely on this behaviour, though.
Fascinating what other languages do:
Fortran:
program test
print *, (-10.0) ** 6 ! Legitimate; will be done by repeated-multiply, not exp-log
! print *, (-10.0) ** 6.0 ! Simply won't compile
end program test
Apropos of nothing regarding how pow() overloads work, it is interesting (to me at least) to see there are differences in output using std::format vs. using just std::cout: