Why isn't `int pow(int base, int exponent)` in the standard C++ libraries?

前端 未结 11 1266
礼貌的吻别
礼貌的吻别 2020-11-27 02:20

I feel like I must just be unable to find it. Is there any reason that the C++ pow function does not implement the \"power\" function for anything except

相关标签:
11条回答
  • 2020-11-27 02:59

    As a matter of fact, it does.

    Since C++11 there is a templated implementation of pow(int, int) --- and even more general cases, see (7) in http://en.cppreference.com/w/cpp/numeric/math/pow


    EDIT: purists may argue this is not correct, as there is actually "promoted" typing used. One way or another, one gets a correct int result, or an error, on int parameters.

    0 讨论(0)
  • 2020-11-27 03:03

    As of C++11, special cases were added to the suite of power functions (and others). C++11 [c.math] /11 states, after listing all the float/double/long double overloads (my emphasis, and paraphrased):

    Moreover, there shall be additional overloads sufficient to ensure that, if any argument corresponding to a double parameter has type double or an integer type, then all arguments corresponding to double parameters are effectively cast to double.

    So, basically, integer parameters will be upgraded to doubles to perform the operation.


    Prior to C++11 (which was when your question was asked), no integer overloads existed.

    Since I was neither closely associated with the creators of C nor C++ in the days of their creation (though I am rather old), nor part of the ANSI/ISO committees that created the standards, this is necessarily opinion on my part. I'd like to think it's informed opinion but, as my wife will tell you (frequently and without much encouragement needed), I've been wrong before :-)

    Supposition, for what it's worth, follows.

    I suspect that the reason the original pre-ANSI C didn't have this feature is because it was totally unnecessary. First, there was already a perfectly good way of doing integer powers (with doubles and then simply converting back to an integer, checking for integer overflow and underflow before converting).

    Second, another thing you have to remember is that the original intent of C was as a systems programming language, and it's questionable whether floating point is desirable in that arena at all.

    Since one of its initial use cases was to code up UNIX, the floating point would have been next to useless. BCPL, on which C was based, also had no use for powers (it didn't have floating point at all, from memory).

    As an aside, an integral power operator would probably have been a binary operator rather than a library call. You don't add two integers with x = add (y, z) but with x = y + z - part of the language proper rather than the library.

    Third, since the implementation of integral power is relatively trivial, it's almost certain that the developers of the language would better use their time providing more useful stuff (see below comments on opportunity cost).

    That's also relevant for the original C++. Since the original implementation was effectively just a translator which produced C code, it carried over many of the attributes of C. Its original intent was C-with-classes, not C-with-classes-plus-a-little-bit-of-extra-math-stuff.

    As to why it was never added to the standards before C++11, you have to remember that the standards-setting bodies have specific guidelines to follow. For example, ANSI C was specifically tasked to codify existing practice, not to create a new language. Otherwise, they could have gone crazy and given us Ada :-)

    Later iterations of that standard also have specific guidelines and can be found in the rationale documents (rationale as to why the committee made certain decisions, not rationale for the language itself).

    For example the C99 rationale document specifically carries forward two of the C89 guiding principles which limit what can be added:

    • Keep the language small and simple.
    • Provide only one way to do an operation.

    Guidelines (not necessarily those specific ones) are laid down for the individual working groups and hence limit the C++ committees (and all other ISO groups) as well.

    In addition, the standards-setting bodies realise that there is an opportunity cost (an economic term meaning what you have to forego for a decision made) to every decision they make. For example, the opportunity cost of buying that $10,000 uber-gaming machine is cordial relations (or probably all relations) with your other half for about six months.

    Eric Gunnerson explains this well with his -100 points explanation as to why things aren't always added to Microsoft products- basically a feature starts 100 points in the hole so it has to add quite a bit of value to be even considered.

    In other words, would you rather have a integral power operator (which, honestly, any half-decent coder could whip up in ten minutes) or multi-threading added to the standard? For myself, I'd prefer to have the latter and not have to muck about with the differing implementations under UNIX and Windows.

    I would like to also see thousands and thousands of collection the standard library (hashes, btrees, red-black trees, dictionary, arbitrary maps and so forth) as well but, as the rationale states:

    A standard is a treaty between implementer and programmer.

    And the number of implementers on the standards bodies far outweigh the number of programmers (or at least those programmers that don't understand opportunity cost). If all that stuff was added, the next standard C++ would be C++215x and would probably be fully implemented by compiler developers three hundred years after that.

    Anyway, that's my (rather voluminous) thoughts on the matter. If only votes were handed out bases on quantity rather than quality, I'd soon blow everyone else out of the water. Thanks for listening :-)

    0 讨论(0)
  • 2020-11-27 03:04

    The World is constantly evolving and so are the programming languages. The fourth part of the C decimal TR¹ adds some more functions to <math.h>. Two families of these functions may be of interest for this question:

    • The pown functions, that takes a floating point number and an intmax_t exponent.
    • The powr functions, that takes two floating points numbers (x and y) and compute x to the power y with the formula exp(y*log(x)).

    It seems that the standard guys eventually deemed these features useful enough to be integrated in the standard library. However, the rational is that these functions are recommended by the ISO/IEC/IEEE 60559:2011 standard for binary and decimal floating point numbers. I can't say for sure what "standard" was followed at the time of C89, but the future evolutions of <math.h> will probably be heavily influenced by the future evolutions of the ISO/IEC/IEEE 60559 standard.

    Note that the fourth part of the decimal TR won't be included in C2x (the next major C revision), and will probably be included later as an optional feature. There hasn't been any intent I know of to include this part of the TR in a future C++ revision.


    ¹ You can find some work-in-progress documentation here.

    0 讨论(0)
  • 2020-11-27 03:06

    One reason for C++ to not have additional overloads is to be compatible with C.

    C++98 has functions like double pow(double, int), but these have been removed in C++11 with the argument that C99 didn't include them.

    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3286.html#550

    Getting a slightly more accurate result also means getting a slightly different result.

    0 讨论(0)
  • 2020-11-27 03:08

    That's actually an interesting question. One argument I haven't found in the discussion is the simple lack of obvious return values for the arguments. Let's count the ways the hypthetical int pow_int(int, int) function could fail.

    1. Overflow
    2. Result undefined pow_int(0,0)
    3. Result can't be represented pow_int(2,-1)

    The function has at least 2 failure modes. Integers can't represent these values, the behaviour of the function in these cases would need to be defined by the standard - and programmers would need to be aware of how exactly the function handles these cases.

    Overall leaving the function out seems like the only sensible option. The programmer can use the floating point version with all the error reporting available instead.

    0 讨论(0)
  • 2020-11-27 03:10

    A very simple reason:

    5^-2 = 1/25
    

    Everything in the STL library is based on the most accurate, robust stuff imaginable. Sure, the int would return to a zero (from 1/25) but this would be an inaccurate answer.

    I agree, it's weird in some cases.

    0 讨论(0)
提交回复
热议问题