• why is there not a ipow version of pow?

    From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 03:01:07 2026
    From Newsgroup: comp.lang.c

    Why is there not a ipow version of pow?

    ipow would return an int instead of a double. Or a long long int.

    Thanks,
    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 13:11:40 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 10:01 schrieb Lynn McGuire:

    Why is there not a ipow version of pow?
    ipow would return an int instead of a double.-a Or a long long int.

    Integer multiplies have nearly the same cost as floating point multi-
    plies. pow() is done with binary exponentation. This means that you
    need a lot of bit-checks an multiplies. This is nearly the same as
    with floating point numbers which don't have fractions. So you can
    stick with fp-values. The only difference is the reduced amount of
    bits (24 vs. 32 or 53 vs. 64).
    But I don't think that's there much usage for such a function.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.c++,comp.lang.c on Tue Aug 11 12:45:23 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 12:11, Bonita Montero wrote:
    Am 11.08.2026 um 10:01 schrieb Lynn McGuire:

    Why is there not a ipow version of pow?
    ipow would return an int instead of a double.-a Or a long long int.

    Integer multiplies have nearly the same cost as floating point multi-
    plies.

    Have you done any actual measurements?

    My language has an "**" operator which is overloaded for ints and floats.

    Doing a**b, which uses a special recursive routine for integers, is 5
    times as fast as for floats where it calls out to 'pow()' inside msvcrt
    C library.

    (This was for a=4, b=3; it will likely vary for integers depending on b,
    but b is unlikely to be large, as the results would overflow anyway.
    However for 2**63 - I'm using 64 bits - the integer version was still
    twice as fast.)

    With C, you are dependent on how well a compiler may optimise it. But an expression like c = pow(a, b), where a/b/c are all ints, still seemed to
    call pow() even using gcc-O3.

    In fact it is slower than with floats since conversion between ints and
    floats is needed.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 14:34:15 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 13:45 schrieb bart:

    Have you done any actual measurements?

    https://agner.org/optimize/instruction_tables.ods

    In fact it is slower than with floats since conversion between ints and floats is needed.

    Your measurements are not correct for sure. Check the above document.
    With my Zen4-CPU double * double is faster than i64 * i64.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 14:55:51 2026
    From Newsgroup: comp.lang.c

    I did run the numbers. I wasn't wrong but also not totally right.
    The result of the difference between integer and fp-multiplies
    is nearly zero:

    #include <iostream>
    #include <chrono>

    using namespace std;
    using namespace chrono;

    volatile double dOne = 1.0;
    volatile uint64_t dU64 = 1;

    int main()
    {
    auto tm = []( const char *what, auto fn )
    {
    time_point start = steady_clock::now();
    uint64_t n = fn();
    duration dur = steady_clock::now() - start;
    int64_t dur64 = dur.count();
    cout << what << (double)dur64 / (double)n << endl;
    };
    double d = ::dOne;
    tm( "fp: ", [&]
    {
    uint64_t r = 0;
    for( ; r < 1'000'000'000; d *= d, ++r );
    return r;
    } );
    uint64_t u = ::dU64;
    tm( "int: ", [&]
    {
    uint64_t r = 0;
    for( ; r < 1'000'000'000; u *= u, ++r );
    return r;
    } );
    return (int)d + (int)u;
    }
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 15:17:14 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 13:45, bart wrote:
    On 11/08/2026 12:11, Bonita Montero wrote:
    Am 11.08.2026 um 10:01 schrieb Lynn McGuire:

    Why is there not a ipow version of pow?
    ipow would return an int instead of a double.-a Or a long long int.

    Integer multiplies have nearly the same cost as floating point multi-
    plies.

    Have you done any actual measurements?

    Apparently Bonita has not done any such checking.


    My language has an "**" operator which is overloaded for ints and floats.

    Doing a**b, which uses a special recursive routine for integers, is 5
    times as fast as for floats where it calls out to 'pow()' inside msvcrt
    C library.

    (This was for a=4, b=3; it will likely vary for integers depending on b,
    but b is unlikely to be large, as the results would overflow anyway.
    However for 2**63 - I'm using 64 bits - the integer version was still
    twice as fast.)

    With C, you are dependent on how well a compiler may optimise it. But an expression like c = pow(a, b), where a/b/c are all ints, still seemed to call pow() even using gcc-O3.

    In fact it is slower than with floats since conversion between ints and floats is needed.



    Absolutely.

    For small values of b, an inlined integer ipow() function (or built-in
    feature of a language or compiler extension) will be a lot faster than
    an external floating point function. There are all sorts of overheads involved in the floating point option - some of which you have mentioned
    - that apply even if an individual floating point multiply has the same
    cost as an integer multiply. (And they are only the same cost on some processors, in some circumstances.)

    For b = 3, you are just doing "a * a * a" - generated inline, that will
    be /far/ smaller than the overheads of converting back and forth between integer and floating point types, and far below the overhead of an
    external dll-based function call, even before you get to the calculation.

    And a general-purpose floating-point pow() implementation has to cope
    with any possible values of "a" and "b" - that means calculating exp(b * log(a)). Each of "exp" and "log" is perhaps 60 cycles, and you also
    have to use various extra complications to retain accuracy for different ranges of "a" and "b". I would be surprised to find any value of "a"
    and "b" for which "(int64_t) pow(a, b)" was faster than a recursive
    integer implementation:

    int64_t ipow(int64_t a, uint64_t b) {
    return b ? ((b & 1) ? a : 1) * ipow(a * a, b >> 1) : 1;
    }

    A slightly more sophisticated version could have quick checks for small
    values of "b", and tail recursion will turn this into a loop (or that
    can be done manually). At worst you have 63 rounds, which will likely
    still be faster than an external "pow" function, but of course in real
    usage "b" will be much smaller or you'd overflow.


    I think the reason that there is no "integer power" function in the
    standard C library is that integer powers normally use fixed and small exponents that are easy enough to write it out manually.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 15:19:33 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 14:55, Bonita Montero wrote:
    I did run the numbers. I wasn't wrong but also not totally right.
    The result of the difference between integer and fp-multiplies
    is nearly zero:


    Even if that were true (and it is processor-dependent, so only true on
    some devices), it would be irrelevant to the OP's question. Floating
    point "pow" does not work by repeated multiplication - both operands are floating point.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 15:27:06 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 15:19 schrieb David Brown:

    On 11/08/2026 14:55, Bonita Montero wrote:

    I did run the numbers. I wasn't wrong but also not totally right.
    The result of the difference between integer and fp-multiplies
    is nearly zero:

    Even if that were true (and it is processor-dependent, so only true on
    some devices), it would be irrelevant to the OP's question.-a Floating
    point "pow" does not work by repeated multiplication - both operands
    are floating point.

    The OP asked why there's no pow() with integers. I said the performance
    must be almost the same as the overhead of a fp-multiplication is
    "near-ly the same" as with integers. Bart said that integer multiplies are
    five times faster than fp-multiplies. I did run the numbers for a modern machine and proved him wrong.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 15:28:30 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 15:17 schrieb David Brown:

    For small values of b, an inlined integer ipow() function (or built-in feature of a language or compiler extension) will be a lot faster than
    an external floating point function.-a...

    Prove that.

    For b = 3, you are just doing "a * a * a" - generated inline, ...

    I guess Lynn didn't ask for a solution optimized for constants.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Paul@nospam@needed.invalid to comp.lang.c++,comp.lang.c on Tue Aug 11 09:36:00 2026
    From Newsgroup: comp.lang.c

    On Tue, 8/11/2026 7:11 AM, Bonita Montero wrote:
    Am 11.08.2026 um 10:01 schrieb Lynn McGuire:

    Why is there not a ipow version of pow?
    ipow would return an int instead of a double.-a Or a long long int.

    Integer multiplies have nearly the same cost as floating point multi-
    plies. pow() is done with binary exponentation. This means that you
    need a lot of bit-checks an multiplies. This is nearly the same as
    with floating point numbers which don't have fractions. So you can
    stick with fp-values. The only difference is the reduced amount of
    bits (24 vs. 32 or 53 vs. 64).
    But I don't think that's there much usage for such a function.


    With pow(), you can do pow(2.2,3.3) ==> 13.49

    https://github.com/lattera/glibc/blob/master/sysdeps/ieee754/dbl-64/e_pow.c

    /* x^y =e^(y log (X)) */

    ( https://stackoverflow.com/questions/40824677/how-is-pow-calculated-in-c )

    There is also a .tbl file in that source.

    Apparently the processor has a mixed method for doing log(),
    using a Taylor series and a lookup table of some sort. That suggests, approximately, that using log() of something isn't going to be
    blindingly fast. But that also does not mean anyone has to like the
    valid range or how many digits it puts out. A person could craft
    their own log().

    There are some conditional checks for pow(). Maybe ipow()
    has some things to check too.

    And you can go on a shopping spree. There is more than one of
    these out there, but they are cut for speed, not necessarily
    for considering absolutely every condition. The domain and range
    could differ, compared to a library quality implementation.

    # ipow()

    https://gist.github.com/orlp/3551590

    Paul
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 16:08:22 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 15:27, Bonita Montero wrote:
    Am 11.08.2026 um 15:19 schrieb David Brown:

    On 11/08/2026 14:55, Bonita Montero wrote:

    I did run the numbers. I wasn't wrong but also not totally right.
    The result of the difference between integer and fp-multiplies
    is nearly zero:

    Even if that were true (and it is processor-dependent, so only true on
    some devices), it would be irrelevant to the OP's question.-a Floating
    point "pow" does not work by repeated multiplication - both operands
    are floating point.


    I'll take this slowly and hope that you read this better than you read
    other posts.

    The OP asked why there's no pow() with integers.

    Yes.

    I said the performance
    must be almost the same as the overhead of a fp-multiplication is "near-
    ly the same" as with integers.

    You did. You failed to mention the vital fact that this applies to some processors and not others, but it is apparently correct for Zen 4
    processors at least.

    It is, however, almost entirely irrelevant to the OP or to calculating
    "pow" in floating point or integer arithmetic. Floating point "pow"
    does not use multiplication (assuming the target processor has dedicated instructions for logs and anti-logs). It also has a more limited range
    of precise integer values compared to an integer power function, unless
    you are using at least 80-bit floating point types.

    Bart said that integer multiplies are
    five times faster than fp-multiplies.

    No, he did not.

    He said that in his language (we don't know what overheads that has, or
    what other instructions are used) doing "a ** b" in integers, with the
    example values of "a = 4" and "b = 3", was five times as fast as calling
    the external MSVCRT floating point "pow" function. That is a completely different thing, and the only thing surprising (to me) about what he
    wrote is that the difference is so small.

    I did run the numbers for a modern
    machine and proved him wrong.


    No, you did not - you merely demonstrated that you did not understand
    the OP's question and Bart's reply, or that for some reason you want to
    talk about something completely different and pretend that it is
    relevant. No one has said you were wrong about the speed of
    multiplications on Zen 4, because it does not matter.

    The fact that floating point multiply can, in some cases, be nearly as
    fast as integer multiply can be relevant to some code, and can come as a surprise to some people. But it has no bearing to the OP and an integer
    power function.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 16:18:35 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 16:08 schrieb David Brown:

    You did.-a You failed to mention the vital fact that this applies to some processors and not others, but it is apparently correct for Zen 4
    processors at least.

    Agner has taken this numbers on dozens of CPUs, and if you compare
    fp- and integer-times you've mostly the same relationship.

    It is, however, almost entirely irrelevant to the OP or to calculating
    "pow" in floating point or integer arithmetic.-a Floating point "pow"
    does not use multiplication (assuming the target processor has dedicated instructions for logs and anti-logs).

    Of course it doesn multiplications. It multiplies base by itself as
    long there are exponent bits and if an exponent bit is set the currently calulated value is multiplied by the base ^ (2 ^ n) value. For the frac-
    tion bits the square root is inrementally done in the same way. That's
    called binary exponentation.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 16:43:42 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 15:28, Bonita Montero wrote:
    Am 11.08.2026 um 15:17 schrieb David Brown:

    For small values of b, an inlined integer ipow() function (or built-in
    feature of a language or compiler extension) will be a lot faster than
    an external floating point function.-a...

    Prove that.

    #include <stdint.h>
    #include <math.h>

    int64_t ipow(int64_t a, uint64_t b) {
    return b ? ((b & 1) ? a : 1) * ipow(a * a, b >> 1) : 1;
    }

    #ifdef INT
    #define POW ipow
    #endif
    #ifdef FLOAT
    #define POW pow
    #endif
    #ifdef FIXEDB
    #define BVOL const
    #else
    #define BVOL volatile
    #endif

    int main(void) {
    volatile int64_t a = 29101;
    BVOL uint64_t b = 5;
    volatile int64_t c;

    uint64_t n = 1000 * 1000 * 1000;

    while (n--) {
    c = POW(a, b);
    }
    }

    $ gcc-14 -O2 -DINT -o powtest_int powtest.c
    $ gcc-14 -O2 -DINT -DFIXEDB -o powtest_int_fixed powtest.c
    $ gcc-14 -O2 -DFLOAT -o powtest_float powtest.c -lm
    $ gcc-14 -O2 -DFLOAT -DFIXEDB -o powtest_float_fixed powtest.c -lm

    $ time ./powtest_int

    real 0m1.538s
    user 0m1.536s
    sys 0m0.001s

    $ time ./powtest_int_fixed

    real 0m0.807s
    user 0m0.805s
    sys 0m0.002s

    $ time ./powtest_float

    real 0m11.219s
    user 0m11.217s
    sys 0m0.002s

    $ time ./powtest_float_fixed

    real 0m11.028s
    user 0m11.027s
    sys 0m0.001s

    That's a very rough test, with one set of values, on one system, and no control about what else might cause variations in the values. But an
    inlined integer power function for a small fixed "b" is comfortably more
    than 10 times the speed of calling "pow".


    For b = 3, you are just doing "a * a * a" - generated inline, ...

    I guess Lynn didn't ask for a solution optimized for constants.


    Lynn did not ask for any solution, merely an answer as to why there is
    no standard "ipow" function.

    Real-life usages of integer powers are likely to have small, fixed (at compile-time) values of "b". But of course only Lynn can say exactly
    what the usage would be in his own code.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.c++,comp.lang.c on Tue Aug 11 15:45:04 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 15:08, David Brown wrote:
    On 11/08/2026 15:27, Bonita Montero wrote:

    He said that in his language (we don't know what overheads that has, or
    what other instructions are used) doing "a ** b" in integers, with the example values of "a = 4" and "b = 3", was five times as fast as calling
    the external MSVCRT floating point "pow" function.-a That is a completely different thing, and the only thing surprising (to me) about what he
    wrote is that the difference is so small.

    The integer routine was equivalent to this C version:

    long long int ipow(long long a, int n) {
    long long int res;

    res = 1;
    if (n < 0) {
    res = 0;

    } else if (n == 0) {
    res = 1;

    } else if (n == 1) {
    res = a;

    } else if ((n & 1) == 0) { // n is even
    res = ipow(a*a, n/2);

    } else { // n is odd
    res = ipow(a*a, (n-1)/2)*a;
    }

    return res;
    }

    If I try this instead then I get the same results (which was more like 6
    times as fast as a version applying pow() to floats).


    I can't run an optimised version as the loop I used will just get
    optimised out.

    I did run the numbers for a modern
    machine and proved him wrong.


    No, you did not - you merely demonstrated that you did not understand
    the OP's question and Bart's reply, or that for some reason you want to
    talk about something completely different and pretend that it is
    relevant.-a No one has said you were wrong about the speed of multiplications on Zen 4, because it does not matter.

    The fact that floating point multiply can, in some cases, be nearly as
    fast as integer multiply can be relevant to some code, and can come as a surprise to some people.-a But it has no bearing to the OP and an integer power function.

    Maybe BM thinks that x**n requires n-1 multiplications.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 16:47:51 2026
    From Newsgroup: comp.lang.c

    Try my benchmark. The code is much more professional and in C++.

    #include <iostream>
    #include <chrono>

    using namespace std;
    using namespace chrono;

    volatile double dOne = 1.0;
    volatile uint64_t dU64 = 1;

    int main()
    {
    auto tm = []( const char *what, auto fn )
    {
    time_point start = steady_clock::now();
    uint64_t n = fn();
    duration dur = steady_clock::now() - start;
    int64_t dur64 = dur.count();
    cout << what << (double)dur64 / (double)n << endl;
    };
    double d = ::dOne;
    tm( "fp: ", [&]
    {
    uint64_t r = 0;
    for( ; r < 1'000'000'000; d *= d, ++r );
    return r;
    } );
    uint64_t u = ::dU64;
    tm( "int: ", [&]
    {
    uint64_t r = 0;
    for( ; r < 1'000'000'000; u *= u, ++r );
    return r;
    } );
    return (int)d + (int)u;
    }
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 16:56:04 2026
    From Newsgroup: comp.lang.c

    This is the integer pow() code so far I wrote in C++:

    template<typename Int>
    constexpr optional<Int> ipow( Int b, Int e )
    {
    constexpr bool Sgn = is_signed_v<Int>;
    using uint = make_unsigned_t<Int>;
    if( !b )
    return !e;
    uint ub, ue;
    if constexpr( Sgn )
    if( e >= 0 )
    {
    ub = abs( b );
    ue = abs( e );
    }
    else
    return abs( b ) == 1;
    else
    ub = b, ue = e;
    uint result = 1, msk = 1, sq = ub;
    while( ue )
    {
    if( (ue & msk) )
    {
    uint next = result * sq;
    if( next / sq != result )
    return nullopt;
    result = next;
    ue &= ~msk;
    }
    msk <<= 1;
    if( sq * sq / sq != sq )
    return nullopt;
    sq *= sq;
    }
    if constexpr( Sgn )
    if( bool neg = b < 0; neg && (e & 1) )
    if( result <= (uint)numeric_limits<Int>::min() )
    result = -(Int)result;
    else
    return nullopt;
    return result;

    }

    I didn't test all corner cases, but for values which don't overflow the
    code should be corrent. The crucial case about the performance here is
    that I need a division to check for overflows; in these cases you get
    a nullopt. With fp-values you get inf and that's less expensive.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 17:11:58 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 16:18, Bonita Montero wrote:
    Am 11.08.2026 um 16:08 schrieb David Brown:

    You did.-a You failed to mention the vital fact that this applies to
    some processors and not others, but it is apparently correct for Zen 4
    processors at least.

    Agner has taken this numbers on dozens of CPUs, and if you compare
    fp- and integer-times you've mostly the same relationship.

    He has numbers for dozens of x86 processors. There are many others that
    he has not covered. (But he has done a truly amazing job with the x86
    world.)


    It is, however, almost entirely irrelevant to the OP or to calculating
    "pow" in floating point or integer arithmetic.-a Floating point "pow"
    does not use multiplication (assuming the target processor has
    dedicated instructions for logs and anti-logs).

    Of course it doesn multiplications. It multiplies base by itself as
    long there are exponent bits and if an exponent bit is set the currently calulated value is multiplied by the base ^ (2 ^ n) value. For the frac-
    tion bits the square root is inrementally done in the same way. That's
    called binary exponentation.


    "pow(a, b)" is implemented approximately as "exp(b * log(a))". The calculations for "exp" and "log" will involve multiplications, of
    course, but not repeated multiplications of "a". Since it does not use multiplication in the same way and for the same purpose as you have in
    an integer power function, the relationship between the speed of multiplication instructions for integers and floating point does not matter.

    It is possible, I suppose, for a "pow" function to have a path that
    checks for "b" being a positive integer and then using an algorithm akin
    to the "ipow" for the calculation. I don't see that being the case in
    my testing (with glibc), but it could give a fast path for small integer
    "b". It would still have more overheads and be slower than the integer version, but much less less so.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 17:16:50 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 16:45, bart wrote:
    On 11/08/2026 15:08, David Brown wrote:
    On 11/08/2026 15:27, Bonita Montero wrote:

    He said that in his language (we don't know what overheads that has,
    or what other instructions are used) doing "a ** b" in integers, with
    the example values of "a = 4" and "b = 3", was five times as fast as
    calling the external MSVCRT floating point "pow" function.-a That is a
    completely different thing, and the only thing surprising (to me)
    about what he wrote is that the difference is so small.

    The integer routine was equivalent to this C version:

    -along long int ipow(long long a, int n) {
    -a-a-a long long int res;

    -a-a-a res = 1;
    -a-a-a if (n < 0) {
    -a-a-a-a-a-a-a res = 0;

    -a-a-a } else if (n == 0) {
    -a-a-a-a-a-a-a res = 1;

    -a-a-a } else if (n == 1) {
    -a-a-a-a-a-a-a res = a;

    -a-a-a } else if ((n & 1) == 0) {-a-a-a-a-a-a-a // n is even
    -a-a-a-a-a-a-a res = ipow(a*a, n/2);

    -a-a-a } else {-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a // n is odd
    -a-a-a-a-a-a-a res = ipow(a*a, (n-1)/2)*a;
    -a-a-a }

    -a-a-a return res;
    -a}


    That will give basically the same results, probably with similar timing
    to my version, as long as the compiler can do tail recursion.

    If I try this instead then I get the same results (which was more like 6 times as fast as a version applying pow() to floats).


    I can't run an optimised version as the loop I used will just get
    optimised out.


    For testing in C, use "volatile" on the inputs and outputs of the thing
    you are testing - then you can optimise freely.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 17:20:14 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 17:11 schrieb David Brown:

    He has numbers for dozens of x86 processors.-a There are many others that
    he has not covered.-a (But he has done a truly amazing job with the x86 world.)

    Agner covers almost all x86-microarcitecures that have been seen so far.


    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    Check the glibc sourcecode. Binary exponentation is the fastest way
    to to that and the way with the least precision loss.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 17:23:15 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 16:56, Bonita Montero wrote:
    This is the integer pow() code so far I wrote in C++:


    I didn't test all corner cases, but for values which don't overflow the
    code should be corrent. The crucial case about the performance here is
    that I need a division to check for overflows; in these cases you get
    a nullopt. With fp-values you get inf and that's less expensive.


    If you are writing a real integer power function with speed in mind,
    don't do that. Use ckd_mul, or compiler-specific builtins (with
    appropriate compiler-specific conditional compilation).

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.c++,comp.lang.c on Tue Aug 11 16:23:32 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 15:56, Bonita Montero wrote:
    This is the integer pow() code so far I wrote in C++:

    template<typename Int>
    constexpr optional<Int> ipow( Int b, Int e )
    {
    -a-a-a-aconstexpr bool Sgn = is_signed_v<Int>;
    -a-a-a-ausing uint = make_unsigned_t<Int>;
    -a-a-a-aif( !b )
    -a-a-a-a-a-a-a return !e;
    -a-a-a-auint ub, ue;
    -a-a-a-aif constexpr( Sgn )
    -a-a-a-a-a-a-a if( e >= 0 )
    -a-a-a-a-a-a-a {
    -a-a-a-a-a-a-a-a-a-a-a ub = abs( b );
    -a-a-a-a-a-a-a-a-a-a-a ue = abs( e );
    -a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a else
    -a-a-a-a-a-a-a-a-a-a-a return abs( b ) == 1;
    -a-a-a-aelse
    -a-a-a-a-a-a-a ub = b, ue = e;
    -a-a-a-auint result = 1, msk = 1, sq = ub;
    -a-a-a-awhile( ue )
    -a-a-a-a{
    -a-a-a-a-a-a-a if( (ue & msk) )
    -a-a-a-a-a-a-a {
    -a-a-a-a-a-a-a-a-a-a-a uint next = result * sq;
    -a-a-a-a-a-a-a-a-a-a-a if( next / sq != result )
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a return nullopt;
    -a-a-a-a-a-a-a-a-a-a-a result = next;
    -a-a-a-a-a-a-a-a-a-a-a ue &= ~msk;
    -a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a msk <<= 1;
    -a-a-a-a-a-a-a if( sq * sq / sq != sq )
    -a-a-a-a-a-a-a-a-a-a-a return nullopt;
    -a-a-a-a-a-a-a sq *= sq;
    -a-a-a-a}
    -a-a-a-aif constexpr( Sgn )
    -a-a-a-a-a-a-a if( bool neg = b < 0; neg && (e & 1) )
    -a-a-a-a-a-a-a-a-a-a-a if( result <= (uint)numeric_limits<Int>::min() )
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a result = -(Int)result;
    -a-a-a-a-a-a-a-a-a-a-a else
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a return nullopt;
    -a-a-a-areturn result;

    }


    Can you package this into something I can all as ipow(a, b)?

    As it is this doesn't compile by itself.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 17:24:20 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 16:47, Bonita Montero wrote:
    Try my benchmark. The code is much more professional and in C++.


    "Professional" means getting paid for the task. If you want to pay me,
    I will do "more professional" testing.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 17:24:35 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 17:23 schrieb David Brown:

    If you are writing a real integer power function with speed in mind,
    don't do that.-a...
    If I want to compare the speed against a fp-pow() that's the right way.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 17:26:17 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 17:23 schrieb bart:
    On 11/08/2026 15:56, Bonita Montero wrote:
    This is the integer pow() code so far I wrote in C++:

    template<typename Int>
    constexpr optional<Int> ipow( Int b, Int e )
    {
    -a-a-a-a-aconstexpr bool Sgn = is_signed_v<Int>;
    -a-a-a-a-ausing uint = make_unsigned_t<Int>;
    -a-a-a-a-aif( !b )
    -a-a-a-a-a-a-a-a return !e;
    -a-a-a-a-auint ub, ue;
    -a-a-a-a-aif constexpr( Sgn )
    -a-a-a-a-a-a-a-a if( e >= 0 )
    -a-a-a-a-a-a-a-a {
    -a-a-a-a-a-a-a-a-a-a-a-a ub = abs( b );
    -a-a-a-a-a-a-a-a-a-a-a-a ue = abs( e );
    -a-a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a-a else
    -a-a-a-a-a-a-a-a-a-a-a-a return abs( b ) == 1;
    -a-a-a-a-aelse
    -a-a-a-a-a-a-a-a ub = b, ue = e;
    -a-a-a-a-auint result = 1, msk = 1, sq = ub;
    -a-a-a-a-awhile( ue )
    -a-a-a-a-a{
    -a-a-a-a-a-a-a-a if( (ue & msk) )
    -a-a-a-a-a-a-a-a {
    -a-a-a-a-a-a-a-a-a-a-a-a uint next = result * sq;
    -a-a-a-a-a-a-a-a-a-a-a-a if( next / sq != result )
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a return nullopt;
    -a-a-a-a-a-a-a-a-a-a-a-a result = next;
    -a-a-a-a-a-a-a-a-a-a-a-a ue &= ~msk;
    -a-a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a-a msk <<= 1;
    -a-a-a-a-a-a-a-a if( sq * sq / sq != sq )
    -a-a-a-a-a-a-a-a-a-a-a-a return nullopt;
    -a-a-a-a-a-a-a-a sq *= sq;
    -a-a-a-a-a}
    -a-a-a-a-aif constexpr( Sgn )
    -a-a-a-a-a-a-a-a if( bool neg = b < 0; neg && (e & 1) )
    -a-a-a-a-a-a-a-a-a-a-a-a if( result <= (uint)numeric_limits<Int>::min() )
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a result = -(Int)result;
    -a-a-a-a-a-a-a-a-a-a-a-a else
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a return nullopt;
    -a-a-a-a-areturn result;

    }


    Can you package this into something I can all as ipow(a, b)?

    You need <optional>, type_traits>, <cmath>, <random>.

    As it is this doesn't compile by itself.

    Don't you program C ?

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 17:32:32 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 17:20, Bonita Montero wrote:
    Am 11.08.2026 um 17:11 schrieb David Brown:

    He has numbers for dozens of x86 processors.-a There are many others
    that he has not covered.-a (But he has done a truly amazing job with
    the x86 world.)

    Agner covers almost all x86-microarcitecures that have been seen so far.

    Most processors in the world are /not/ x86. On some devices, a floating
    point multiply will be perhaps 200 times slower than an integer
    multiply. You may also find that on some devices with 32-bit GPRs and
    64-bit hardware floating point, floating point multiplication could be
    faster than 64-bit integer multiplication. Anger covers the x86 world,
    not the entire processor world.



    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    Check the glibc sourcecode. Binary exponentation is the fastest way
    to to that and the way with the least precision loss.


    Let me try again.

    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    /Obviously/ the base used for the "exp" and "log" is base 2, since that
    is the most efficient base for calculating "exp" and "log" on a binary computer, especially with standard floating point formats.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 17:39:16 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 17:32 schrieb David Brown:

    Most processors in the world are /not/ x86.

    And do you think they've better multipliers because they've a
    different architecture ? I don't.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From James Kuyper@jameskuyper@alumni.caltech.edu to comp.lang.c++,comp.lang.c on Tue Aug 11 11:46:06 2026
    From Newsgroup: comp.lang.c

    On 2026-08-11 11:32, David Brown wrote:
    On 11/08/2026 17:20, Bonita Montero wrote:
    Am 11.08.2026 um 17:11 schrieb David Brown:
    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    Check the glibc sourcecode. Binary exponentation is the fastest way
    to to that and the way with the least precision loss.


    Let me try again.

    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    /Obviously/ the base used for the "exp" and "log" is base 2, since that
    is the most efficient base for calculating "exp" and "log" on a binary computer, especially with standard floating point formats.
    I hope that exp() and log() use base e! The exp2() and log2() functions
    are the ones that are supposed to use base 2.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 17:54:25 2026
    From Newsgroup: comp.lang.c

    I did handle two additional corner cases, but I still don't know
    if I'm 100% correct.

    template<typename Int>
    constexpr optional<Int> ipow( Int b, Int e )
    {
    constexpr bool Sgn = is_signed_v<Int>;
    using uint = make_unsigned_t<Int>;
    if( !b )
    return !e;
    uint ub, ue;
    if constexpr( Sgn )
    if( e >= 0 )
    {
    ub = abs( b );
    ue = abs( e );
    }
    else
    return abs( b ) == 1 ? b : 0;
    else
    ub = b, ue = e;
    uint result = 1, msk = 1, sq = ub;
    while( ue )
    {
    if( (ue & msk) )
    {
    uint next = result * sq;
    if( next / sq != result )
    return nullopt;
    result = next;
    ue &= ~msk;
    }
    msk <<= 1;
    if( (uint)(sq * sq) / sq != sq )
    return nullopt;
    sq *= sq;
    }
    constexpr uint Max = numeric_limits<Int>::min();
    if constexpr( Sgn )
    if( b < 0 )
    if( (e & 1) )
    if( result <= Max )
    result = -(Int)result;
    else
    return nullopt;
    else
    if( result >= Max )
    return nullopt;
    else
    if( result >= Max )
    return nullopt;
    return result;
    }
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 18:33:11 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 17:39, Bonita Montero wrote:
    Am 11.08.2026 um 17:32 schrieb David Brown:

    Most processors in the world are /not/ x86.

    And do you think they've better multipliers because they've a
    different architecture ? I don't.


    I know that on many devices, integer multipliers are faster than
    floating point multipliers. Most processors do not have any kind of
    hardware floating point - all floating point is done in software. For
    those that have hardware floating point, a many take a few cycles to do
    the multiplication in hardware, because single-cycle floating point
    hardware takes a lot of die space and is far less useful than
    single-cycle integer multiply.

    Once you have a die as large as for x86 processors, the cost of
    single-cycle floating point multipliers is not nearly as high. But even
    then, many x86 processors have been designed where there are
    significantly more integer multiply units than floating point multiply
    units - giving significantly greater integer multiply throughput.

    This is not difficult to understand. Integer multiplications are needed
    more than floating point multiplications, and they are simpler and
    smaller to implement.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Tue Aug 11 18:35:51 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 17:46, James Kuyper wrote:
    On 2026-08-11 11:32, David Brown wrote:
    On 11/08/2026 17:20, Bonita Montero wrote:
    Am 11.08.2026 um 17:11 schrieb David Brown:
    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    Check the glibc sourcecode. Binary exponentation is the fastest way
    to to that and the way with the least precision loss.


    Let me try again.

    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    /Obviously/ the base used for the "exp" and "log" is base 2, since that
    is the most efficient base for calculating "exp" and "log" on a binary
    computer, especially with standard floating point formats.
    I hope that exp() and log() use base e! The exp2() and log2() functions
    are the ones that are supposed to use base 2.

    I know this is c.l.c. (and c.l.c++), but I was referring to generic logarithmic and anti-logarithmic functions rather than the C standard
    library functions. For implementing a power function, any base will do.
    (And the implementation is unlikely to use the standard exp2 and log2 functions.)

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 18:39:31 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 18:33 schrieb David Brown:

    I know that on many devices, integer multipliers are faster than
    floating point multipliers.-a Most processors do not have any kind
    of hardware floating point - all floating point is done in software.

    Cood for comparisons between int- and fp-multipliers !!!

    Once you have a die as large as for x86 processors, the cost of single- cycle floating point multipliers is not nearly as high.

    With x86 there are no single cycle fp-multipliers and I'm pretty sure
    that's not different on any comparable performant cores with other architectures.

    But even then, many x86 processors have been designed where there are significantly more integer multiply units than floating point multiply
    units - giving significantly greater integer multiply throughput.

    Absolutely not because there's SIMD whose execution units could be used
    scalar.

    This is not difficult to understand.-a Integer multiplications are needed more than floating point multiplications, and they are simpler and
    smaller to implement.

    But they're not faster on all current x86-architectures.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 18:40:46 2026
    From Newsgroup: comp.lang.c

    This is further improved with some bit-scanning to find the
    next set bit in the exponent beginning from the lowest bit on.
    This should be somewhat faster.

    template<typename Int>
    constexpr optional<Int> ipow( Int b, Int e )
    {
    constexpr bool Sgn = is_signed_v<Int>;
    using uint = make_unsigned_t<Int>;
    if( !b )
    return !e;
    uint ub, ue;
    if constexpr( Sgn )
    if( e >= 0 )
    {
    ub = abs( b );
    ue = abs( e );
    }
    else
    return abs( b ) == 1 ? b : 0;
    else
    ub = b, ue = e;
    uint result = 1, msk = 1, sq = ub;
    for( int xskip = 0; ue; xskip = 1 )
    {
    int skip = countr_zero( ue );
    for( int s = skip + xskip; s; sq *= sq, --s )
    if( (uint)(sq * sq) / sq != sq )
    return nullopt;
    if( (uint)(result * sq) / sq != result )
    return nullopt;
    result *= sq;
    ue >>= skip;
    ue >>= 1;
    }
    constexpr uint UMax = numeric_limits<Int>::min();
    if constexpr( Sgn )
    if( b < 0 )
    if( (e & 1) )
    if( result <= UMax )
    result = -(Int)result;
    else
    return nullopt;
    else
    if( result >= UMax )
    return nullopt;
    else
    if( result >= UMax )
    return nullopt;
    return result;
    }
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 19:15:33 2026
    From Newsgroup: comp.lang.c

    On 2026-08-11 10:01, Lynn McGuire wrote:
    Why is there not a ipow version of pow?

    It may sound strange (at first glance), but the negated answer would
    probably be easier to answer.

    If there were one one could easily formulate some advantages compared
    to the floating point versions.

    But since there isn't one we can only speculate and say that possible advantages were probably not considered worthwhile an addition.

    Other languages support it, probably with overloaded operators for a
    unified looking expressions experience, but underlying functions may nonetheless differ (depending on the involved types and signatures).

    ipow would return an int instead of a double.-a Or a long long int.

    Yes. Even the semantics may vary (compared to a float version); e.g.
    while a (primitive) float version might be formulated using exp/ln
    for the whole range of numbers an int x int -> int version might
    not be defined for exponents less than zero. (Or, as I've noticed in
    one of the posted algorithms, might just return 0.) And real x real
    real and real x int -> real might be two other implementations.
    All three distinct.

    Curious; is your question just an academical one (out of interest) or
    do you have a specific demand for it?

    When I started programming decades ago accuracy was an issue, so the
    exp/ln approach was not always appropriate. Also speed of computation.
    But things have changed since then, concerning accuracy of floats and
    the speed of math operations. So check your requirements and make sure
    whether the supported "pow" functions do what you need, else implement
    one or find a good one on the Internet. (I've seen a sensible looking
    version posted here in this thread.)

    Janis

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.c++,comp.lang.c on Tue Aug 11 18:43:27 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 15:56, Bonita Montero wrote:

    I didn't test all corner cases, but for values which don't overflow the
    code should be corrent. The crucial case about the performance here is
    that I need a division to check for overflows; in these cases you get
    a nullopt. With fp-values you get inf and that's less expensive.



    Why do you need all that? You basically just want ipow(a, 4) to return a*a*a*a.

    If worried about overflow, then use floating point pow().
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 19:56:45 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 19:43 schrieb bart:

    Why do you need all that? You basically just want ipow(a, 4) to return a*a*a*a.

    To have variable exponents.

    If worried about overflow, then use floating point pow().

    I did this to compare the performance, but I didn't run the numbers on
    that. I mentioned that the overflow detection needs a division, thereby
    making the code not competitive to a fp-version.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c++,comp.lang.c on Tue Aug 11 18:19:36 2026
    From Newsgroup: comp.lang.c

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 11.08.2026 um 17:11 schrieb David Brown:

    He has numbers for dozens of x86 processors.-a There are many others that >> he has not covered.-a (But he has done a truly amazing job with the x86
    world.)

    Agner covers almost all x86-microarcitecures that have been seen so far.

    That's what David stated, yes.

    That doesn't include PowerPC, uMIPS, ARMv7/8/9, S390, or the myriad
    of small microcontrollers and utility processors still in common use.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 20:21:43 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 20:19 schrieb Scott Lurndal:

    That doesn't include PowerPC, uMIPS, ARMv7/8/9, S390, or the myriad
    of small microcontrollers and utility processors still in common use.

    Do you think these architectures have faster integer-multipliers ?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 20:24:09 2026
    From Newsgroup: comp.lang.c

    Now I did run the numbers on that. My integer code is about four
    times faster with g++ and clang++/clang-cl for all cases where
    there's no overflow on ipow() *and* pow(). I didn't expect that.

    #include <iostream>
    #include <optional>
    #include <type_traits>
    #include <cmath>
    #include <random>
    #include <bit>
    #include <chrono>

    using namespace std;
    using namespace chrono;

    template<typename Int>
    constexpr optional<Int> ipow( Int b, Int e );

    int main()
    {
    constexpr int64_t Base = -3;
    constexpr size_t Rounds = 10'000'000;
    int maxExp = 0;
    for( ; ipow( Base, (int64_t)maxExp ); ++maxExp );
    int64_t joined = 0;
    auto tm = [&]( const char *what, auto fn )
    {
    time_point start = steady_clock::now();
    for( size_t r = Rounds; r; --r )
    for( int exp = 0; exp <= maxExp; ++exp )
    joined ^= fn( exp );
    duration dur = duration_cast<nanoseconds>( steady_clock::now() - start );
    double ns = (double)dur.count() / ((double)Rounds * (double)(maxExp + 1));
    cout << what << ns << endl;
    };
    tm( "integer: ", []( int exp ) { return *ipow( Base, (int64_t)exp ); } );
    tm( "double: ", []( int exp ) { return bit_cast<int64_t>( pow( (double)Base, exp ) ); } );
    return (int)joined;
    }

    template<typename Int>
    constexpr optional<Int> ipow( Int b, Int e )
    {
    constexpr bool Sgn = is_signed_v<Int>;
    using uint = make_unsigned_t<Int>;
    if( !b )
    return !e;
    uint ub, ue;
    if constexpr( Sgn )
    if( e >= 0 )
    {
    ub = abs( b );
    ue = abs( e );
    }
    else
    return abs( b ) == 1 ? b : 0;
    else
    ub = b, ue = e;
    uint result = 1, sq = ub;
    for( int xskip = 0; ue; xskip = 1 )
    {
    int skip = countr_zero( ue );
    for( int s = skip + xskip; s; sq *= sq, --s )
    if( (uint)(sq * sq) / sq != sq )
    return nullopt;
    if( (uint)(result * sq) / sq != result )
    return nullopt;
    result *= sq;
    ue >>= skip;
    ue >>= 1;
    }
    constexpr uint UMax = numeric_limits<Int>::min();
    if constexpr( Sgn )
    if( b < 0 && (e & 1) )
    if( result <= UMax )
    result = -(Int)result;
    else
    return nullopt;
    else
    if( result >= UMax )
    return nullopt;
    return result;
    }
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c++,comp.lang.c on Tue Aug 11 21:58:37 2026
    From Newsgroup: comp.lang.c

    On Tue, 11 Aug 2026 17:20:14 +0200
    Bonita Montero <Bonita.Montero@gmail.com> wrote:
    Am 11.08.2026 um 17:11 schrieb David Brown:

    He has numbers for dozens of x86 processors.a There are many others
    that he has not covered.a (But he has done a truly amazing job with
    the x86 world.)

    Agner covers almost all x86-microarcitecures that have been seen so
    far.


    Last Intel's microarcitecure covered by Agner Fog is Sunny Cove,
    featured in Ice Lake, Rocket Lake and Tiger Lake CPUs. (2019-2021).
    He provides no information for anything more modern.
    The claimed reasons is that all post-Tiger Intel laptop and desktop CPUs
    use hybrid approach, containing mix of "perfformance" (* Cove) and
    "efficiency" (* Mont) cores, so which makes measurements somewhat less
    simple.
    I would think that the real reason is his age, fatigue and being
    now retired it's less easy for him to get access to different hardware
    then when he was still in academy.
    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    Check the glibc sourcecode. Binary exponentation is the fastest way
    to to that and the way with the least precision loss.

    So, 2.0**(b * log2(a)). Same shite, as long as you're not nitpicking.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.c++,comp.lang.c on Tue Aug 11 20:27:29 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 19:24, Bonita Montero wrote:
    Now I did run the numbers on that. My integer code is about four
    times faster with g++ and clang++/clang-cl for all cases where
    there's no overflow on ipow() *and* pow(). I didn't expect that.


    When I tried to compile this, it said:

    C:/tdm/include/c++/16.1.0/optional:1256: constexpr _Tp&& std::optional<_Tp>::operator*() && [with _T
    p = long long int]: Assertion 'this->_M_is_engaged()' failed.


    I don't know enough C++ to fix it, but, got rid of enough stuff to get
    it to compile, while still doing the task.

    The version below, compiled with g++-O2, completed in 0.5 seconds.

    My C version, with the same driver code and compiled with gcc-O2,
    completed in 0.2 seconds (0.25 if ipow was in a separate file; normally
    ipow() would be in a library).

    If doing ipow(2, 60) instead, yours took 0.9s compared with my 0.4(0.5) seconds.

    ---------------------------------

    #include <iostream>
    #include <optional>
    #include <type_traits>
    #include <cmath>
    #include <random>
    #include <bit>
    #include <chrono>

    using namespace std;
    using namespace chrono;

    typedef long long int Int;

    Int ipow( Int b, Int e )
    {
    constexpr bool Sgn = is_signed_v<Int>;
    using uint = make_unsigned_t<Int>;
    if( !b )
    return !e;
    uint ub, ue;
    if constexpr( Sgn )
    if( e >= 0 )
    {
    ub = abs( b );
    ue = abs( e );
    }
    else
    return abs( b ) == 1 ? b : 0;
    else
    ub = b, ue = e;
    uint result = 1, sq = ub;
    for( int xskip = 0; ue; xskip = 1 )
    {
    int skip = countr_zero( ue );
    for( int s = skip + xskip; s; sq *= sq, --s )
    if( (uint)(sq * sq) / sq != sq )
    return 0;
    if( (uint)(result * sq) / sq != result )
    return 0;
    result *= sq;
    ue >>= skip;
    ue >>= 1;
    }
    return result;
    }

    int main() {
    volatile Int a=4,b=3,c;

    for (int i=0; i<100000000; ++i)
    c=ipow(a, b);
    printf("%d\n", c);
    }
    ------------------

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.c++,comp.lang.c on Tue Aug 11 20:41:28 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 18:56, Bonita Montero wrote:
    Am 11.08.2026 um 19:43 schrieb bart:

    Why do you need all that? You basically just want ipow(a, 4) to return
    a*a*a*a.

    To have variable exponents.

    You mean ipow(a, b) where b is known at runtime?

    Then that's exactly what I mean. This should be the equivalant of
    a*a*a...*a with b-1 multiplications, but done more efficiently.

    For example my function can calculate ipow(1, 1000000) 10,000 times
    faster than a version that simply does 1000000 or so multiplications.


    If worried about overflow, then use floating point pow().

    I did this to compare the performance, but I didn't run the numbers on
    that. I mentioned that the overflow detection needs a division, thereby making the code not competitive to a fp-version.


    People don't care about integer overflow in general, why should they here?

    However if large-magnitude results (greater than 2**63) are likely, then
    they should go with floats and use pow, at a loss of some precision.

    Or use the same algorithm with a bigint library as I also do.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c++,comp.lang.c on Tue Aug 11 23:31:50 2026
    From Newsgroup: comp.lang.c

    On Tue, 11 Aug 2026 18:33:11 +0200
    David Brown <david.brown@hesbynett.no> wrote:

    On 11/08/2026 17:39, Bonita Montero wrote:
    Am 11.08.2026 um 17:32 schrieb David Brown:

    Most processors in the world are /not/ x86.

    And do you think they've better multipliers because they've a
    different architecture ? I don't.


    I know that on many devices, integer multipliers are faster than
    floating point multipliers. Most processors do not have any kind of hardware floating point - all floating point is done in software.
    For those that have hardware floating point, a many take a few cycles
    to do the multiplication in hardware, because single-cycle floating
    point hardware takes a lot of die space and is far less useful than single-cycle integer multiply.

    Once you have a die as large as for x86 processors, the cost of
    single-cycle floating point multipliers is not nearly as high.

    If you talk latency, then the cost of single-cycle floating point
    multiply, even single precision, on any "big" fast CPU, not just x86,
    but all of them that still compete in high-perf single-thread game,
    is not just high, it's practically unattainable without compromising
    Holy Cycle Time.
    Throughput is another matter. Here you can see rather huge numbers.
    32 SP fmuls per cycle (2x512bit SIMD) are not uncommon.


    But
    even then, many x86 processors have been designed where there are significantly more integer multiply units than floating point
    multiply units - giving significantly greater integer multiply
    throughput.

    This is not difficult to understand. Integer multiplications are
    needed more than floating point multiplications, and they are simpler
    and smaller to implement.


    Actually, x86-64 has integer multiplications up to 64b * 64 bit => 128
    bit.
    Such multiplier is significantly bigger than the one needed by DP FMUL
    or even by DP FMA. Naturally, on majority of x86-64 implementations
    such integer multiplication has the same or slower latency than DP
    FMUL/FMA.

    On aarch64 there is no 64x64=>128b, but there is 64-bit UMULH, which is
    only 1/4th or so smaller. It also typically has the same or higher
    latecy as DP FMUL. Apple is an exception to that (3 for UMULH, 4 for
    FMUL).



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c++,comp.lang.c on Tue Aug 11 21:10:23 2026
    From Newsgroup: comp.lang.c

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 11.08.2026 um 20:19 schrieb Scott Lurndal:

    That doesn't include PowerPC, uMIPS, ARMv7/8/9, S390, or the myriad
    of small microcontrollers and utility processors still in common use.

    Do you think these architectures have faster integer-multipliers ?

    Depends on clock speed. The Neoverse-N2 integer multiply instruction
    has a latency of 2 cycles and throughput of one per cycle. Seems
    fast enough.

    Those same latency and throughput numbers apply to the multiply-add
    and multiply-subtract instructions as well.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 16:41:20 2026
    From Newsgroup: comp.lang.c

    On 8/11/2026 12:15 PM, Janis Papanagnou wrote:
    On 2026-08-11 10:01, Lynn McGuire wrote:
    Why is there not a ipow version of pow?

    It may sound strange (at first glance), but the negated answer would
    probably be easier to answer.

    If there were one one could easily formulate some advantages compared
    to the floating point versions.

    But since there isn't one we can only speculate and say that possible advantages were probably not considered worthwhile an addition.

    Other languages support it, probably with overloaded operators for a
    unified looking expressions experience, but underlying functions may nonetheless differ (depending on the involved types and signatures).

    ipow would return an int instead of a double.-a Or a long long int.

    Yes. Even the semantics may vary (compared to a float version); e.g.
    while a (primitive) float version might be formulated using exp/ln
    for the whole range of numbers an-a int x int -> int-a version might
    not be defined for exponents less than zero. (Or, as I've noticed in
    one of the posted algorithms, might just return 0.) And-a real x real
    real-a and-a real x int -> real-a might be two other implementations.
    All three distinct.

    Curious; is your question just an academical one (out of interest) or
    do you have a specific demand for it?

    When I started programming decades ago accuracy was an issue, so the
    exp/ln approach was not always appropriate. Also speed of computation.
    But things have changed since then, concerning accuracy of floats and
    the speed of math operations. So check your requirements and make sure whether the supported "pow" functions do what you need, else implement
    one or find a good one on the Internet. (I've seen a sensible looking
    version posted here in this thread.)

    Janis

    I have pow of an integer to an integer power in my code, yes.

    I am converting 800,000 lines of F77 code to C++.

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c++,comp.lang.c on Wed Aug 12 00:42:38 2026
    From Newsgroup: comp.lang.c

    On Tue, 11 Aug 2026 21:10:23 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 11.08.2026 um 20:19 schrieb Scott Lurndal:

    That doesn't include PowerPC, uMIPS, ARMv7/8/9, S390, or the myriad
    of small microcontrollers and utility processors still in common
    use.

    Do you think these architectures have faster integer-multipliers ?

    Depends on clock speed. The Neoverse-N2 integer multiply instruction
    has a latency of 2 cycles and throughput of one per cycle. Seems
    fast enough.

    Those same latency and throughput numbers apply to the multiply-add
    and multiply-subtract instructions as well.

    Actually, it does not depend on clock speed alone.
    More like on relationships betwween clock speed and power consumption.

    Arm Cortex X4 reaches much higher clock speed than Neoverse-N2, but
    it also consumes more power. At the end, latency of integer multiplier
    is the same as N2 - 2 for regular multiply, 3 for umulh.

    Even X925 that goes to quite extreme clock frequencies (and throughput),
    has most of the latencies the same as N2. Only integer
    multiple-accumulate is higher by 1 clock.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 16:42:50 2026
    From Newsgroup: comp.lang.c

    On 8/11/2026 8:36 AM, Paul wrote:
    On Tue, 8/11/2026 7:11 AM, Bonita Montero wrote:
    Am 11.08.2026 um 10:01 schrieb Lynn McGuire:

    Why is there not a ipow version of pow?
    ipow would return an int instead of a double.-a Or a long long int.

    Integer multiplies have nearly the same cost as floating point multi-
    plies. pow() is done with binary exponentation. This means that you
    need a lot of bit-checks an multiplies. This is nearly the same as
    with floating point numbers which don't have fractions. So you can
    stick with fp-values. The only difference is the reduced amount of
    bits (24 vs. 32 or 53 vs. 64).
    But I don't think that's there much usage for such a function.


    With pow(), you can do pow(2.2,3.3) ==> 13.49

    https://github.com/lattera/glibc/blob/master/sysdeps/ieee754/dbl-64/e_pow.c

    /* x^y =e^(y log (X)) */

    ( https://stackoverflow.com/questions/40824677/how-is-pow-calculated-in-c )

    There is also a .tbl file in that source.

    Apparently the processor has a mixed method for doing log(),
    using a Taylor series and a lookup table of some sort. That suggests, approximately, that using log() of something isn't going to be
    blindingly fast. But that also does not mean anyone has to like the
    valid range or how many digits it puts out. A person could craft
    their own log().

    There are some conditional checks for pow(). Maybe ipow()
    has some things to check too.

    And you can go on a shopping spree. There is more than one of
    these out there, but they are cut for speed, not necessarily
    for considering absolutely every condition. The domain and range
    could differ, compared to a library quality implementation.

    # ipow()

    https://gist.github.com/orlp/3551590

    Paul

    https://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 16:49:32 2026
    From Newsgroup: comp.lang.c

    On 8/11/2026 4:41 PM, Lynn McGuire wrote:
    On 8/11/2026 12:15 PM, Janis Papanagnou wrote:
    On 2026-08-11 10:01, Lynn McGuire wrote:
    Why is there not a ipow version of pow?

    It may sound strange (at first glance), but the negated answer would
    probably be easier to answer.

    If there were one one could easily formulate some advantages compared
    to the floating point versions.

    But since there isn't one we can only speculate and say that possible
    advantages were probably not considered worthwhile an addition.

    Other languages support it, probably with overloaded operators for a
    unified looking expressions experience, but underlying functions may
    nonetheless differ (depending on the involved types and signatures).

    ipow would return an int instead of a double.-a Or a long long int.

    Yes. Even the semantics may vary (compared to a float version); e.g.
    while a (primitive) float version might be formulated using exp/ln
    for the whole range of numbers an-a int x int -> int-a version might
    not be defined for exponents less than zero. (Or, as I've noticed in
    one of the posted algorithms, might just return 0.) And-a real x real
    real-a and-a real x int -> real-a might be two other implementations.
    All three distinct.

    Curious; is your question just an academical one (out of interest) or
    do you have a specific demand for it?

    When I started programming decades ago accuracy was an issue, so the
    exp/ln approach was not always appropriate. Also speed of computation.
    But things have changed since then, concerning accuracy of floats and
    the speed of math operations. So check your requirements and make sure
    whether the supported "pow" functions do what you need, else implement
    one or find a good one on the Internet. (I've seen a sensible looking
    version posted here in this thread.)

    Janis

    I have pow of an integer to an integer power in my code, yes.

    I am converting 800,000 lines of F77 code to C++.

    Lynn

    Here is some of the code:

    longint i__1 = *ng;
    for (ig = 1; ig <= i__1; ++ig) {
    ihold = 0;
    ntype = ntpg[ig - 1];
    longint i__2 = ntype;
    for (it = 1; it <= i__2; ++it) {
    ++itup;
    igo = grou[itup - 1];
    if (it == 1) {
    ihldty = igo;
    }
    iun = defaul[igo - 1];
    if (igo == 2 && it > 1) {
    iun = 2;
    }
    if (*iflag == 2 && igo == 8) {
    iun = 2;
    }
    if (*iflag == 2 && igo == 7) {
    iun = 1;
    }
    longint i__3 = it - 1;
    ihold += iun * pow (mul, i__3);
    }

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.c++,comp.lang.c on Tue Aug 11 23:28:56 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 22:49, Lynn McGuire wrote:
    On 8/11/2026 4:41 PM, Lynn McGuire wrote:
    On 8/11/2026 12:15 PM, Janis Papanagnou wrote:
    On 2026-08-11 10:01, Lynn McGuire wrote:
    Why is there not a ipow version of pow?

    It may sound strange (at first glance), but the negated answer would
    probably be easier to answer.

    If there were one one could easily formulate some advantages compared
    to the floating point versions.

    But since there isn't one we can only speculate and say that possible
    advantages were probably not considered worthwhile an addition.

    Other languages support it, probably with overloaded operators for a
    unified looking expressions experience, but underlying functions may
    nonetheless differ (depending on the involved types and signatures).

    ipow would return an int instead of a double.-a Or a long long int.

    Yes. Even the semantics may vary (compared to a float version); e.g.
    while a (primitive) float version might be formulated using exp/ln
    for the whole range of numbers an-a int x int -> int-a version might
    not be defined for exponents less than zero. (Or, as I've noticed in
    one of the posted algorithms, might just return 0.) And-a real x real
    real-a and-a real x int -> real-a might be two other implementations. >>> All three distinct.

    Curious; is your question just an academical one (out of interest) or
    do you have a specific demand for it?

    When I started programming decades ago accuracy was an issue, so the
    exp/ln approach was not always appropriate. Also speed of computation.
    But things have changed since then, concerning accuracy of floats and
    the speed of math operations. So check your requirements and make sure
    whether the supported "pow" functions do what you need, else implement
    one or find a good one on the Internet. (I've seen a sensible looking
    version posted here in this thread.)

    Janis

    I have pow of an integer to an integer power in my code, yes.

    I am converting 800,000 lines of F77 code to C++.

    Lynn

    Here is some of the code:

    -a-a-a longint i__1 = *ng;
    -a-a-a for (ig = 1; ig <= i__1; ++ig) {
    -a-a-a-a-a-a-a ihold = 0;
    -a-a-a-a-a-a-a ntype = ntpg[ig - 1];
    -a-a-a-a-a-a-a longint i__2 = ntype;
    -a-a-a-a-a-a-a for (it = 1; it <= i__2; ++it) {
    -a-a-a-a-a-a-a-a-a-a-a ++itup;
    -a-a-a-a-a-a-a-a-a-a-a igo = grou[itup - 1];
    -a-a-a-a-a-a-a-a-a-a-a if (it == 1) {
    -a-a-a-a-a-a-a-a-a-a-a ihldty = igo;
    -a-a-a-a-a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a-a-a-a-a iun = defaul[igo - 1];
    -a-a-a-a-a-a-a-a-a-a-a if (igo == 2 && it > 1) {
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a iun = 2;
    -a-a-a-a-a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a-a-a-a-a if (*iflag == 2 && igo == 8) {
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a iun = 2;
    -a-a-a-a-a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a-a-a-a-a if (*iflag == 2 && igo == 7) {
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a iun = 1;
    -a-a-a-a-a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a-a-a-a-a longint i__3 = it - 1;
    -a-a-a-a-a-a-a-a-a-a-a ihold += iun * pow (mul, i__3);
    -a-a-a-a-a-a-a }

    That doesn't look like Fortran! So it's already been converted, and it
    was decided to turn A**B (or whatever Fortran used) into pow(A, B)?

    However I don't really see the problem. Just write some function 'ipow'
    for example (you already have a link to one), and use it in place of 'pow'.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 15:33:03 2026
    From Newsgroup: comp.lang.c

    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    [...]
    On 2026-08-11 10:01, Lynn McGuire wrote:
    Why is there not a ipow version of pow?
    [...]
    I have pow of an integer to an integer power in my code, yes.

    I am converting 800,000 lines of F77 code to C++.

    It's a perfectly valid question, but I don't think any answer is
    going to help you with your immediate problem.

    I think the best solution to your immediate problem would be to write
    your own ipow() function(s). Depending on the actual exponents,
    it might be worth optimizing it by using squaring, so for example
    ipow(n, 4) performs 2 multiplications rather than 3. As I recall,
    you're already modifying the C code produced by f2c.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 17:49:56 2026
    From Newsgroup: comp.lang.c

    On 8/11/2026 5:33 PM, Keith Thompson wrote:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    [...]
    On 2026-08-11 10:01, Lynn McGuire wrote:
    Why is there not a ipow version of pow?
    [...]
    I have pow of an integer to an integer power in my code, yes.

    I am converting 800,000 lines of F77 code to C++.

    It's a perfectly valid question, but I don't think any answer is
    going to help you with your immediate problem.

    I think the best solution to your immediate problem would be to write
    your own ipow() function(s). Depending on the actual exponents,
    it might be worth optimizing it by using squaring, so for example
    ipow(n, 4) performs 2 multiplications rather than 3. As I recall,
    you're already modifying the C code produced by f2c.

    I agree with writing my own "long long int ipow (long long int, long
    long int)" code. Both situations that I have found are in my input file parser code dealing with dimensional unit conversions. So efficiency is
    not a big deal, but rigorousness and correctness is very important to me.

    I put BigDigits into my software decades ago but all of the power
    functions there are unrolled powers of 2.
    https://di-mgt.com.au/bigdigits.html

    All of my other power calculations are in my double precision code with
    lots and lots and lots of looping.

    Thanks to all !

    Lynn McGuire

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 17:51:55 2026
    From Newsgroup: comp.lang.c

    On 8/11/2026 5:28 PM, bart wrote:
    ...
    I have pow of an integer to an integer power in my code, yes.

    I am converting 800,000 lines of F77 code to C++.

    Lynn

    Here is some of the code:

    -a-a-a-a longint i__1 = *ng;
    -a-a-a-a for (ig = 1; ig <= i__1; ++ig) {
    -a-a-a-a-a-a-a-a ihold = 0;
    -a-a-a-a-a-a-a-a ntype = ntpg[ig - 1];
    -a-a-a-a-a-a-a-a longint i__2 = ntype;
    -a-a-a-a-a-a-a-a for (it = 1; it <= i__2; ++it) {
    -a-a-a-a-a-a-a-a-a-a-a-a ++itup;
    -a-a-a-a-a-a-a-a-a-a-a-a igo = grou[itup - 1];
    -a-a-a-a-a-a-a-a-a-a-a-a if (it == 1) {
    -a-a-a-a-a-a-a-a-a-a-a-a ihldty = igo;
    -a-a-a-a-a-a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a-a-a-a-a-a iun = defaul[igo - 1];
    -a-a-a-a-a-a-a-a-a-a-a-a if (igo == 2 && it > 1) {
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a iun = 2;
    -a-a-a-a-a-a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a-a-a-a-a-a if (*iflag == 2 && igo == 8) {
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a iun = 2;
    -a-a-a-a-a-a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a-a-a-a-a-a if (*iflag == 2 && igo == 7) {
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a iun = 1;
    -a-a-a-a-a-a-a-a-a-a-a-a }
    -a-a-a-a-a-a-a-a-a-a-a-a longint i__3 = it - 1;
    -a-a-a-a-a-a-a-a-a-a-a-a ihold += iun * pow (mul, i__3);
    -a-a-a-a-a-a-a-a }

    That doesn't look like Fortran! So it's already been converted, and it
    was decided to turn A**B (or whatever Fortran used) into pow(A, B)?

    However I don't really see the problem. Just write some function 'ipow'
    for example (you already have a link to one), and use it in place of 'pow'.

    I agree with writing my own "long long int ipow (long long int, long
    long int)" code. Both situations that I have found are in my input file parser code dealing with dimensional unit conversions. So efficiency is
    not a big deal, but rigorousness and correctness is very important to me.

    I put BigDigits into my software decades ago but all of the power
    functions there are unrolled powers of 2.
    https://di-mgt.com.au/bigdigits.html

    All of my other power calculations are in my double precision code with
    lots and lots and lots of looping.

    Thanks to all !

    Lynn McGuire
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.lang.c++,comp.lang.c on Tue Aug 11 22:53:04 2026
    From Newsgroup: comp.lang.c

    In comp.lang.c David Brown <david.brown@hesbynett.no> wrote:
    On 11/08/2026 17:20, Bonita Montero wrote:
    Am 11.08.2026 um 17:11 schrieb David Brown:

    He has numbers for dozens of x86 processors.-a There are many others
    that he has not covered.-a (But he has done a truly amazing job with
    the x86 world.)

    Agner covers almost all x86-microarcitecures that have been seen so far.

    Most processors in the world are /not/ x86. On some devices, a floating point multiply will be perhaps 200 times slower than an integer
    multiply. You may also find that on some devices with 32-bit GPRs and 64-bit hardware floating point, floating point multiplication could be faster than 64-bit integer multiplication. Anger covers the x86 world,
    not the entire processor world.



    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    Check the glibc sourcecode. Binary exponentation is the fastest way
    to to that and the way with the least precision loss.


    Let me try again.

    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    In floating point this formula is loosing accuracy for very large
    'a'. The is pressure on library authors to deliver high accuracy,
    so there is nontrivial chance that library is using much more
    complicated (and expensive) method to compute the resut.

    /Obviously/ the base used for the "exp" and "log" is base 2, since that
    is the most efficient base for calculating "exp" and "log" on a binary computer, especially with standard floating point formats.

    This is rather unfortunate statement. Logaritms are defined for
    any base and "pow(a, b)" has alternative name as "exponential function
    with base a". Of course log above is natural log, that is base 'e'
    and 'exp(x)' means "e to power a", so normaly wordy version would be "exponential with base e". To avoid loss of accuracy library
    may write a as 2^k*m with m mot too far from 1 and then it may
    use higher precision computation to handle 2^k part. You can
    view 'k' above as base 2 logarithm of 2^k. But for m base 2
    give only troubles and if you multiply k times b you typically
    get something that is not an integer, so exponential in base 2
    really boils down to multiplying by log(2) and normal exp. In
    other words, you are likely to use log(2) in computation (it may
    be stored to desired accuracy), but you really are not using
    exponential with base 2.
    --
    Waldek Hebisch
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 16:19:49 2026
    From Newsgroup: comp.lang.c

    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 8/11/2026 5:33 PM, Keith Thompson wrote:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    [...]
    On 2026-08-11 10:01, Lynn McGuire wrote:
    Why is there not a ipow version of pow?
    [...]
    I have pow of an integer to an integer power in my code, yes.

    I am converting 800,000 lines of F77 code to C++.
    It's a perfectly valid question, but I don't think any answer is
    going to help you with your immediate problem.
    I think the best solution to your immediate problem would be to
    write
    your own ipow() function(s). Depending on the actual exponents,
    it might be worth optimizing it by using squaring, so for example
    ipow(n, 4) performs 2 multiplications rather than 3. As I recall,
    you're already modifying the C code produced by f2c.

    I agree with writing my own "long long int ipow (long long int, long
    long int)" code. Both situations that I have found are in my input
    file parser code dealing with dimensional unit conversions. So
    efficiency is not a big deal, but rigorousness and correctness is very important to me.

    The name "ipow" doesn't suggest an operation on long long.

    If you want generality, you might want something like:

    int ipow(int, int);
    long ipowl(long, int);
    long long ipowll(long long, int);


    (Or you can overload ipow() if you're using C++, but I thought
    you were just converting Fortran to C, which makes me wonder why
    you cross-posted.)

    Note that I'm assuming the exponent is an int in all cases.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 16:20:30 2026
    From Newsgroup: comp.lang.c

    bart <bc@freeuk.com> writes:
    On 11/08/2026 15:56, Bonita Montero wrote:
    This is the integer pow() code so far I wrote in C++:
    [snip]

    Can you package this into something I can all as ipow(a, b)?

    As it is this doesn't compile by itself.

    Not by itself, no. I was able to get it to compile by adding a
    few lines at the top. I won't go into details in a thread that's inappropriately cross-posted to comp.lang.c.

    Ask in comp.lang.c++ without the crosspost to comp.lang.c, and I'll
    be glad to explain if nobody else does so first.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c++,comp.lang.c on Wed Aug 12 04:26:22 2026
    From Newsgroup: comp.lang.c

    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs
    all down to dynamic range. Logs and exponentials by their nature are
    liable to cover a huge range of magnitudes in either the argument
    (logarithm) or result (exponential). Integer formats in common use do
    not cater for this. Whereas with floating-point -- well, itrCOs there in
    the name, isnrCOt it?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 06:41:08 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 23:10 schrieb Scott Lurndal:

    Depends on clock speed. The Neoverse-N2 integer multiply instruction
    has a latency of 2 cycles and throughput of one per cycle. Seems
    fast enough.

    According to the AI it's three cycles.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 06:42:43 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 21:41 schrieb bart:

    People don't care about integer overflow in general, why should they here?

    Yes, because it happens almost never. But when it happens you handle it.
    And with an integer pow() it's rather likely.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Ross Finlayson@ross.a.finlayson@gmail.com to comp.lang.c++,comp.lang.c on Tue Aug 11 21:44:18 2026
    From Newsgroup: comp.lang.c

    On 08/11/2026 07:18 AM, Bonita Montero wrote:
    Am 11.08.2026 um 16:08 schrieb David Brown:

    You did. You failed to mention the vital fact that this applies to
    some processors and not others, but it is apparently correct for Zen 4
    processors at least.

    Agner has taken this numbers on dozens of CPUs, and if you compare
    fp- and integer-times you've mostly the same relationship.

    It is, however, almost entirely irrelevant to the OP or to calculating
    "pow" in floating point or integer arithmetic. Floating point "pow"
    does not use multiplication (assuming the target processor has
    dedicated instructions for logs and anti-logs).

    Of course it doesn multiplications. It multiplies base by itself as
    long there are exponent bits and if an exponent bit is set the currently calulated value is multiplied by the base ^ (2 ^ n) value. For the frac-
    tion bits the square root is inrementally done in the same way. That's
    called binary exponentation.


    https://en.wikipedia.org/wiki/Stirling%27s_formula

    If there's a neat way to compute factorial fast,
    then there's a term in Stirling's formula that
    gives e^n, that can be transformed to b^n.

    Lanczos also has an approximation for n!,
    also I wrote one in about 2003.


    That Wikipedia is a fantastic resource and
    all the bot-chat quite slurped and leeched it,
    the bot-chat owes Wikipedia more than a gratuity.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 06:45:27 2026
    From Newsgroup: comp.lang.c

    Am 11.08.2026 um 21:27 schrieb bart:

    When I tried to compile this, it said: C:/tdm/include/c++/16.1.0/optional:1256: constexpr _Tp&& std::optional<_Tp>::operator*() && [with _T
    p = long long int]: Assertion 'this->_M_is_engaged()' failed.

    For me it compiles with g++-14 and clang++-20 and C++23 (-std:c++20).


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 00:32:37 2026
    From Newsgroup: comp.lang.c

    On 8/11/2026 6:19 PM, Keith Thompson wrote:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 8/11/2026 5:33 PM, Keith Thompson wrote:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    [...]
    On 2026-08-11 10:01, Lynn McGuire wrote:
    Why is there not a ipow version of pow?
    [...]
    I have pow of an integer to an integer power in my code, yes.

    I am converting 800,000 lines of F77 code to C++.
    It's a perfectly valid question, but I don't think any answer is
    going to help you with your immediate problem.
    I think the best solution to your immediate problem would be to
    write
    your own ipow() function(s). Depending on the actual exponents,
    it might be worth optimizing it by using squaring, so for example
    ipow(n, 4) performs 2 multiplications rather than 3. As I recall,
    you're already modifying the C code produced by f2c.

    I agree with writing my own "long long int ipow (long long int, long
    long int)" code. Both situations that I have found are in my input
    file parser code dealing with dimensional unit conversions. So
    efficiency is not a big deal, but rigorousness and correctness is very
    important to me.

    The name "ipow" doesn't suggest an operation on long long.

    If you want generality, you might want something like:

    int ipow(int, int);
    long ipowl(long, int);
    long long ipowll(long long, int);


    (Or you can overload ipow() if you're using C++, but I thought
    you were just converting Fortran to C, which makes me wonder why
    you cross-posted.)

    Note that I'm assuming the exponent is an int in all cases.

    I am converting my F77 code to C++. I am really big on type safety
    after writing a bunch of Smalltalk code back in the 1980s and 1990s.

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 01:37:45 2026
    From Newsgroup: comp.lang.c

    On 8/11/2026 11:26 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs
    all down to dynamic range. Logs and exponentials by their nature are
    liable to cover a huge range of magnitudes in either the argument
    (logarithm) or result (exponential). Integer formats in common use do
    not cater for this. Whereas with floating-point -- well, itrCOs there in
    the name, isnrCOt it?

    This is why you calculate and return a long long int. Or maybe even a
    128 bit int.

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 08:49:43 2026
    From Newsgroup: comp.lang.c

    There was a very little mistake with my last code: If the exponent is
    negative (immediate return), abs( base ) == 1 and the exponent is odd,
    the return is not 1 vs. 0 but -1 vs 0.
    And there are two *theoretical* UBs I cover. If either base or exponent
    have the maximum negative values negating them is UB. So now I do a
    0u - (uint)value. But that's rather aesthetics on today's platforms.
    Claude and GPT don't complain about my code now.
    Didn't think that this code would be so tricky at last. And the major
    issue with my code is: no one needs a pow for integers, even my pow()
    is faster for valid values than a fp-pow().
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Wed Aug 12 10:23:21 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 21:41, bart wrote:
    On 11/08/2026 18:56, Bonita Montero wrote:
    Am 11.08.2026 um 19:43 schrieb bart:

    Why do you need all that? You basically just want ipow(a, 4) to
    return a*a*a*a.

    To have variable exponents.

    You mean ipow(a, b) where b is known at runtime?

    Then that's exactly what I mean. This should be the equivalant of
    a*a*a...*a with b-1 multiplications, but done more efficiently.

    For example my function can calculate ipow(1, 1000000) 10,000 times
    faster than a version that simply does 1000000 or so multiplications.


    If worried about overflow, then use floating point pow().

    I did this to compare the performance, but I didn't run the numbers on
    that. I mentioned that the overflow detection needs a division, thereby
    making the code not competitive to a fp-version.


    People don't care about integer overflow in general, why should they here?

    Most people /do/ care about integer overflows - they aim to use types
    and expressions that don't overflow. If you assume that the person
    calling your "ipow" function only does so with sensible values, then the implementation of "ipow" doesn't have to consider overflow and can be
    simpler and faster (like your code, or my code). This is not because no
    one cares about integer overflow, it's about putting the responsibility
    in the place where the potential bug actually exists and can therefore
    be fixed.

    Of course it is also possible to write an integer power function that saturates on overflow, or that has some error indicator, but that's a different function specification. Bonita is apparently trying to code
    for such a function.


    However if large-magnitude results (greater than 2**63) are likely, then they should go with floats and use pow, at a loss of some precision.


    Yes.

    Or it might be more useful to have a half-way function:

    double power_by_int(double a, int b);

    (Here "b" is allowed to be negative.)

    That would use the same multiplication algorithm as we have shown
    previously.

    Or use the same algorithm with a bigint library as I also do.

    For big values of "b", the most common usage of "a ** b" is to calculate
    "(a ** b) % c". And clearly you do that as a single function, not by
    doing the power operation then the modulo operation. But once you have
    your bigint support for multiplication, adding a "power" function like
    the one you wrote is going to be quite simple even if it is never used
    for large values of "b".


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.c++,comp.lang.c on Wed Aug 12 11:28:34 2026
    From Newsgroup: comp.lang.c

    On 12/08/2026 05:26, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs
    all down to dynamic range. Logs and exponentials by their nature are
    liable to cover a huge range of magnitudes in either the argument
    (logarithm) or result (exponential). Integer formats in common use do
    not cater for this. Whereas with floating-point -- well, itrCOs there in
    the name, isnrCOt it?

    'ipow()' is just a convenient way to do repeated integer multiplication.

    You may not have need for it yourself, but here Fortran code is being
    ported to C and Fortran does have it, /and/ it is being used in the
    program being ported.

    Usually it is not as mathematical as the float version (I don't know if
    that is the case here).

    It is certainly convenient to be able to write 2**32 instead of 1<<32,
    where it is so easy to write 2<<32 by mistake.

    Also, since in C you have to emulate it by a function like ipow(a, b)
    anyway, then ipow can be made to take i64 arguments (for a at least),
    then it doesn't even matter if you forget to write 1ULL for my example.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 03:58:16 2026
    From Newsgroup: comp.lang.c

    David Brown <david.brown@hesbynett.no> writes:
    [...]
    And I thought it is entirely obvious that when you are actually
    implementing a floating point power function on a binary computer
    using floating point formats specified in binary, it is most efficient
    to use base 2 for the log and anti-log. If you had a floating point
    format that used base 10, you'd probably want to use base 10 for the
    log and anti-log.

    Is it obvious? It had never occurred to me.

    log and exp are certainly more mathematically straightforward in
    base e than in other bases. Of course floating-point is typically
    binary, but I didn't know that would imply that log(x) base 2 is
    easier to compute that log(x) base e. I've always assumed that
    base e is more efficient than other bases.

    Also, I vaguely recall that though x**y is mathematically equivalent
    to exp(y * log(x)), that's not the most efficient and/or accurate
    way to compute it.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Wed Aug 12 13:31:30 2026
    From Newsgroup: comp.lang.c

    On 12/08/2026 12:58, Keith Thompson wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    And I thought it is entirely obvious that when you are actually
    implementing a floating point power function on a binary computer
    using floating point formats specified in binary, it is most efficient
    to use base 2 for the log and anti-log. If you had a floating point
    format that used base 10, you'd probably want to use base 10 for the
    log and anti-log.

    Is it obvious? It had never occurred to me.

    log and exp are certainly more mathematically straightforward in
    base e than in other bases. Of course floating-point is typically
    binary, but I didn't know that would imply that log(x) base 2 is
    easier to compute that log(x) base e. I've always assumed that
    base e is more efficient than other bases.

    Maybe I have been too quick to jump to conclusions. I have not done
    much work with implementing such floating point functions - when I have implementing things like trig functions it is because I needed a very different balance of speed and precision than standard library
    functions, and where I have a clear knowledge of the range needed.
    There's a lot of detail in making a good "pow" function that I don't know.

    However, when dealing with logs and anti-logs of floating point numbers,
    you are going to use base 2 for at least part of the job. Your float f
    is already in the form m * (2 ** p), so log_n(f) will be log_n(m) +
    log_n(2 ** p), the later part being p * log_n(2). If you can keep that
    part as the simple integer "p" for the rest of your calculations - using
    base n = 2 for that part at least, then you would probably want to do
    that. Similarly, anti-logs of integer parts are easiest in base 2 and
    turn into an addition or subtraction on the exponent part of the
    floating point format.

    In general, I don't think logs or exponents are likely to be much
    difference to calculate in different bases. Clearly base "e" is nicer mathematically, but I expect you'd be doing numerical calculations using
    range reductions, then approximation polynomials, and different bases
    just mean different factors in the polynomials.

    The biggest factor, I expect, is how this all fits with instruction sets
    on the target processor. I've been thinking in terms of doing it all in software - particular instructions might make a big change to the best tactics.


    Also, I vaguely recall that though x**y is mathematically equivalent
    to exp(y * log(x)), that's not the most efficient and/or accurate
    way to compute it.


    Certainly there are complications involved to keep the accuracy. You
    would not want to use this expression as-is. At the very least, I would expect you would handle the mantissa and exponent of the float separately.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 14:08:44 2026
    From Newsgroup: comp.lang.c

    The difference between my code and that of Fortran 77 are:

    * 0 ^ 0 is forbidden with F77, the result of my code is one.
    * 0 ^ -n is forbidden with F77, the result of my code is infinite
    / unexpected( true ).
    * F77 doesn't have an overflow detection, I return unexpected( false ).

    The following code is slightly changed in it's API.

    template<typename Int>
    constexpr expected<Int, bool> ipow( Int b, Int e )
    {
    constexpr bool Sgn = is_signed_v<Int>;
    using uint = make_unsigned_t<Int>;
    constexpr auto
    Infinite = unexpected( true ),
    Overflow = unexpected( false );
    if( !b )
    if constexpr( Sgn )
    if( e >= 0 )
    return !e;
    else
    return Infinite;
    else
    return !e;
    uint ub = b, ue = e;
    if constexpr( Sgn )
    if( constexpr auto *Abs = +[]( Int v ) -> uint { return v >= 0 ? v :
    0u - (uint)v; };
    e >= 0 ) [[likely]]
    {
    ub = Abs( b );
    ue = Abs( e );
    }
    else
    {
    Int neg = -(e & 1);
    return ((Abs( b ) == 1 ? b : 0) ^ neg) - neg;
    }
    uint result = 1, sq = ub;
    for( int xskip = 0; ue; xskip = 1 ) [[likely]]
    {
    int skip = countr_zero( ue );
    for( int s = skip + xskip; s; sq *= sq, --s ) [[likely]]
    if( (uint)(sq * sq) / sq != sq ) [[unlikely]]
    return Overflow;
    if( (uint)(result * sq) / sq != result ) [[unlikely]]
    return Overflow;
    result *= sq;
    ue >>= skip;
    ue >>= 1;
    }
    constexpr uint UMax = numeric_limits<Int>::min();
    if constexpr( Sgn )
    if( b < 0 && (e & 1) ) [[unlikely]]
    if( result <= UMax ) [[likely]]
    result = -(Int)result;
    else
    return Overflow;
    else
    if( result >= UMax ) [[unlikely]]
    return Overflow;
    return (Int)result;
    }

    A return value of unexpected( true ) is infinity and unexpected( false )
    is an overflow.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Paul@nospam@needed.invalid to comp.lang.c++,comp.lang.c on Wed Aug 12 09:11:38 2026
    From Newsgroup: comp.lang.c

    On Wed, 8/12/2026 2:49 AM, Bonita Montero wrote:
    There was a very little mistake with my last code: If the exponent is negative (immediate return), abs( base ) == 1 and the exponent is odd,
    the return is not 1 vs. 0 but -1 vs 0.
    And there are two *theoretical* UBs I cover. If either base or exponent
    have the maximum negative values negating them is UB. So now I do a
    0u - (uint)value. But that's rather aesthetics on today's platforms.
    Claude and GPT don't complain about my code now.
    Didn't think that this code would be so tricky at last. And the major
    issue with my code is: no one needs a pow for integers, even my pow()
    is faster for valid values than a fp-pow().

    And this highlights the issue with crafting your own.

    https://gmplib.org/manual/Integer-Functions

    https://gmplib.org/manual/Integer-Exponentiation

    Function: void mpz_pow_ui (mpz_t rop, const mpz_t base, unsigned long int exp)
    Function: void mpz_ui_pow_ui (mpz_t rop, unsigned long int base, unsigned long int exp)

    Maybe one of those two is actually an ipow() :-)

    And since this function is so ugly (the special cases may not
    make any sense to you, like who goes around doing ipow(0,0)),
    you really need a test bench for it. For some softwares,
    the test bench has more intellectual property associated with
    it, than any generated code for it. Getting routines like this
    right, is easier when what the code is doing, matches your
    grade school knowledge of what the answer should be.

    I would not trust an LLM-AI to do an off-the-cuff analysis
    of the code for this one. Claude may have a slight edge over
    the competition, but LLM-AI really do make mistakes, and it
    isn't pretty when they do.

    Paul

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 16:05:07 2026
    From Newsgroup: comp.lang.c

    Am 12.08.2026 um 15:11 schrieb Paul:

    I would not trust an LLM-AI to do an off-the-cuff analysis
    of the code for this one. Claude may have a slight edge over
    the competition, but LLM-AI really do make mistakes, and it
    isn't pretty when they do.

    If Claude sees 95% of all issues that's useful.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c++,comp.lang.c on Wed Aug 12 14:19:38 2026
    From Newsgroup: comp.lang.c

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 11.08.2026 um 23:10 schrieb Scott Lurndal:

    Depends on clock speed. The Neoverse-N2 integer multiply instruction
    has a latency of 2 cycles and throughput of one per cycle. Seems
    fast enough.

    According to the AI it's three cycles.

    Yet another case where the AI is wrong.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 16:56:38 2026
    From Newsgroup: comp.lang.c

    Am 12.08.2026 um 16:19 schrieb Scott Lurndal:

    Bonita Montero <Bonita.Montero@gmail.com> writes:

    According to the AI it's three cycles.

    Yet another case where the AI is wrong.

    Show me the documentation.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c++,comp.lang.c on Wed Aug 12 15:32:53 2026
    From Newsgroup: comp.lang.c

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 12.08.2026 um 16:19 schrieb Scott Lurndal:

    Bonita Montero <Bonita.Montero@gmail.com> writes:

    According to the AI it's three cycles.

    Yet another case where the AI is wrong.

    Show me the documentation.

    https://support.arm.com/documentation/109914/0500/

    page 21
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 18:40:37 2026
    From Newsgroup: comp.lang.c

    Nice fact: clang++ and g++ are *much* faster than MSVC with my code.
    I asked my self why is that and I had a look at the compiled code.
    I do a "b * e / b == b" check. MSVC uses a division for that. g++
    and clang++ just check the overflow flag after doing the multipli-
    cation. I guess that makes the difference since the other code is
    similar.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c++,comp.lang.c on Wed Aug 12 22:05:17 2026
    From Newsgroup: comp.lang.c

    On Wed, 12 Aug 2026 06:41:08 +0200
    Bonita Montero <Bonita.Montero@gmail.com> wrote:

    Am 11.08.2026 um 23:10 schrieb Scott Lurndal:

    Depends on clock speed. The Neoverse-N2 integer multiply
    instruction has a latency of 2 cycles and throughput of one per
    cycle. Seems fast enough.

    According to the AI it's three cycles.

    3 cycles is umulh. Normal umul/imul is 2.
    You AI probably can't distinguish between Neoverse-N2 (derived from Cortex-A710, which is ARMv9 variant of A78) and Neoverse-N1 (derived
    from Cortex-A76).

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 12:40:14 2026
    From Newsgroup: comp.lang.c

    On 8/12/2026 7:05 AM, Bonita Montero wrote:
    Am 12.08.2026 um 15:11 schrieb Paul:

    I would not trust an LLM-AI to do an off-the-cuff analysis
    of the code for this one. Claude may have a slight edge over
    the competition, but LLM-AI really do make mistakes, and it
    isn't pretty when they do.

    If Claude sees 95% of all issues that's useful.


    Why not use your own mind, for your own work?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c++,comp.lang.c on Wed Aug 12 22:43:33 2026
    From Newsgroup: comp.lang.c

    On Wed, 12 Aug 2026 03:58:16 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    David Brown <david.brown@hesbynett.no> writes:
    [...]
    And I thought it is entirely obvious that when you are actually implementing a floating point power function on a binary computer
    using floating point formats specified in binary, it is most
    efficient to use base 2 for the log and anti-log. If you had a
    floating point format that used base 10, you'd probably want to use
    base 10 for the log and anti-log.

    Is it obvious? It had never occurred to me.

    log and exp are certainly more mathematically straightforward in
    base e than in other bases.

    Only near x=1 for log(x) and near x=0 for exp(x).

    Of course floating-point is typically
    binary, but I didn't know that would imply that log(x) base 2 is
    easier to compute that log(x) base e. I've always assumed that
    base e is more efficient than other bases.

    You are mostly wrong. David is mostly correct.


    Also, I vaguely recall that though x**y is mathematically equivalent
    to exp(y * log(x)), that's not the most efficient and/or accurate
    way to compute it.


    Apart from corner cases, it is the most efficient.
    And I am pretty sure that it's sufficiently accurate for most uses,
    including you typical C library. I did no deep numeric analysis, but my intuition suggest that as long as underlaying primitives, i.e. log2 and
    2**x, are well implemented, i.e. their maximal error is under 0.6 ULP,
    then the worst case error of combined calculation should be below 2.5
    ULP and most likely even lower than that. Which is good enough.
    For more than 50% of inputs you will end within 1 ULP.

    Of course, you don't do it stupidly. You start by splitting a with
    frexp() and splitting b to integer and fractional, probably with
    fractional in range [-0.5:0.5]. Then you take away trivial parts, i.e
    integer power of two. But then you come to the main part and this part
    is as David suggested.






    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.lang.c++,comp.lang.c on Wed Aug 12 20:23:17 2026
    From Newsgroup: comp.lang.c

    In comp.lang.c David Brown <david.brown@hesbynett.no> wrote:
    On 12/08/2026 00:53, Waldek Hebisch wrote:
    In comp.lang.c David Brown <david.brown@hesbynett.no> wrote:
    On 11/08/2026 17:20, Bonita Montero wrote:
    Am 11.08.2026 um 17:11 schrieb David Brown:

    He has numbers for dozens of x86 processors.-a There are many others >>>>> that he has not covered.-a (But he has done a truly amazing job with >>>>> the x86 world.)

    Agner covers almost all x86-microarcitecures that have been seen so far. >>>
    Most processors in the world are /not/ x86. On some devices, a floating >>> point multiply will be perhaps 200 times slower than an integer
    multiply. You may also find that on some devices with 32-bit GPRs and
    64-bit hardware floating point, floating point multiplication could be
    faster than 64-bit integer multiplication. Anger covers the x86 world,
    not the entire processor world.



    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    Check the glibc sourcecode. Binary exponentation is the fastest way
    to to that and the way with the least precision loss.


    Let me try again.

    "pow(a, b)" is implemented approximately as "exp(b * log(a))".

    In floating point this formula is loosing accuracy for very large
    'a'. The is pressure on library authors to deliver high accuracy,
    so there is nontrivial chance that library is using much more
    complicated (and expensive) method to compute the resut.

    That's why I wrote "approximately". I realise there are a lot of
    details involved to make the calculation of "pow" work accurately over a wide range of values. My point was merely that calculation of powers
    with floating point is done with that mathematical formula at heart,
    which is entirely different from how an integer power function is
    usually calculated (by repeated multiplication).


    /Obviously/ the base used for the "exp" and "log" is base 2, since that
    is the most efficient base for calculating "exp" and "log" on a binary
    computer, especially with standard floating point formats.

    This is rather unfortunate statement. Logaritms are defined for
    any base and "pow(a, b)" has alternative name as "exponential function
    with base a". Of course log above is natural log, that is base 'e'
    and 'exp(x)' means "e to power a", so normaly wordy version would be
    "exponential with base e".
    No, "log" and "exp" as words alone do /not/ imply base "e" - or any
    other specific base. Within some contexts, there may be an implication
    from common usage - and "context" may include "that's what we wrote at school or university in my country", "that's the name used in the
    standard library", "that's the buttons on my calculator", etc. To be
    fair, these are the names for the functions in base "e" in the C
    standard library, and that is a reasonable context to use in these
    Usenet groups. I should therefore have been a bit clearer that that was
    not what I meant.

    I thought it was quite clear that I was referring to a general log and anti-log function pair, writing as mathematics and not as a C
    expression. From the maths viewpoint, the base does not matter (at
    least for a sane base - a real number greater than 1), as long as it is consistent.

    And I thought it is entirely obvious that when you are actually
    implementing a floating point power function on a binary computer using floating point formats specified in binary, it is most efficient to use
    base 2 for the log and anti-log. If you had a floating point format
    that used base 10, you'd probably want to use base 10 for the log and anti-log.

    I see. It is kinda "obvious", but wrong. In a sense base is a
    trivial detail, you multiply result of 'log' by appropriate
    constant to get any base you need and you divide argument of
    'exp' to get different base. But when you get to meat of the
    calculation other bases have no advantage compared to base e
    (for some approaches base e is a clear winner, for other it is
    a tie).

    This is all implementation detail, and not the focus of my post.

    But again, given that "exp" and "log" are base "e" functions in the C standard library, I should have been clearer there.




    --
    Waldek Hebisch
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 13:44:50 2026
    From Newsgroup: comp.lang.c

    Michael S <already5chosen@yahoo.com> writes:
    On Wed, 12 Aug 2026 03:58:16 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    And I thought it is entirely obvious that when you are actually
    implementing a floating point power function on a binary computer
    using floating point formats specified in binary, it is most
    efficient to use base 2 for the log and anti-log. If you had a
    floating point format that used base 10, you'd probably want to use
    base 10 for the log and anti-log.

    Is it obvious? It had never occurred to me.

    log and exp are certainly more mathematically straightforward in
    base e than in other bases.

    Only near x=1 for log(x) and near x=0 for exp(x).

    Can you explain what you mean by that?

    Mathematically, exp(x) (base e) is described by the Taylor series.
    In clumsy ASCII notation, it's:

    1 + x + x**2/2! + x**3/3! + x**4/4! + ...

    b**x, were b is a base other than e (often 2 or 10) is
    exp(x * log(base)), where exp() and log() are base e. In other
    words, exp and log for bases other than e are most straightforwardly
    defined on top of exp and log for base e.

    That's what I meant by "more mathematically straightforward".

    If you say there are computational reasons why exp2 and log2 are
    advantageous when using binary floating-point, I can believe that.
    I just don't understand the reasons (and to be honest, I'm not sure
    I'd understand an explanation without more effort than I'm willing
    to expend, unless somebody wants to pay me to work on this stuff).

    Of course floating-point is typically
    binary, but I didn't know that would imply that log(x) base 2 is
    easier to compute that log(x) base e. I've always assumed that
    base e is more efficient than other bases.

    You are mostly wrong. David is mostly correct.

    Quite possibly.

    Also, I vaguely recall that though x**y is mathematically equivalent
    to exp(y * log(x)), that's not the most efficient and/or accurate
    way to compute it.

    Apart from corner cases, it is the most efficient.
    And I am pretty sure that it's sufficiently accurate for most uses,
    including you typical C library. I did no deep numeric analysis, but my intuition suggest that as long as underlaying primitives, i.e. log2 and
    2**x, are well implemented, i.e. their maximal error is under 0.6 ULP,

    2**x is provided in <math.h> as exp2(), since C99.

    then the worst case error of combined calculation should be below 2.5
    ULP and most likely even lower than that. Which is good enough.
    For more than 50% of inputs you will end within 1 ULP.

    Of course, you don't do it stupidly. You start by splitting a with
    frexp() and splitting b to integer and fractional, probably with
    fractional in range [-0.5:0.5]. Then you take away trivial parts, i.e
    integer power of two. But then you come to the main part and this part
    is as David suggested.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c++,comp.lang.c on Thu Aug 13 00:24:09 2026
    From Newsgroup: comp.lang.c

    On Wed, 12 Aug 2026 13:44:50 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Wed, 12 Aug 2026 03:58:16 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    And I thought it is entirely obvious that when you are actually
    implementing a floating point power function on a binary computer
    using floating point formats specified in binary, it is most
    efficient to use base 2 for the log and anti-log. If you had a
    floating point format that used base 10, you'd probably want to
    use base 10 for the log and anti-log.

    Is it obvious? It had never occurred to me.

    log and exp are certainly more mathematically straightforward in
    base e than in other bases.

    Only near x=1 for log(x) and near x=0 for exp(x).

    Can you explain what you mean by that?

    Mathematically, exp(x) (base e) is described by the Taylor series.
    In clumsy ASCII notation, it's:

    1 + x + x**2/2! + x**3/3! + x**4/4! + ...

    b**x, were b is a base other than e (often 2 or 10) is
    exp(x * log(base)), where exp() and log() are base e. In other
    words, exp and log for bases other than e are most straightforwardly
    defined on top of exp and log for base e.

    That's what I meant by "more mathematically straightforward".

    If you say there are computational reasons why exp2 and log2 are
    advantageous when using binary floating-point, I can believe that.
    I just don't understand the reasons (and to be honest, I'm not sure
    I'd understand an explanation without more effort than I'm willing
    to expend, unless somebody wants to pay me to work on this stuff).


    It's late here and I want to sleep, so very briefly:
    The best computational way to calculate a**x for constant a on
    relatively big interval of x, like [0:1] or [-0.5:0.5] is not through evaluation of polynomial of very high degree, but by splitting
    interval into sub ranges and calculating y = Yi * a**(x-Xi) where
    Yi is tabulated and may be Xi tabulated too, or may be Xi just regularly spaced. For double precision and for speed/space/precision requirements
    of C math library you will probably want many dozen of intervals, or
    low hundreds. That allows much lower degree of poly for a**(x-Xi).
    And to lower degree even further you use Chebyshev series or may be
    even series derived by Remez exchange algorithm rather than Taylor
    series. It means that even for a=e the second coefficient is not 1 and
    likely the 1st coefficient is also not 1. So, a=e has no advantage vs
    a=2. Of course, in this part of calculation a=2 also holds no
    advantages vs any other base, but it has advantages in other parts of
    of solution.
    Different but ideologically similar reasoning applies to natural
    log vs log2.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Wed Aug 12 16:49:39 2026
    From Newsgroup: comp.lang.c

    On 8/12/2026 4:24 PM, Michael S wrote:
    On Wed, 12 Aug 2026 13:44:50 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Wed, 12 Aug 2026 03:58:16 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    And I thought it is entirely obvious that when you are actually
    implementing a floating point power function on a binary computer
    using floating point formats specified in binary, it is most
    efficient to use base 2 for the log and anti-log. If you had a
    floating point format that used base 10, you'd probably want to
    use base 10 for the log and anti-log.

    Is it obvious? It had never occurred to me.

    log and exp are certainly more mathematically straightforward in
    base e than in other bases.

    Only near x=1 for log(x) and near x=0 for exp(x).

    Can you explain what you mean by that?

    Mathematically, exp(x) (base e) is described by the Taylor series.
    In clumsy ASCII notation, it's:

    1 + x + x**2/2! + x**3/3! + x**4/4! + ...

    b**x, were b is a base other than e (often 2 or 10) is
    exp(x * log(base)), where exp() and log() are base e. In other
    words, exp and log for bases other than e are most straightforwardly
    defined on top of exp and log for base e.

    That's what I meant by "more mathematically straightforward".

    If you say there are computational reasons why exp2 and log2 are
    advantageous when using binary floating-point, I can believe that.
    I just don't understand the reasons (and to be honest, I'm not sure
    I'd understand an explanation without more effort than I'm willing
    to expend, unless somebody wants to pay me to work on this stuff).


    It's late here and I want to sleep, so very briefly:
    The best computational way to calculate a**x for constant a on
    relatively big interval of x, like [0:1] or [-0.5:0.5] is not through evaluation of polynomial of very high degree, but by splitting
    interval into sub ranges and calculating y = Yi * a**(x-Xi) where
    Yi is tabulated and may be Xi tabulated too, or may be Xi just regularly spaced. For double precision and for speed/space/precision requirements
    of C math library you will probably want many dozen of intervals, or
    low hundreds. That allows much lower degree of poly for a**(x-Xi).
    And to lower degree even further you use Chebyshev series or may be
    even series derived by Remez exchange algorithm rather than Taylor
    series. It means that even for a=e the second coefficient is not 1 and
    likely the 1st coefficient is also not 1. So, a=e has no advantage vs
    a=2. Of course, in this part of calculation a=2 also holds no
    advantages vs any other base, but it has advantages in other parts of
    of solution.
    Different but ideologically similar reasoning applies to natural
    log vs log2.

    I have found over the years that 200 points seems to be best when
    performing a numerical integration of a curve. For me, 200 points is
    the point where diminishing returns has set in. Of course, YMMV.

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Paul@nospam@needed.invalid to comp.lang.c++,comp.lang.c on Wed Aug 12 19:09:26 2026
    From Newsgroup: comp.lang.c

    On Wed, 8/12/2026 3:05 PM, Michael S wrote:
    On Wed, 12 Aug 2026 06:41:08 +0200
    Bonita Montero <Bonita.Montero@gmail.com> wrote:

    Am 11.08.2026 um 23:10 schrieb Scott Lurndal:

    Depends on clock speed. The Neoverse-N2 integer multiply
    instruction has a latency of 2 cycles and throughput of one per
    cycle. Seems fast enough.

    According to the AI it's three cycles.

    3 cycles is umulh. Normal umul/imul is 2.
    You AI probably can't distinguish between Neoverse-N2 (derived from Cortex-A710, which is ARMv9 variant of A78) and Neoverse-N1 (derived
    from Cortex-A76).


    It's how you ask the question, that matters :-)

    For example, the level of detail in your paragraph, the machine
    will suck that up like a sponge.

    *********** Question ***************

    Since I do not know the field well, I am going to give you
    a word jumble, and you can construct an answer from the terms of it.

    CPU instructions: umulh umul imul
    Neoverse-N2 Cortex-A710 ARMv9 (A78)
    Neoverse-N1 Cortex-A76

    Write a cogent summary of the cycle count performance
    for these items, as best you can.

    *********** Answer *************** boom!

    That killed the machine!!! Hahaha. Oh well, I
    hope I get my quarter back. I'll have to run
    this locally, and see if it blows that one up as well.
    The online screen is jammed and it won't scroll. It's dead Jim.

    Summary: Yes, it does matter how you ask the question.
    Another one for my book of trivia. FFS.

    OK, ran the question locally, and this is the first part of the answer.
    Took about 11 minutes locally, as I have no acceleration to speak of for it.

    **QuickrCalook table**

    | Core (micro-arch) | Instruction* | Operand size | Latency (cycles)rC> | Thruput (ops / cycle) |
    |------------------------------------------|--------------------------|--------------|--------------------|------------------------|
    | **Neoverse-N1** rCo Cortex-A76 (ARMv8.2) | imul (signed MUL) | 32-bit | 3 | 1 |
    | | | 64-bit | 4-5 | 1 |
    | | umul (unsigned MUL) | 32-bit | 3 | 1 |
    | | | 64-bit | 4-5 | 1 |
    | | umulh (unsigned UMULH |
    | | - high half) | 32-bit | 4 | 1 |
    | | | 64-bit | 5-6 | 1 |
    | **Neoverse-N2** - Cortex-A710 | imul (signed *MUL*) | 32-bit | 2 | 1 |
    | (ARMv9 /"A78" family) | | 64-bit | 3 | 1 |
    | | umul (unsigned *MUL*) | 32-bit | 2 | 1 |
    | | | 64-bit | 3 | 1 |
    | | umulh (unsigned *UMULH*) | 32-bit | 3 | 1 |
    | | | 64-bit | 4 | 1 |

    The high reasoning window was showing it wasn't entirely comfortable
    with the labeling of the input in the question. But it does that
    for other questions, so I won't treat that as any sort of evidence
    of something. At least the machine did not roll over and die,
    like the online one :-) In high-reasoning mode it can come back
    quickly if it doesn't find any puzzles for itself. If the signal is
    strong, maybe two runs and it is done with the reasoning.

    The system monitor, shows it writes the blather in the high reasoning
    window to disk. Now, I have to figure out where it is writing that.

    If it found a "hole" in the dataset while in high
    reasoning mode, it will grumble in its own special way about
    the problem. And that was not evident. Didn't grumble. So
    some sort of info is in the training set. My local model is
    from a year ago Aug 2025 or so.

    It never says "I don't know". It was claimed in some article, it
    could do that. I don't think it can. The closest we got to an admission
    of something was "I would be guessing if I answered that part".
    Which means the info was detected as being missing from the training set.
    In low-reasoning mode, it had been perfectly willing to "hallucinate"
    some details (the answer changed on each run -- nice). Which is why the
    run got repeated in the other mode, just to see what it would say.

    Paul

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c++,comp.lang.c on Wed Aug 12 23:52:28 2026
    From Newsgroup: comp.lang.c

    On Wed, 12 Aug 2026 11:28:34 +0100, bart wrote:

    It is certainly convenient to be able to write 2**32 instead of
    1<<32, where it is so easy to write 2<<32 by mistake.

    DoesnrCOt seem any more likely than writing rCL1**32rCY though, does it?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.c on Thu Aug 13 01:30:50 2026
    From Newsgroup: comp.lang.c

    On 13/08/2026 00:52, Lawrence DrCOOliveiro wrote:
    On Wed, 12 Aug 2026 11:28:34 +0100, bart wrote:

    It is certainly convenient to be able to write 2**32 instead of
    1<<32, where it is so easy to write 2<<32 by mistake.

    DoesnrCOt seem any more likely than writing rCL1**32rCY though, does it?

    Actually it is. I've done it quite a few times. The point of 1<<N is to
    end up with a value of 2**N (ie. a value with only bit N set). But if
    the language allows you to write 2**N anyway, then there's no need to
    use an error prone workaround.

    My language, which does have **, also allows you to set or reset bit N
    of an existing value directly (and works with 64 bits so no ULLs needed).

    So you can do 'A.[N] := 1' or 'A.[N] := 0'. In C it would be one of:

    A |= 1ull << N;
    A &= ~(1ull << N);

    or something. Nothing error prone or convoluted about that at all!

    It can also do 'A.[N] := x' where x is 0 or 1. The C for that is a bit
    more elaborate.

    Such microfeatures are highly useful.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c on Thu Aug 13 02:24:18 2026
    From Newsgroup: comp.lang.c

    On Thu, 13 Aug 2026 01:30:50 +0100, bart wrote:

    On 13/08/2026 00:52, Lawrence DrCOOliveiro wrote:

    On Wed, 12 Aug 2026 11:28:34 +0100, bart wrote:

    It is certainly convenient to be able to write 2**32 instead of
    1<<32, where it is so easy to write 2<<32 by mistake.

    DoesnrCOt seem any more likely than writing rCL1**32rCY though, does it?

    Actually it is. I've done it quite a few times.

    Has anybody else?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Paul@nospam@needed.invalid to comp.lang.c++,comp.lang.c on Thu Aug 13 00:12:59 2026
    From Newsgroup: comp.lang.c

    On Wed, 8/12/2026 2:37 AM, Lynn McGuire wrote:
    On 8/11/2026 11:26 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs
    all down to dynamic range. Logs and exponentials by their nature are
    liable to cover a huge range of magnitudes in either the argument
    (logarithm) or result (exponential). Integer formats in common use do
    not cater for this. Whereas with floating-point -- well, itrCOs there in
    the name, isnrCOt it?

    This is why you calculate and return a long long int.-a Or maybe even a 128 bit int.

    Lynn


    Fun with LLM-AI.

    Assumes "sudo apt install libgmp-dev" has already been done, for the components needed.

    #include <stdio.h>
    #include <gmp.h>

    // gcc -Wall -O2 -o gmp_pow_demo gmp_pow_demo.c -lgmp

    int main(void)
    {
    // mpz_ui_pow_ui only accepts unsigned long for both base and exponent.
    // If you want negative bases, you must use mpz_pow_ui(mpz_t rop, const mpz_t base, unsigned long int exp)

    struct {
    unsigned long a;
    unsigned long b;
    const char *desc;
    } tests[] = {
    {0, 0, "Zero to the zeroth power"},
    {0, 5, "Zero to a positive power"},
    {5, 0, "Positive to zero power"},
    {1, 100, "One to a high power"},
    {2, 63, "2^63 (fits in 64 bits)"},
    {2, 127, "2^127 (fits in 128 bits)"},
    {7, 20, "Small base, moderate exponent"},
    {123456789ULL, 5, "Large base, small exponent"},
    {15, 15, "15^15"},
    };

    mpz_t result;
    mpz_init(result);

    for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) {
    unsigned long a = tests[i].a;
    unsigned long b = tests[i].b;

    mpz_ui_pow_ui(result, a, b);

    printf("Test %zu: %s\n", i + 1, tests[i].desc);
    printf(" a = %lu, b = %lu\n", a, b);

    // Print the result
    gmp_printf(" result = %Zd\n", result);

    // Print the bit size of the result
    printf(" GMP bit-size = %zu bits\n\n", mpz_sizeinbase(result, 2));
    }

    mpz_clear(result);
    return 0;
    }

    $ ./gmp_pow_demo
    Test 1: Zero to the zeroth power
    a = 0, b = 0
    result = 1
    GMP bit-size = 1 bits

    Test 2: Zero to a positive power
    a = 0, b = 5
    result = 0
    GMP bit-size = 1 bits

    Test 3: Positive to zero power
    a = 5, b = 0
    result = 1
    GMP bit-size = 1 bits

    Test 4: One to a high power
    a = 1, b = 100
    result = 1
    GMP bit-size = 1 bits

    Test 5: 2^63 (fits in 64 bits)
    a = 2, b = 63
    result = 9223372036854775808
    GMP bit-size = 64 bits

    Test 6: 2^127 (fits in 128 bits)
    a = 2, b = 127
    result = 170141183460469231731687303715884105728
    GMP bit-size = 128 bits

    Test 7: Small base, moderate exponent
    a = 7, b = 20
    result = 79792266297612001
    GMP bit-size = 57 bits

    Test 8: Large base, small exponent
    a = 123456789, b = 5
    result = 28679718602997181072337614380936720482949
    GMP bit-size = 135 bits

    Test 9: 15^15
    a = 15, b = 15
    result = 437893890380859375
    GMP bit-size = 59 bits

    ************************************

    #include <stdio.h>
    #include <gmp.h>

    // gcc -Wall -O2 -o gmp_pow_demo2 gmp_pow_demo2.c -lgmp

    int main(void)
    {
    struct {
    long a; // signed base
    unsigned long b; // exponent
    const char *desc;
    } tests[] = {
    {0, 0, "Zero to the zeroth power"},
    {0, 7, "Zero to a positive power"},
    {5, 0, "Positive to zero power"},
    {-5, 0, "Negative to zero power"},
    {1, 100, "One to a high power"},
    {-1, 101, "Negative one to an odd power"},
    {-1, 100, "Negative one to an even power"},
    {-2, 63, "Negative base, odd exponent"},
    {-2, 64, "Negative base, even exponent"},
    {2, 127, "2^127 (fits in 128 bits)"},
    {-3, 20, "Negative base, moderate exponent"},
    {123456789L, 5, "Large positive base"},
    {-123456789L, 5, "Large negative base"},
    {15, 15, "15^15"},
    {-15, 15, "-15^15"},
    };

    mpz_t base, result;
    mpz_init(base);
    mpz_init(result);

    for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) {
    long a = tests[i].a;
    unsigned long b = tests[i].b;

    mpz_set_si(base, a); // load signed base into mpz_t
    mpz_pow_ui(result, base, b);

    printf("Test %zu: %s\n", i + 1, tests[i].desc);
    printf(" a = %ld, b = %lu\n", a, b);

    gmp_printf(" result = %Zd\n", result);

    printf(" GMP bit-size = %zu bits\n\n",
    mpz_sizeinbase(result, 2));
    }

    mpz_clear(base);
    mpz_clear(result);
    return 0;
    }

    $ ./gmp_pow_demo2
    Test 1: Zero to the zeroth power
    a = 0, b = 0
    result = 1
    GMP bit-size = 1 bits

    Test 2: Zero to a positive power
    a = 0, b = 7
    result = 0
    GMP bit-size = 1 bits

    Test 3: Positive to zero power
    a = 5, b = 0
    result = 1
    GMP bit-size = 1 bits

    Test 4: Negative to zero power
    a = -5, b = 0
    result = 1
    GMP bit-size = 1 bits

    Test 5: One to a high power
    a = 1, b = 100
    result = 1
    GMP bit-size = 1 bits

    Test 6: Negative one to an odd power
    a = -1, b = 101
    result = -1
    GMP bit-size = 1 bits

    Test 7: Negative one to an even power
    a = -1, b = 100
    result = 1
    GMP bit-size = 1 bits

    Test 8: Negative base, odd exponent
    a = -2, b = 63
    result = -9223372036854775808
    GMP bit-size = 64 bits

    Test 9: Negative base, even exponent
    a = -2, b = 64
    result = 18446744073709551616
    GMP bit-size = 65 bits

    Test 10: 2^127 (fits in 128 bits)
    a = 2, b = 127
    result = 170141183460469231731687303715884105728
    GMP bit-size = 128 bits

    Test 11: Negative base, moderate exponent
    a = -3, b = 20
    result = 3486784401
    GMP bit-size = 32 bits

    Test 12: Large positive base
    a = 123456789, b = 5
    result = 28679718602997181072337614380936720482949
    GMP bit-size = 135 bits

    Test 13: Large negative base
    a = -123456789, b = 5
    result = -28679718602997181072337614380936720482949
    GMP bit-size = 135 bits

    Test 14: 15^15
    a = 15, b = 15
    result = 437893890380859375
    GMP bit-size = 59 bits

    Test 15: -15^15
    a = -15, b = 15
    result = -437893890380859375
    GMP bit-size = 59 bits

    Now, this is the kind of programming task, the LLM-AI likes.
    I didn't get any predictions of doom or anything :-)

    Paul
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Wed Aug 12 21:13:48 2026
    From Newsgroup: comp.lang.c

    Lawrence DrCOOliveiro <ldo@nz.invalid> writes:
    On Thu, 13 Aug 2026 01:30:50 +0100, bart wrote:
    On 13/08/2026 00:52, Lawrence DrCOOliveiro wrote:
    On Wed, 12 Aug 2026 11:28:34 +0100, bart wrote:
    It is certainly convenient to be able to write 2**32 instead of
    1<<32, where it is so easy to write 2<<32 by mistake.

    DoesnrCOt seem any more likely than writing rCL1**32rCY though, does it?

    Actually it is. I've done it quite a few times.

    Has anybody else?

    I probably have. (I don't think I've ever made that mistake and
    not caught it reasonably quickly.)
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Thu Aug 13 08:38:42 2026
    From Newsgroup: comp.lang.c

    On 12/08/2026 23:49, Lynn McGuire wrote:
    On 8/12/2026 4:24 PM, Michael S wrote:
    On Wed, 12 Aug 2026 13:44:50 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Wed, 12 Aug 2026 03:58:16 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    And I thought it is entirely obvious that when you are actually
    implementing a floating point power function on a binary computer
    using floating point formats specified in binary, it is most
    efficient to use base 2 for the log and anti-log.-a If you had a
    floating point format that used base 10, you'd probably want to
    use base 10 for the log and anti-log.

    Is it obvious?-a It had never occurred to me.

    log and exp are certainly more mathematically straightforward in
    base e than in other bases.

    Only near x=1 for log(x) and near x=0 for exp(x).

    Can you explain what you mean by that?

    Mathematically, exp(x) (base e) is described by the Taylor series.
    In clumsy ASCII notation, it's:

    -a-a-a-a 1 + x + x**2/2! + x**3/3! + x**4/4! + ...

    b**x, were b is a base other than e (often 2 or 10) is
    exp(x * log(base)), where exp() and log() are base e.-a In other
    words, exp and log for bases other than e are most straightforwardly
    defined on top of exp and log for base e.

    That's what I meant by "more mathematically straightforward".

    If you say there are computational reasons why exp2 and log2 are
    advantageous when using binary floating-point, I can believe that.
    I just don't understand the reasons (and to be honest, I'm not sure
    I'd understand an explanation without more effort than I'm willing
    to expend, unless somebody wants to pay me to work on this stuff).


    It's late here and I want to sleep, so very briefly:
    The best computational way to calculate a**x for constant a on
    relatively big interval of x, like [0:1] or [-0.5:0.5] is not through
    evaluation of polynomial of very high degree, but by splitting
    interval into sub ranges and calculating y = Yi * a**(x-Xi) where
    Yi is tabulated and may be Xi tabulated too, or may be Xi just regularly
    spaced. For double precision and for speed/space/precision requirements
    of C math library you will probably want many dozen of intervals, or
    low hundreds. That allows much lower degree of poly for a**(x-Xi).
    And to lower degree even further you use Chebyshev series or may be
    even series derived by Remez exchange algorithm rather than Taylor
    series. It means that even for a=e the second coefficient is not 1 and
    likely the 1st coefficient is also not 1. So, a=e has no advantage vs
    a=2. Of course, in this part of calculation a=2 also holds no
    advantages vs any other base, but it has advantages in other parts of
    of solution.
    Different but ideologically similar reasoning applies to natural
    log vs log2.

    I have found over the years that 200 points seems to be best when
    performing a numerical integration of a curve.-a For me, 200 points is
    the point where diminishing returns has set in.-a Of course, YMMV.


    Your mileage may very much vary. The best number of points depends on
    many factors, such as the type of curve (how "wiggly" it is, whether it
    has additional characteristics like monoticity that you can use, etc.), whether you are using linearly separated points or free points, how your interpolation works, what characteristics you need for the generated
    results, your required precision, etc. Characteristics of the target architecture can influence the best choice of points - bigger tables may
    let you use simpler calculations, but calculations may be cheaper than
    more complicated table lookup schemes. There is no single guideline for
    the number of points in such tables that can be useful in any general sense.

    I don't quite understand the use of the table Michael is describing
    here, but it does not at all surprise me that practical implementations
    of "pow" (and no doubt many other irrational functions) combine range-splitting and tables so that the polynomial approximations are efficient.

    My own understanding here is probably on a similar level to Keith's - I
    know the theoretical maths (Taylor series and all), know the difference between the theoretical infinite precision infinite series and limited precision numerical analysis, know about error analysis, basis
    polynomials like Chebyshev, etc. But I also know there's a lot of
    detail that I would have to learn or look up, that real-world speed can
    have surprising differences from what you expect, that people have
    figured out smart tricks to get good results faster, and that you need a
    great deal of experience working on this kind of code to write it well.
    I don't have that experience or practical knowledge - I have to trust
    those that do (like Michael).


    For my own uses, I typically need things like sin functions for motor
    control and other such applications. Tables of perhaps 16 or 32 evenly
    spaced points, with cubic interpolation, are often fine to get the
    accuracy I need in a few clock cycles on a microcontroller. (I don't
    think I have ever needed a floating point "pow" on a microcontroller.)



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Johann 'Myrkraverk' Oskarsson@johann@myrkraverk.invalid to comp.lang.c++,comp.lang.c on Thu Aug 13 17:19:53 2026
    From Newsgroup: comp.lang.c

    On 11/08/2026 4:01 PM, Lynn McGuire wrote:
    Why is there not a ipow version of pow?

    ipow would return an int instead of a double.-a Or a long long int.

    Thanks,
    Lynn


    Dear Lynn,

    I can't speak for the ISO C committee, but my guess is the lack of a
    multi precision library in the standard. If I remember Tom St Denis'
    book correctly, implementing an ipow() with such a library is /trivial/
    for some version of trivial. I just don't remember if such a function
    is included in his.

    In any case, I don't think an ipow() is all that useful unless there is
    a multiprecision type to return the value. Do you disagree with that?
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++,comp.lang.c on Thu Aug 13 15:46:53 2026
    From Newsgroup: comp.lang.c

    Am 12.08.2026 um 21:40 schrieb Chris M. Thomasson:
    On 8/12/2026 7:05 AM, Bonita Montero wrote:
    Am 12.08.2026 um 15:11 schrieb Paul:

    I would not trust an LLM-AI to do an off-the-cuff analysis
    of the code for this one. Claude may have a slight edge over
    the competition, but LLM-AI really do make mistakes, and it
    isn't pretty when they do.

    If Claude sees 95% of all issues that's useful.


    Why not use your own mind, for your own work?

    Why are a lot of developers working in teams and not only on their own ?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Thu Aug 13 14:33:51 2026
    From Newsgroup: comp.lang.c

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Lawrence DrCOOliveiro <ldo@nz.invalid> writes:
    On Thu, 13 Aug 2026 01:30:50 +0100, bart wrote:
    On 13/08/2026 00:52, Lawrence DrCOOliveiro wrote:
    On Wed, 12 Aug 2026 11:28:34 +0100, bart wrote:
    It is certainly convenient to be able to write 2**32 instead of
    1<<32, where it is so easy to write 2<<32 by mistake.

    DoesnrCOt seem any more likely than writing rCL1**32rCY though, does it? >>>
    Actually it is. I've done it quite a few times.

    Has anybody else?

    I probably have. (I don't think I've ever made that mistake and
    not caught it reasonably quickly.)

    Likewise.

    To avoid those potenial errors, one might wrap the shifts in
    inline functions or macros, e.g. in C++:

    namespace bit {
    template<class T> static inline void set(T& vector, size_t bit)
    {
    vector |= (static_cast<T>(1) << bit);
    }
    };

    bit::set(word, 5);


    A similar macro can be used in C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Thu Aug 13 16:45:39 2026
    From Newsgroup: comp.lang.c

    Am 13.08.2026 um 16:33 schrieb Scott Lurndal:

    namespace bit {
    template<class T> static inline void set(T& vector, size_t bit)
    {
    vector |= (static_cast<T>(1) << bit);
    }
    };

    Do you really need such child-proof locks ?

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Thu Aug 13 14:55:56 2026
    From Newsgroup: comp.lang.c

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 13.08.2026 um 16:33 schrieb Scott Lurndal:

    namespace bit {
    template<class T> static inline void set(T& vector, size_t bit)
    {
    vector |= (static_cast<T>(1) << bit);
    }
    };

    Do you really need such child-proof locks ?

    1) it helps eliminate mistakes.
    2) it is self-documenting.

    So, the answer to your frage is clearly Ja.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Thu Aug 13 17:19:15 2026
    From Newsgroup: comp.lang.c

    On 13/08/2026 16:33, Scott Lurndal wrote:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Lawrence DrCOOliveiro <ldo@nz.invalid> writes:
    On Thu, 13 Aug 2026 01:30:50 +0100, bart wrote:
    On 13/08/2026 00:52, Lawrence DrCOOliveiro wrote:
    On Wed, 12 Aug 2026 11:28:34 +0100, bart wrote:
    It is certainly convenient to be able to write 2**32 instead of
    1<<32, where it is so easy to write 2<<32 by mistake.

    DoesnrCOt seem any more likely than writing rCL1**32rCY though, does it? >>>>
    Actually it is. I've done it quite a few times.

    Has anybody else?

    I probably have. (I don't think I've ever made that mistake and
    not caught it reasonably quickly.)

    Likewise.

    To avoid those potenial errors, one might wrap the shifts in
    inline functions or macros, e.g. in C++:

    namespace bit {
    template<class T> static inline void set(T& vector, size_t bit)
    {
    vector |= (static_cast<T>(1) << bit);
    }
    };

    bit::set(word, 5);


    A similar macro can be used in C.


    I am sure I have also made such mistakes - but like Keith, I am also
    sure I found the error quite quickly. I've seen countless macros,
    inline functions, enumerations, templates, lists of #define'd constants,
    etc., used by programmers and libraries as alternatives to just writing
    (1u << n). I don't think any of them add to the clarity of code, or
    reduce the risk of errors in any significant way - except if the
    programmer skimps on parentheses. (1u << n) may be a little odd when
    you first see it, but if you work with code that needs a lot of bit
    twiddling, you get familiar with it very quickly.

    I've had the odd occasion where an integer "a ** b" power operator would
    be convenient, and if C had one then I might use (2 ** n) rather than
    (1u << n), but it would be a very minor issue.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Thu Aug 13 16:09:22 2026
    From Newsgroup: comp.lang.c

    David Brown <david.brown@hesbynett.no> writes:
    On 13/08/2026 16:33, Scott Lurndal wrote:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Lawrence DrCOOliveiro <ldo@nz.invalid> writes:
    On Thu, 13 Aug 2026 01:30:50 +0100, bart wrote:
    On 13/08/2026 00:52, Lawrence DrCOOliveiro wrote:
    On Wed, 12 Aug 2026 11:28:34 +0100, bart wrote:
    It is certainly convenient to be able to write 2**32 instead of
    1<<32, where it is so easy to write 2<<32 by mistake.

    DoesnrCOt seem any more likely than writing rCL1**32rCY though, does it? >>>>>
    Actually it is. I've done it quite a few times.

    Has anybody else?

    I probably have. (I don't think I've ever made that mistake and
    not caught it reasonably quickly.)

    Likewise.

    To avoid those potenial errors, one might wrap the shifts in
    inline functions or macros, e.g. in C++:

    namespace bit {
    template<class T> static inline void set(T& vector, size_t bit)
    {
    vector |= (static_cast<T>(1) << bit);
    }
    };

    bit::set(word, 5);


    A similar macro can be used in C.


    I am sure I have also made such mistakes - but like Keith, I am also
    sure I found the error quite quickly.

    That's not always been the case in my experience with large
    code bases. It certainly doesn't hurt to abstract bit ops, particularly
    when there are complementary patterns for other bit manipulations:

    bit::reset(word, 5);
    data = bit::extract(word, 15, 8); /* extract bits <15:8> */
    data = bit::extracts(word, 15, 8); /* same, but sign extended */
    data = bit::insert(data, insertdata, 8, 4); /* insert four bits starting at bit 8 */
    if (bit::test(word, 7)) ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Thu Aug 13 18:10:12 2026
    From Newsgroup: comp.lang.c

    Am 13.08.2026 um 16:55 schrieb Scott Lurndal:
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 13.08.2026 um 16:33 schrieb Scott Lurndal:

    namespace bit {
    template<class T> static inline void set(T& vector, size_t bit)
    {
    vector |= (static_cast<T>(1) << bit);
    }
    };

    Do you really need such child-proof locks ?

    1) it helps eliminate mistakes.

    It makes code less readable for nearly no gain.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Thu Aug 13 16:16:54 2026
    From Newsgroup: comp.lang.c

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 13.08.2026 um 16:55 schrieb Scott Lurndal:
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 13.08.2026 um 16:33 schrieb Scott Lurndal:

    namespace bit {
    template<class T> static inline void set(T& vector, size_t bit)
    {
    vector |= (static_cast<T>(1) << bit);
    }
    };

    Do you really need such child-proof locks ?

    1) it helps eliminate mistakes.

    It makes code less readable for nearly no gain.

    That description applies to most of your C++ examples...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Thu Aug 13 16:21:03 2026
    From Newsgroup: comp.lang.c

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 13.08.2026 um 16:55 schrieb Scott Lurndal:
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 13.08.2026 um 16:33 schrieb Scott Lurndal:

    namespace bit {
    template<class T> static inline void set(T& vector, size_t bit)
    {
    vector |= (static_cast<T>(1) << bit);
    }
    };

    Do you really need such child-proof locks ?

    1) it helps eliminate mistakes.

    It makes code less readable for nearly no gain.

    $ grep "bit::" *.[ch]* */*.[ch]* */*/*.[ch]* */*/*/*.[ch] | wc -l
    38493

    It's not uncommon for programmers to forget the type suffix
    when shifting (e.g. shifting 1 by 33 bits instead of 1ul).

    Using the helpers will prevent that simple mistake.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Thu Aug 13 18:52:10 2026
    From Newsgroup: comp.lang.c

    On 13/08/2026 18:09, Scott Lurndal wrote:
    David Brown <david.brown@hesbynett.no> writes:
    On 13/08/2026 16:33, Scott Lurndal wrote:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Lawrence DrCOOliveiro <ldo@nz.invalid> writes:
    On Thu, 13 Aug 2026 01:30:50 +0100, bart wrote:
    On 13/08/2026 00:52, Lawrence DrCOOliveiro wrote:
    On Wed, 12 Aug 2026 11:28:34 +0100, bart wrote:
    It is certainly convenient to be able to write 2**32 instead of >>>>>>>> 1<<32, where it is so easy to write 2<<32 by mistake.

    DoesnrCOt seem any more likely than writing rCL1**32rCY though, does it?

    Actually it is. I've done it quite a few times.

    Has anybody else?

    I probably have. (I don't think I've ever made that mistake and
    not caught it reasonably quickly.)

    Likewise.

    To avoid those potenial errors, one might wrap the shifts in
    inline functions or macros, e.g. in C++:

    namespace bit {
    template<class T> static inline void set(T& vector, size_t bit)
    {
    vector |= (static_cast<T>(1) << bit);
    }
    };

    bit::set(word, 5);


    A similar macro can be used in C.


    I am sure I have also made such mistakes - but like Keith, I am also
    sure I found the error quite quickly.

    That's not always been the case in my experience with large
    code bases. It certainly doesn't hurt to abstract bit ops, particularly when there are complementary patterns for other bit manipulations:

    bit::reset(word, 5);
    data = bit::extract(word, 15, 8); /* extract bits <15:8> */
    data = bit::extracts(word, 15, 8); /* same, but sign extended */
    data = bit::insert(data, insertdata, 8, 4); /* insert four bits starting at bit 8 */
    if (bit::test(word, 7)) ...

    I can agree on field extraction functions / macros - these are a pain to
    do manually.

    But I dislike functions that change the value of parameters that appear
    to be passed by value - generally, I think passing by non-const
    reference is very questionable. A full C++ class where the whole thing
    is in a strong type, so that you are then doing "word.reset_bit(5);"
    would be better.

    Still, I can accept that on a large code base with lots of people,
    having a single consistent solution here is not a bad idea. In my
    world, it's typically the other way round - you have a single developer
    (or small team) and a few libraries or SDK's for your microcontroller
    drivers, RTOS, network stack, etc., and they all use a different system.
    That's the biggest pain.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From James Kuyper@jameskuyper@alumni.caltech.edu to comp.lang.c++,comp.lang.c on Thu Aug 13 12:59:51 2026
    From Newsgroup: comp.lang.c

    On 2026-08-12 16:44, Keith Thompson wrote:
    Michael S <already5chosen@yahoo.com> writes:
    On Wed, 12 Aug 2026 03:58:16 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    And I thought it is entirely obvious that when you are actually
    implementing a floating point power function on a binary computer
    using floating point formats specified in binary, it is most
    efficient to use base 2 for the log and anti-log. If you had a
    floating point format that used base 10, you'd probably want to use
    base 10 for the log and anti-log.

    Is it obvious? It had never occurred to me.

    log and exp are certainly more mathematically straightforward in
    base e than in other bases.

    Only near x=1 for log(x) and near x=0 for exp(x).

    Can you explain what you mean by that?

    Mathematically, exp(x) (base e) is described by the Taylor series.
    In clumsy ASCII notation, it's:

    1 + x + x**2/2! + x**3/3! + x**4/4! + ...

    b**x, were b is a base other than e (often 2 or 10) is
    exp(x * log(base)), where exp() and log() are base e. In other
    words, exp and log for bases other than e are most straightforwardly
    defined on top of exp and log for base e.

    That's what I meant by "more mathematically straightforward".

    If you say there are computational reasons why exp2 and log2 are
    advantageous when using binary floating-point, I can believe that.
    I just don't understand the reasons (and to be honest, I'm not sure
    I'd understand an explanation without more effort than I'm willing
    to expend, unless somebody wants to pay me to work on this stuff).

    I would expect log2(x) to be easier to calculate than other bases when
    using binary floating point, because the integer part of the result is
    already stored (with an offset) as the exponent of the number; then you
    can just calculate the fractional part from the significand. Similarly,
    exp2(x) can just extract the integer part of x, and place it with the
    correct offset in the exponent, and then calculate the significand of
    the result from the fractional part. I don't know how significant a
    savings that is, but it does seem like it should help. It might be
    sufficiently significant to justify implementing exp(x) as
    exp2(log(2)*x), and log(x) = log2(x)/log(2), where log(2) would be a precomputed constant.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Thu Aug 13 14:28:01 2026
    From Newsgroup: comp.lang.c

    On 8/13/2026 6:46 AM, Bonita Montero wrote:
    Am 12.08.2026 um 21:40 schrieb Chris M. Thomasson:
    On 8/12/2026 7:05 AM, Bonita Montero wrote:
    Am 12.08.2026 um 15:11 schrieb Paul:

    I would not trust an LLM-AI to do an off-the-cuff analysis
    of the code for this one. Claude may have a slight edge over
    the competition, but LLM-AI really do make mistakes, and it
    isn't pretty when they do.

    If Claude sees 95% of all issues that's useful.


    Why not use your own mind, for your own work?

    Why are a lot of developers working in teams and not only on their own ?

    Kind of sounds like you are allowing the AI to be you. Sigh.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Thu Aug 13 18:59:22 2026
    From Newsgroup: comp.lang.c

    On 8/13/2026 1:38 AM, David Brown wrote:
    On 12/08/2026 23:49, Lynn McGuire wrote:
    On 8/12/2026 4:24 PM, Michael S wrote:
    On Wed, 12 Aug 2026 13:44:50 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Wed, 12 Aug 2026 03:58:16 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    And I thought it is entirely obvious that when you are actually
    implementing a floating point power function on a binary computer >>>>>>> using floating point formats specified in binary, it is most
    efficient to use base 2 for the log and anti-log.-a If you had a >>>>>>> floating point format that used base 10, you'd probably want to
    use base 10 for the log and anti-log.

    Is it obvious?-a It had never occurred to me.

    log and exp are certainly more mathematically straightforward in
    base e than in other bases.

    Only near x=1 for log(x) and near x=0 for exp(x).

    Can you explain what you mean by that?

    Mathematically, exp(x) (base e) is described by the Taylor series.
    In clumsy ASCII notation, it's:

    -a-a-a-a 1 + x + x**2/2! + x**3/3! + x**4/4! + ...

    b**x, were b is a base other than e (often 2 or 10) is
    exp(x * log(base)), where exp() and log() are base e.-a In other
    words, exp and log for bases other than e are most straightforwardly
    defined on top of exp and log for base e.

    That's what I meant by "more mathematically straightforward".

    If you say there are computational reasons why exp2 and log2 are
    advantageous when using binary floating-point, I can believe that.
    I just don't understand the reasons (and to be honest, I'm not sure
    I'd understand an explanation without more effort than I'm willing
    to expend, unless somebody wants to pay me to work on this stuff).


    It's late here and I want to sleep, so very briefly:
    The best computational way to calculate a**x for constant a on
    relatively big interval of x, like [0:1] or [-0.5:0.5] is not through
    evaluation of polynomial of very high degree, but by splitting
    interval into sub ranges and calculating y = Yi * a**(x-Xi) where
    Yi is tabulated and may be Xi tabulated too, or may be Xi just regularly >>> spaced. For double precision and for speed/space/precision requirements
    of C math library you will probably want many dozen of intervals, or
    low hundreds. That allows much lower degree of poly for a**(x-Xi).
    And to lower degree even further you use Chebyshev series or may be
    even series derived by Remez exchange algorithm rather than Taylor
    series. It means that even for a=e the second coefficient is not 1 and
    likely the 1st coefficient is also not 1. So, a=e has no advantage vs
    a=2. Of course, in this part of calculation a=2 also holds no
    advantages vs any other base, but it has advantages in other parts of
    of solution.
    Different but ideologically similar reasoning applies to natural
    log vs log2.

    I have found over the years that 200 points seems to be best when
    performing a numerical integration of a curve.-a For me, 200 points is
    the point where diminishing returns has set in.-a Of course, YMMV.


    Your mileage may very much vary.-a The best number of points depends on
    many factors, such as the type of curve (how "wiggly" it is, whether it
    has additional characteristics like monoticity that you can use, etc.), whether you are using linearly separated points or free points, how your interpolation works, what characteristics you need for the generated results, your required precision, etc.-a Characteristics of the target architecture can influence the best choice of points - bigger tables may
    let you use simpler calculations, but calculations may be cheaper than
    more complicated table lookup schemes.-a There is no single guideline for the number of points in such tables that can be useful in any general
    sense.

    I don't quite understand the use of the table Michael is describing
    here, but it does not at all surprise me that practical implementations
    of "pow" (and no doubt many other irrational functions) combine range- splitting and tables so that the polynomial approximations are efficient.

    My own understanding here is probably on a similar level to Keith's - I
    know the theoretical maths (Taylor series and all), know the difference between the theoretical infinite precision infinite series and limited precision numerical analysis, know about error analysis, basis
    polynomials like Chebyshev, etc.-a But I also know there's a lot of
    detail that I would have to learn or look up, that real-world speed can
    have surprising differences from what you expect, that people have
    figured out smart tricks to get good results faster, and that you need a great deal of experience working on this kind of code to write it well.
    I don't have that experience or practical knowledge - I have to trust
    those that do (like Michael).


    For my own uses, I typically need things like sin functions for motor control and other such applications.-a Tables of perhaps 16 or 32 evenly spaced points, with cubic interpolation, are often fine to get the
    accuracy I need in a few clock cycles on a microcontroller.-a (I don't
    think I have ever needed a floating point "pow" on a microcontroller.)

    Mine is coming from a chemical process simulator where chemicals are
    moving between the four phases of matter that we support: vapor,
    hydrocarbon liquid, aqueous liquid, and solids, based on temperature and pressure. The tables are incredibly non-linear.

    This is my people and I:
    https://www.winsim.com/

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Thu Aug 13 19:07:02 2026
    From Newsgroup: comp.lang.c

    On 8/13/2026 4:19 AM, Johann 'Myrkraverk' Oskarsson wrote:
    On 11/08/2026 4:01 PM, Lynn McGuire wrote:
    Why is there not a ipow version of pow?

    ipow would return an int instead of a double.-a Or a long long int.

    Thanks,
    Lynn


    Dear Lynn,

    I can't speak for the ISO C committee, but my guess is the lack of a
    multi precision library in the standard.-a If I remember Tom St Denis'
    book correctly, implementing an ipow() with such a library is /trivial/
    for some version of trivial.-a I just don't remember if such a function
    is included in his.

    In any case, I don't think an ipow() is all that useful unless there is
    a multiprecision type to return the value.-a Do you disagree with that?

    I would rather see a standard user interface toolkit for C++ first.

    https://wxwidgets.org/ is close but I have yet to try it out.

    Thanks,
    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Thu Aug 13 18:51:03 2026
    From Newsgroup: comp.lang.c

    On 8/13/2026 4:59 PM, Lynn McGuire wrote:
    [...]
    Mine is coming from a chemical process simulator where chemicals are
    moving between the four phases of matter that we support: vapor,
    hydrocarbon liquid, aqueous liquid, and solids, based on temperature and pressure.-a The tables are incredibly non-linear.

    This is my people and I:
    -a-a https://www.winsim.com/

    Notice any fractal growth in there?

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c++,comp.lang.c on Fri Aug 14 02:50:12 2026
    From Newsgroup: comp.lang.c

    On Wed, 12 Aug 2026 18:40:37 +0200, Bonita Montero wrote:

    Nice fact: clang++ and g++ are *much* faster than MSVC with my code.
    I asked my self why is that and I had a look at the compiled code. I
    do a "b * e / b == b" check. MSVC uses a division for that. g++ and
    clang++ just check the overflow flag after doing the multiplication.

    Clever. :)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Johann 'Myrkraverk' Oskarsson@johann@myrkraverk.invalid to comp.lang.c++,comp.lang.c on Fri Aug 14 10:58:03 2026
    From Newsgroup: comp.lang.c

    On 14/08/2026 8:07 AM, Lynn McGuire wrote:
    On 8/13/2026 4:19 AM, Johann 'Myrkraverk' Oskarsson wrote:
    On 11/08/2026 4:01 PM, Lynn McGuire wrote:
    Why is there not a ipow version of pow?

    ipow would return an int instead of a double.-a Or a long long int.

    Thanks,
    Lynn


    Dear Lynn,

    I can't speak for the ISO C committee, but my guess is the lack of a
    multi precision library in the standard.-a If I remember Tom St Denis'
    book correctly, implementing an ipow() with such a library is /trivial/
    for some version of trivial.-a I just don't remember if such a function
    is included in his.

    In any case, I don't think an ipow() is all that useful unless there is
    a multiprecision type to return the value.-a Do you disagree with that?

    I would rather see a standard user interface toolkit for C++ first.

    Fair enough. I come at this discussion from comp.lang.c, and as such,
    don't care what the C++ standards committee does.


    https://wxwidgets.org/ is close but I have yet to try it out.

    I just treat IUP as an /industry standard/ interface toolkit for C.

    https://iup.sourceforge.net/

    And I believe that would require a different standards committee than
    -- what was it? WG14 -- to include in the ISO standards collection, as
    it's still targetting C89 if I'm not mistaken, and doesn't keep up with
    WG14 at all.

    Perhaps just best to standardize it with A.N.S.I. in the United States,
    if at all? I admit ignorance on how much paperwork that is, and I'd
    certainly include PUC Rio in such discussions, somehow. Even if they're
    also not in the United States.


    Best wishes, and happy interfacing with IUP!
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Johann 'Myrkraverk' Oskarsson@johann@myrkraverk.invalid to comp.lang.c++,comp.lang.c on Fri Aug 14 11:22:25 2026
    From Newsgroup: comp.lang.c

    On 12/08/2026 2:37 PM, Lynn McGuire wrote:
    On 8/11/2026 11:26 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs
    all down to dynamic range. Logs and exponentials by their nature are
    liable to cover a huge range of magnitudes in either the argument
    (logarithm) or result (exponential). Integer formats in common use do
    not cater for this. Whereas with floating-point -- well, itrCOs there in
    the name, isnrCOt it?

    This is why you calculate and return a long long int.-a Or maybe even a
    128 bit int.

    Lynn


    Is there a reason you don't use a multiprecision library, such as the
    one by the late Tom St Denis, in your code base?
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 00:58:49 2026
    From Newsgroup: comp.lang.c

    On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:
    On 8/13/2026 4:59 PM, Lynn McGuire wrote:
    [...]
    Mine is coming from a chemical process simulator where chemicals are
    moving between the four phases of matter that we support: vapor,
    hydrocarbon liquid, aqueous liquid, and solids, based on temperature
    and pressure.-a The tables are incredibly non-linear.

    This is my people and I:
    -a-a-a https://www.winsim.com/

    Notice any fractal growth in there?

    We don't do that.

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 01:00:40 2026
    From Newsgroup: comp.lang.c

    On 8/13/2026 10:22 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 12/08/2026 2:37 PM, Lynn McGuire wrote:
    On 8/11/2026 11:26 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs >>> all down to dynamic range. Logs and exponentials by their nature are
    liable to cover a huge range of magnitudes in either the argument
    (logarithm) or result (exponential). Integer formats in common use do
    not cater for this. Whereas with floating-point -- well, itrCOs there in >>> the name, isnrCOt it?

    This is why you calculate and return a long long int.-a Or maybe even a
    128 bit int.

    Lynn


    Is there a reason you don't use a multiprecision library, such as the
    one by the late Tom St Denis, in your code base?

    I am converting from Fortran 77 to C++. The last thing I want to do is introduce more new features in the code.

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 01:14:11 2026
    From Newsgroup: comp.lang.c

    On 8/13/2026 9:58 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 14/08/2026 8:07 AM, Lynn McGuire wrote:
    On 8/13/2026 4:19 AM, Johann 'Myrkraverk' Oskarsson wrote:
    On 11/08/2026 4:01 PM, Lynn McGuire wrote:
    Why is there not a ipow version of pow?

    ipow would return an int instead of a double.-a Or a long long int.

    Thanks,
    Lynn


    Dear Lynn,

    I can't speak for the ISO C committee, but my guess is the lack of a
    multi precision library in the standard.-a If I remember Tom St Denis'
    book correctly, implementing an ipow() with such a library is /trivial/
    for some version of trivial.-a I just don't remember if such a function
    is included in his.

    In any case, I don't think an ipow() is all that useful unless there is
    a multiprecision type to return the value.-a Do you disagree with that?

    I would rather see a standard user interface toolkit for C++ first.

    Fair enough.-a I come at this discussion from comp.lang.c, and as such,
    don't care what the C++ standards committee does.


    https://wxwidgets.org/ is close but I have yet to try it out.

    I just treat IUP as an /industry standard/ interface toolkit for C.

    -a https://iup.sourceforge.net/

    And I believe that would require a different standards committee than
    -- what was it? WG14 -- to include in the ISO standards collection, as
    it's still targetting C89 if I'm not mistaken, and doesn't keep up with
    WG14 at all.

    Perhaps just best to standardize it with A.N.S.I. in the United States,
    if at all?-a I admit ignorance on how much paperwork that is, and I'd certainly include PUC Rio in such discussions, somehow.-a Even if they're also not in the United States.


    Best wishes, and happy interfacing with IUP!

    Here is a couple of screenshots of our Windows User Interface using MFC
    and a dialog toolkit that I ported from our Smalltalk app a few decades ago:
    https://www.winsim.com/screenshots.html

    As you can see, we use a diagrammatic user interface very similar to
    Visio. Ours was written back in the Windows 1.0 days in the 1980s and significantly enhanced over the years. I would like to get Mac and
    Linux versions. And port to 64 bit as some of our simulation flowsheets
    are approaching 1 GB where we run out of memory at that point.

    I looked at IUP. Looks interesting.

    Thanks,
    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Johann 'Myrkraverk' Oskarsson@johann@myrkraverk.invalid to comp.lang.c++,comp.lang.c on Fri Aug 14 14:47:19 2026
    From Newsgroup: comp.lang.c

    On 14/08/2026 2:00 PM, Lynn McGuire wrote:
    On 8/13/2026 10:22 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 12/08/2026 2:37 PM, Lynn McGuire wrote:
    On 8/11/2026 11:26 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs >>>> all down to dynamic range. Logs and exponentials by their nature are
    liable to cover a huge range of magnitudes in either the argument
    (logarithm) or result (exponential). Integer formats in common use do
    not cater for this. Whereas with floating-point -- well, itrCOs there in >>>> the name, isnrCOt it?

    This is why you calculate and return a long long int.-a Or maybe even
    a 128 bit int.

    Lynn


    Is there a reason you don't use a multiprecision library, such as the
    one by the late Tom St Denis, in your code base?

    I am converting from Fortran 77 to C++.-a The last thing I want to do is introduce more new features in the code.

    Lynn


    Fair enough. If you change your mind -- and for other people interested
    in the subject -- you can look at chapter seven of Tom's book. Of
    course, you won't need to read the details of the implementation just to
    use the library, which is available somewhere on GitHub.


    Have a nice day!
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c++,comp.lang.c on Fri Aug 14 08:57:12 2026
    From Newsgroup: comp.lang.c

    On 14/08/2026 01:59, Lynn McGuire wrote:
    On 8/13/2026 1:38 AM, David Brown wrote:
    On 12/08/2026 23:49, Lynn McGuire wrote:
    [...]
    I have found over the years that 200 points seems to be best when
    performing a numerical integration of a curve.-a For me, 200 points is
    the point where diminishing returns has set in.-a Of course, YMMV.


    Your mileage may very much vary.-a The best number of points depends on
    many factors, such as the type of curve (how "wiggly" it is, whether
    it has additional characteristics like monoticity that you can use,
    etc.), whether you are using linearly separated points or free points,
    how your interpolation works, what characteristics you need for the
    generated results, your required precision, etc.-a Characteristics of
    the target architecture can influence the best choice of points -
    bigger tables may let you use simpler calculations, but calculations
    may be cheaper than more complicated table lookup schemes.-a There is
    no single guideline for the number of points in such tables that can
    be useful in any general sense.

    [...]

    Mine is coming from a chemical process simulator where chemicals are
    moving between the four phases of matter that we support: vapor,
    hydrocarbon liquid, aqueous liquid, and solids, based on temperature and pressure.-a The tables are incredibly non-linear.


    Sure, for particularly "wiggly" curves, or paths with discontinuities,
    you need a lot more information to describe them - that means more
    points, or more complex interpolation between them. (I am using "interpolation" in a general sense here, including any kind of
    polynomial approximation - not specifically simple linear
    interpolation.) I have no doubt that you need more points than I need -
    there is no universal rule of thumb for table size that suits a range of applications.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 13:54:54 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 1:47 AM, Johann 'Myrkraverk' Oskarsson wrote:
    On 14/08/2026 2:00 PM, Lynn McGuire wrote:
    On 8/13/2026 10:22 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 12/08/2026 2:37 PM, Lynn McGuire wrote:
    On 8/11/2026 11:26 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs >>>>> all down to dynamic range. Logs and exponentials by their nature are >>>>> liable to cover a huge range of magnitudes in either the argument
    (logarithm) or result (exponential). Integer formats in common use do >>>>> not cater for this. Whereas with floating-point -- well, itrCOs there in >>>>> the name, isnrCOt it?

    This is why you calculate and return a long long int.-a Or maybe even >>>> a 128 bit int.

    Lynn


    Is there a reason you don't use a multiprecision library, such as the
    one by the late Tom St Denis, in your code base?

    I am converting from Fortran 77 to C++.-a The last thing I want to do
    is introduce more new features in the code.

    Lynn


    Fair enough.-a If you change your mind -- and for other people interested
    in the subject -- you can look at chapter seven of Tom's book.-a Of
    course, you won't need to read the details of the implementation just to
    use the library, which is available somewhere on GitHub.


    Have a nice day!

    BTW, in Smalltalk you can return any type of object from a method. But
    if the caller got a weird object back, it was a place of confusion and
    often a crash as the expected object type was not the actual object
    type. So, all objects had to have a common set of methods (read, write, print, add, etc) to keep weird crashes from happening. I ended up
    putting all methods at an object and the base object too. Our base
    object had hundreds of methods to handle weird cases.

    I way prefer strongly typed languages now. Stops a lot of crazy at
    runtime, also known as crashes.

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 12:03:07 2026
    From Newsgroup: comp.lang.c

    On 8/13/2026 11:47 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 14/08/2026 2:00 PM, Lynn McGuire wrote:
    On 8/13/2026 10:22 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 12/08/2026 2:37 PM, Lynn McGuire wrote:
    On 8/11/2026 11:26 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs >>>>> all down to dynamic range. Logs and exponentials by their nature are >>>>> liable to cover a huge range of magnitudes in either the argument
    (logarithm) or result (exponential). Integer formats in common use do >>>>> not cater for this. Whereas with floating-point -- well, itrCOs there in >>>>> the name, isnrCOt it?

    This is why you calculate and return a long long int.-a Or maybe even >>>> a 128 bit int.

    Lynn


    Is there a reason you don't use a multiprecision library, such as the
    one by the late Tom St Denis, in your code base?

    I am converting from Fortran 77 to C++.-a The last thing I want to do
    is introduce more new features in the code.

    Lynn


    Fair enough.-a If you change your mind -- and for other people interested
    in the subject -- you can look at chapter seven of Tom's book.-a Of
    course, you won't need to read the details of the implementation just to
    use the library, which is available somewhere on GitHub.


    Have a nice day!

    The have a nice day, and the -- are tell tale signs of an AI writing
    your responses?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 12:08:10 2026
    From Newsgroup: comp.lang.c

    On 8/13/2026 10:58 PM, Lynn McGuire wrote:
    On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:
    On 8/13/2026 4:59 PM, Lynn McGuire wrote:
    [...]
    Mine is coming from a chemical process simulator where chemicals are
    moving between the four phases of matter that we support: vapor,
    hydrocarbon liquid, aqueous liquid, and solids, based on temperature
    and pressure.-a The tables are incredibly non-linear.

    This is my people and I:
    -a-a-a https://www.winsim.com/

    Notice any fractal growth in there?

    We don't do that.
    Let me clarify... Do you make renders of a simulation? If so, do some of
    them look fractal?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 12:46:22 2026
    From Newsgroup: comp.lang.c

    On 8/13/2026 11:57 PM, David Brown wrote:
    On 14/08/2026 01:59, Lynn McGuire wrote:
    On 8/13/2026 1:38 AM, David Brown wrote:
    On 12/08/2026 23:49, Lynn McGuire wrote:
    [...]
    I have found over the years that 200 points seems to be best when
    performing a numerical integration of a curve.-a For me, 200 points
    is the point where diminishing returns has set in.-a Of course, YMMV.


    Your mileage may very much vary.-a The best number of points depends
    on many factors, such as the type of curve (how "wiggly" it is,
    whether it has additional characteristics like monoticity that you
    can use, etc.), whether you are using linearly separated points or
    free points, how your interpolation works, what characteristics you
    need for the generated results, your required precision, etc.
    Characteristics of the target architecture can influence the best
    choice of points - bigger tables may let you use simpler
    calculations, but calculations may be cheaper than more complicated
    table lookup schemes.-a There is no single guideline for the number of
    points in such tables that can be useful in any general sense.

    [...]

    Mine is coming from a chemical process simulator where chemicals are
    moving between the four phases of matter that we support: vapor,
    hydrocarbon liquid, aqueous liquid, and solids, based on temperature
    and pressure.-a The tables are incredibly non-linear.


    Sure, for particularly "wiggly" curves, or paths with discontinuities,
    you need a lot more information to describe them - that means more
    points, or more complex interpolation between them.-a (I am using "interpolation" in a general sense here, including any kind of
    polynomial approximation - not specifically simple linear
    interpolation.)-a I have no doubt that you need more points than I need - there is no universal rule of thumb for table size that suits a range of applications.


    Here is a fairly interesting interpolation... Fwiw, here is my driver
    code. I learned about this algo on a BASIC group. too funny! I ported it
    over to my system. It generates some frames for an animation:

    #pragma once


    #include "ct_multi_thread_field_final.hpp"
    #include "ct_cairo.hpp"
    #include "ct_complex.hpp"
    #include "ct_geometry.hpp"
    #include "ct_glm.hpp"

    #include <iostream>
    #include <vector>
    #include <cstdlib>
    #include <cstdio>
    #include <string>


    namespace ct {

    namespace swimmer {


    struct settings
    {
    float radius = 1;
    float t = 0;
    int n_points = 3000;
    float lw = 1;
    float sin_mul0 = 450;
    float sin_mul1 = 930;
    };

    void
    draw(
    ct::plot::cairo::plot_2d& plot,
    settings const& cfg
    ) {
    glm::vec2 prev(0.0f, 0.0f);

    for (int i = 0; i < cfg.n_points; ++i)
    {
    float a = (float)i / (cfg.n_points - 1);

    float at = 2 * a * CT_PI - 8 * cfg.t;
    float b = glm::sin(cfg.sin_mul0 * a) * (0.7f + glm::sin(cfg.sin_mul1 * a));

    float e = 2 * a * glm::exp(-a * 8);
    float l = 1.5f * (0.7f - a) * (1 - b * b / 8) + cfg.t;
    float w = e * b - glm::sin(at) / 12 + 0.75f;

    glm::vec2 p(w * glm::cos(l), w * glm::sin(l));
    p *= cfg.radius;

    if (i > 0)
    {
    int col = (int)(128 + 127 * glm::cos(4 * b - a * 6));
    unsigned char red = (unsigned char)glm::clamp(col,
    0, 255);
    unsigned char blue = (unsigned char)glm::clamp(255
    - col, 0, 255);

    ct::plot::cairo::pixel color = CT_RGB(red, 255, blue);
    plot.line(prev, p, color, cfg.lw);
    }

    prev = p;
    }
    }


    void
    draw_pinwheel(
    ct::plot::cairo::plot_2d& plot,
    float t,
    unsigned long n = 10
    ) {
    float normal_base = 1.f / (n - 1);

    for (unsigned long i = 0; i < n; ++i)
    {
    float normal = normal_base * i;

    float r = normal;
    float local_t = normal * n * 10 + t; // outer t
    offsets the whole formation

    draw(plot, { .radius = r, .t = local_t, .lw = 2 });
    }
    }


    void
    manifest_anime(
    ct::plot::cairo::plot_2d& scene,
    unsigned long fps,
    unsigned long duration
    ) {
    unsigned long frames = fps * duration;

    float normal_base = 1.f / frames;

    for (unsigned long i = 0; i < frames; ++i)
    {
    float normal = normal_base * i;
    float t = CT_PI2 * normal;

    scene.clear(CT_RGBF(0, 0, 0));

    draw_pinwheel(scene, t, 16);

    {
    std::string filename =
    "./ct_swimmer/frames/ct_frame_" + std::to_string(i) + ".png";

    std::cout << "filename = " << filename << "\n";
    std::cout << "normal = " << normal << "\n";
    std::cout << "t = " << t << std::endl;

    scene.save(filename.c_str());
    }
    }
    }

    void
    manifest(
    ct::plot::cairo::plot_2d& scene
    ) {
    std::cout << "ct::swimmer()\n";
    std::cout << "__________________________________\n" <<
    std::endl;

    {
    manifest_anime(scene, 24, 5);
    }

    {
    // draw_pinwheel(scene, 0.0f);
    // draw_pinwheel(scene, 0.5f);
    // draw_pinwheel(scene, 0.75f);
    // draw_pinwheel(scene, 1.f);
    // draw_pinwheel(scene, 2.f);
    //draw_pinwheel(scene, 3.f);


    }
    }
    }

    } // ct::swimmer



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Johann 'Myrkraverk' Oskarsson@johann@myrkraverk.invalid to comp.lang.c++,comp.lang.c on Sat Aug 15 03:51:07 2026
    From Newsgroup: comp.lang.c

    On 15/08/2026 3:03 AM, Chris M. Thomasson wrote:
    On 8/13/2026 11:47 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 14/08/2026 2:00 PM, Lynn McGuire wrote:
    On 8/13/2026 10:22 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 12/08/2026 2:37 PM, Lynn McGuire wrote:
    On 8/11/2026 11:26 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs >>>>>> all down to dynamic range. Logs and exponentials by their nature are >>>>>> liable to cover a huge range of magnitudes in either the argument
    (logarithm) or result (exponential). Integer formats in common use do >>>>>> not cater for this. Whereas with floating-point -- well, itrCOs
    there in
    the name, isnrCOt it?

    This is why you calculate and return a long long int.-a Or maybe
    even a 128 bit int.

    Lynn


    Is there a reason you don't use a multiprecision library, such as the
    one by the late Tom St Denis, in your code base?

    I am converting from Fortran 77 to C++.-a The last thing I want to do
    is introduce more new features in the code.

    Lynn


    Fair enough.-a If you change your mind -- and for other people interested
    in the subject -- you can look at chapter seven of Tom's book.-a Of
    course, you won't need to read the details of the implementation just to
    use the library, which is available somewhere on GitHub.


    Have a nice day!

    The have a nice day, and the -- are tell tale signs of an AI writing
    your responses?

    Is the expression /tell tale/ a sign of you insisting I use A.I. when
    you know I don't? Do you get off of writing tall tales? Do you post
    in alt.sex.erotica.moderated? Are you the moderator?
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 12:52:31 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 12:51 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 15/08/2026 3:03 AM, Chris M. Thomasson wrote:
    On 8/13/2026 11:47 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 14/08/2026 2:00 PM, Lynn McGuire wrote:
    On 8/13/2026 10:22 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 12/08/2026 2:37 PM, Lynn McGuire wrote:
    On 8/11/2026 11:26 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: itrCOs
    all down to dynamic range. Logs and exponentials by their nature are >>>>>>> liable to cover a huge range of magnitudes in either the argument >>>>>>> (logarithm) or result (exponential). Integer formats in common
    use do
    not cater for this. Whereas with floating-point -- well, itrCOs >>>>>>> there in
    the name, isnrCOt it?

    This is why you calculate and return a long long int.-a Or maybe
    even a 128 bit int.

    Lynn


    Is there a reason you don't use a multiprecision library, such as the >>>>> one by the late Tom St Denis, in your code base?

    I am converting from Fortran 77 to C++.-a The last thing I want to do >>>> is introduce more new features in the code.

    Lynn


    Fair enough.-a If you change your mind -- and for other people interested >>> in the subject -- you can look at chapter seven of Tom's book.-a Of
    course, you won't need to read the details of the implementation just to >>> use the library, which is available somewhere on GitHub.


    Have a nice day!

    The have a nice day, and the -- are tell tale signs of an AI writing
    your responses?

    Is the expression /tell tale/ a sign of you insisting I use A.I. when
    you know I don't?-a Do you get off of writing tall tales?-a Do you post
    in alt.sex.erotica.moderated?-a Are you the moderator?


    Are you using AI to help write your responses? There are some flags.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Johann 'Myrkraverk' Oskarsson@johann@myrkraverk.invalid to comp.lang.c++,comp.lang.c on Sat Aug 15 04:01:14 2026
    From Newsgroup: comp.lang.c

    On 15/08/2026 3:52 AM, Chris M. Thomasson wrote:
    On 8/14/2026 12:51 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 15/08/2026 3:03 AM, Chris M. Thomasson wrote:
    On 8/13/2026 11:47 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 14/08/2026 2:00 PM, Lynn McGuire wrote:
    On 8/13/2026 10:22 PM, Johann 'Myrkraverk' Oskarsson wrote:
    On 12/08/2026 2:37 PM, Lynn McGuire wrote:
    On 8/11/2026 11:26 PM, Lawrence DrCOOliveiro wrote:
    On Tue, 11 Aug 2026 03:01:07 -0500, Lynn McGuire wrote:

    Why is there not a ipow version of pow?

    Perhaps for the same reason there arenrCOt integer log functions: >>>>>>>> itrCOs
    all down to dynamic range. Logs and exponentials by their nature >>>>>>>> are
    liable to cover a huge range of magnitudes in either the argument >>>>>>>> (logarithm) or result (exponential). Integer formats in common >>>>>>>> use do
    not cater for this. Whereas with floating-point -- well, itrCOs >>>>>>>> there in
    the name, isnrCOt it?

    This is why you calculate and return a long long int.-a Or maybe >>>>>>> even a 128 bit int.

    Lynn


    Is there a reason you don't use a multiprecision library, such as the >>>>>> one by the late Tom St Denis, in your code base?

    I am converting from Fortran 77 to C++.-a The last thing I want to
    do is introduce more new features in the code.

    Lynn


    Fair enough.-a If you change your mind -- and for other people
    interested
    in the subject -- you can look at chapter seven of Tom's book.-a Of
    course, you won't need to read the details of the implementation
    just to
    use the library, which is available somewhere on GitHub.


    Have a nice day!

    The have a nice day, and the -- are tell tale signs of an AI writing
    your responses?

    Is the expression /tell tale/ a sign of you insisting I use A.I. when
    you know I don't?-a Do you get off of writing tall tales?-a Do you post
    in alt.sex.erotica.moderated?-a Are you the moderator?


    Are you using AI to help write your responses? There are some flags.

    You're completely free to capture the flag on your own. You'll just
    have to write the game in C, because I'm coming at this from comp.lang.
    c. And not comp.lang.c++.

    I still type my replies by hand, but you're unable to do so, so you must dictate to Siri, which sends the request to Copilot, which hopefully
    uses the most expensive Usenet service available for your posts. I
    mean, why stop at paying both the fruit vendor for Siri, and Microsoft
    for Copilot, and not get the world's best and greatest Usenet provider?


    Happy posting on Usenet with Siri and Copilot!
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 13:29:13 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 1:27 PM, Chris M. Thomasson wrote:
    On 8/14/2026 1:01 PM, Johann 'Myrkraverk' Oskarsson wrote:
    [...]
    You're completely free to capture the flag on your own.-a You'll just
    have to write the game in C, because I'm coming at this from comp.lang.
    c.-a And not comp.lang.c++.

    I still type my replies by hand, but you're unable to do so, so you must
    dictate to Siri, which sends the request to Copilot, which hopefully
    uses the most expensive Usenet service available for your posts.-a I
    mean, why stop at paying both the fruit vendor for Siri, and Microsoft
    for Copilot, and not get the world's best and greatest Usenet provider?


    Happy posting on Usenet with Siri and Copilot!

    Huh. So, you are an "ass" all by yourself?

    The -- and the final "have a happy ..." aspects reek of AI all over...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 13:27:14 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 1:01 PM, Johann 'Myrkraverk' Oskarsson wrote:
    [...]
    You're completely free to capture the flag on your own.-a You'll just
    have to write the game in C, because I'm coming at this from comp.lang.
    c.-a And not comp.lang.c++.

    I still type my replies by hand, but you're unable to do so, so you must dictate to Siri, which sends the request to Copilot, which hopefully
    uses the most expensive Usenet service available for your posts.-a I
    mean, why stop at paying both the fruit vendor for Siri, and Microsoft
    for Copilot, and not get the world's best and greatest Usenet provider?


    Happy posting on Usenet with Siri and Copilot!

    Huh. So, you are an "ass" all by yourself?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 15:48:55 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 2:08 PM, Chris M. Thomasson wrote:
    On 8/13/2026 10:58 PM, Lynn McGuire wrote:
    On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:
    On 8/13/2026 4:59 PM, Lynn McGuire wrote:
    [...]
    Mine is coming from a chemical process simulator where chemicals are
    moving between the four phases of matter that we support: vapor,
    hydrocarbon liquid, aqueous liquid, and solids, based on temperature
    and pressure.-a The tables are incredibly non-linear.

    This is my people and I:
    -a-a-a https://www.winsim.com/

    Notice any fractal growth in there?

    We don't do that.
    Let me clarify... Do you make renders of a simulation? If so, do some of them look fractal?

    In short, no. We have a diagrammatic user interface that allows our
    users to build a diagram of a chemical process flow diagram such as a refinery, a natural gas plan, a pipeline with compressor stations, or a chemical plant.
    https://www.winsim.com/screenshots.html

    And we have a calculation engine that takes a textual version of that
    diagram and solves it thermodynamically. If, it can be solved as not
    all chemical processes can be solved due to constraints or violation of
    the laws of thermodynamics.

    Thanks,
    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Johann 'Myrkraverk' Oskarsson@johann@myrkraverk.invalid to comp.lang.c++,comp.lang.c on Sat Aug 15 04:49:05 2026
    From Newsgroup: comp.lang.c

    On 15/08/2026 4:29 AM, Chris M. Thomasson wrote:
    On 8/14/2026 1:27 PM, Chris M. Thomasson wrote:
    On 8/14/2026 1:01 PM, Johann 'Myrkraverk' Oskarsson wrote:
    [...]
    You're completely free to capture the flag on your own.-a You'll just
    have to write the game in C, because I'm coming at this from comp.lang.
    c.-a And not comp.lang.c++.

    I still type my replies by hand, but you're unable to do so, so you must >>> dictate to Siri, which sends the request to Copilot, which hopefully
    uses the most expensive Usenet service available for your posts.-a I
    mean, why stop at paying both the fruit vendor for Siri, and Microsoft
    for Copilot, and not get the world's best and greatest Usenet provider?


    Happy posting on Usenet with Siri and Copilot!

    Huh. So, you are an "ass" all by yourself?

    The -- and the final "have a happy ..." aspects reek of AI all over...

    Ah, yes. You're still having problems with the distinction between
    fantasy and reality. I believe I've told you this before, and you
    didn't listen then, so I can only surmise you cannot handle the truth.

    I /write well/. I can write micro-fiction for my own amusement all day
    long. And since I have no interest in amusing you, you fucking asshole,
    I guess this is the last I'll ever say on this subject. I don't need to
    use L.L.M. The L.L.Ms. were trained on the best of us. I'm one.


    Deal with it, you fucking cuck!
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 13:51:43 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 1:48 PM, Lynn McGuire wrote:
    On 8/14/2026 2:08 PM, Chris M. Thomasson wrote:
    On 8/13/2026 10:58 PM, Lynn McGuire wrote:
    On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:
    On 8/13/2026 4:59 PM, Lynn McGuire wrote:
    [...]
    Mine is coming from a chemical process simulator where chemicals
    are moving between the four phases of matter that we support:
    vapor, hydrocarbon liquid, aqueous liquid, and solids, based on
    temperature and pressure.-a The tables are incredibly non-linear.

    This is my people and I:
    -a-a-a https://www.winsim.com/

    Notice any fractal growth in there?

    We don't do that.
    Let me clarify... Do you make renders of a simulation? If so, do some
    of them look fractal?

    In short, no.-a We have a diagrammatic user interface that allows our
    users to build a diagram of a chemical process flow diagram such as a refinery, a natural gas plan, a pipeline with compressor stations, or a chemical plant.
    -a-a https://www.winsim.com/screenshots.html

    And we have a calculation engine that takes a textual version of that diagram and solves it thermodynamically.-a If, it can be solved as not
    all chemical processes can be solved due to constraints or violation of
    the laws of thermodynamics.
    Ahhhh! So, you are not making any animations of the processes. Okay. But
    you have the data to do so...

    Fwiw, I bet you already have the data to make one of my 2d examples here:

    https://youtu.be/YS-tyDJVy4M
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 16:40:26 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 3:51 PM, Chris M. Thomasson wrote:
    On 8/14/2026 1:48 PM, Lynn McGuire wrote:
    On 8/14/2026 2:08 PM, Chris M. Thomasson wrote:
    On 8/13/2026 10:58 PM, Lynn McGuire wrote:
    On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:
    On 8/13/2026 4:59 PM, Lynn McGuire wrote:
    [...]
    Mine is coming from a chemical process simulator where chemicals
    are moving between the four phases of matter that we support:
    vapor, hydrocarbon liquid, aqueous liquid, and solids, based on
    temperature and pressure.-a The tables are incredibly non-linear.

    This is my people and I:
    -a-a-a https://www.winsim.com/

    Notice any fractal growth in there?

    We don't do that.
    Let me clarify... Do you make renders of a simulation? If so, do some
    of them look fractal?

    In short, no.-a We have a diagrammatic user interface that allows our
    users to build a diagram of a chemical process flow diagram such as a
    refinery, a natural gas plan, a pipeline with compressor stations, or
    a chemical plant.
    -a-a-a https://www.winsim.com/screenshots.html

    And we have a calculation engine that takes a textual version of that
    diagram and solves it thermodynamically.-a If, it can be solved as not
    all chemical processes can be solved due to constraints or violation
    of the laws of thermodynamics.
    Ahhhh! So, you are not making any animations of the processes. Okay. But
    you have the data to do so...

    Fwiw, I bet you already have the data to make one of my 2d examples here:

    https://youtu.be/YS-tyDJVy4M

    Actually, I do make an animation of the process simulation diagram
    (PSD). If the users run a dynamic (time sensitive) version of the
    simulation, the user can roll through their displayed results on the
    various sheets of the PSD using their time breaks.

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 19:24:28 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 2:40 PM, Lynn McGuire wrote:
    On 8/14/2026 3:51 PM, Chris M. Thomasson wrote:
    On 8/14/2026 1:48 PM, Lynn McGuire wrote:
    On 8/14/2026 2:08 PM, Chris M. Thomasson wrote:
    On 8/13/2026 10:58 PM, Lynn McGuire wrote:
    On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:
    On 8/13/2026 4:59 PM, Lynn McGuire wrote:
    [...]
    Mine is coming from a chemical process simulator where chemicals >>>>>>> are moving between the four phases of matter that we support:
    vapor, hydrocarbon liquid, aqueous liquid, and solids, based on >>>>>>> temperature and pressure.-a The tables are incredibly non-linear. >>>>>>>
    This is my people and I:
    -a-a-a https://www.winsim.com/

    Notice any fractal growth in there?

    We don't do that.
    Let me clarify... Do you make renders of a simulation? If so, do
    some of them look fractal?

    In short, no.-a We have a diagrammatic user interface that allows our
    users to build a diagram of a chemical process flow diagram such as a
    refinery, a natural gas plan, a pipeline with compressor stations, or
    a chemical plant.
    -a-a-a https://www.winsim.com/screenshots.html

    And we have a calculation engine that takes a textual version of that
    diagram and solves it thermodynamically.-a If, it can be solved as not
    all chemical processes can be solved due to constraints or violation
    of the laws of thermodynamics.
    Ahhhh! So, you are not making any animations of the processes. Okay.
    But you have the data to do so...

    Fwiw, I bet you already have the data to make one of my 2d examples here:

    https://youtu.be/YS-tyDJVy4M

    Actually, I do make an animation of the process simulation diagram
    (PSD).

    Can you give me a link to some screenshots so I can get on the same
    page? Thanks. Are you almost done with your Fortran port?


    If the users run a dynamic (time sensitive) version of the
    simulation, the user can roll through their displayed results on the
    various sheets of the PSD using their time breaks.

    Cool. Fwiw, check this shit out:

    https://youtu.be/poXeq5V0dso

    A simulation for the field of one of my circle intersection fractals.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 20:32:52 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 1:49 PM, Johann 'Myrkraverk' Oskarsson wrote:
    [...]

    Deal with it, you fucking cuck!

    Ahhh. Again. I am right.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lynn McGuire@lynnmcguire5@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 22:51:02 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 9:24 PM, Chris M. Thomasson wrote:
    On 8/14/2026 2:40 PM, Lynn McGuire wrote:
    On 8/14/2026 3:51 PM, Chris M. Thomasson wrote:
    On 8/14/2026 1:48 PM, Lynn McGuire wrote:
    On 8/14/2026 2:08 PM, Chris M. Thomasson wrote:
    On 8/13/2026 10:58 PM, Lynn McGuire wrote:
    On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:
    On 8/13/2026 4:59 PM, Lynn McGuire wrote:
    [...]
    Mine is coming from a chemical process simulator where chemicals >>>>>>>> are moving between the four phases of matter that we support: >>>>>>>> vapor, hydrocarbon liquid, aqueous liquid, and solids, based on >>>>>>>> temperature and pressure.-a The tables are incredibly non-linear. >>>>>>>>
    This is my people and I:
    -a-a-a https://www.winsim.com/

    Notice any fractal growth in there?

    We don't do that.
    Let me clarify... Do you make renders of a simulation? If so, do
    some of them look fractal?

    In short, no.-a We have a diagrammatic user interface that allows our >>>> users to build a diagram of a chemical process flow diagram such as
    a refinery, a natural gas plan, a pipeline with compressor stations,
    or a chemical plant.
    -a-a-a https://www.winsim.com/screenshots.html

    And we have a calculation engine that takes a textual version of
    that diagram and solves it thermodynamically.-a If, it can be solved
    as not all chemical processes can be solved due to constraints or
    violation of the laws of thermodynamics.
    Ahhhh! So, you are not making any animations of the processes. Okay.
    But you have the data to do so...

    Fwiw, I bet you already have the data to make one of my 2d examples
    here:

    https://youtu.be/YS-tyDJVy4M

    Actually, I do make an animation of the process simulation diagram (PSD).

    Can you give me a link to some screenshots so I can get on the same
    page? Thanks. Are you almost done with your Fortran port?
    ...

    https://www.winsim.com/screenshots.html

    I am about 1/3rd of the way done with my 800,000 lines of F77 code to
    C++ code. My custom version of F2C is doing about 60 to 70% of the
    work. I am equating the task as equivalent to translating about ten
    long engineering books from German to French. Lots of idioms and basic incompatibilities that have to be ironed out.

    I was shooting for the end of 2026 but that ship has sailed. Maybe
    middle of 2027. Then I have to port to x64 but the port should be easy
    (he says with the ship sitting in ten feet of mud in the harbor).

    Lynn

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Fri Aug 14 22:33:01 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 8:51 PM, Lynn McGuire wrote:
    On 8/14/2026 9:24 PM, Chris M. Thomasson wrote:
    On 8/14/2026 2:40 PM, Lynn McGuire wrote:
    On 8/14/2026 3:51 PM, Chris M. Thomasson wrote:
    On 8/14/2026 1:48 PM, Lynn McGuire wrote:
    On 8/14/2026 2:08 PM, Chris M. Thomasson wrote:
    On 8/13/2026 10:58 PM, Lynn McGuire wrote:
    On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:
    On 8/13/2026 4:59 PM, Lynn McGuire wrote:
    [...]
    Mine is coming from a chemical process simulator where
    chemicals are moving between the four phases of matter that we >>>>>>>>> support: vapor, hydrocarbon liquid, aqueous liquid, and solids, >>>>>>>>> based on temperature and pressure.-a The tables are incredibly >>>>>>>>> non-linear.

    This is my people and I:
    -a-a-a https://www.winsim.com/

    Notice any fractal growth in there?

    We don't do that.
    Let me clarify... Do you make renders of a simulation? If so, do
    some of them look fractal?

    In short, no.-a We have a diagrammatic user interface that allows
    our users to build a diagram of a chemical process flow diagram
    such as a refinery, a natural gas plan, a pipeline with compressor
    stations, or a chemical plant.
    -a-a-a https://www.winsim.com/screenshots.html

    And we have a calculation engine that takes a textual version of
    that diagram and solves it thermodynamically.-a If, it can be solved >>>>> as not all chemical processes can be solved due to constraints or
    violation of the laws of thermodynamics.
    Ahhhh! So, you are not making any animations of the processes. Okay.
    But you have the data to do so...

    Fwiw, I bet you already have the data to make one of my 2d examples
    here:

    https://youtu.be/YS-tyDJVy4M

    Actually, I do make an animation of the process simulation diagram
    (PSD).

    Can you give me a link to some screenshots so I can get on the same
    page? Thanks. Are you almost done with your Fortran port?
    ...

    https://www.winsim.com/screenshots.html

    I am about 1/3rd of the way done with my 800,000 lines of F77 code to C+
    + code.-a My custom version of F2C is doing about 60 to 70% of the work.
    I am equating the task as equivalent to translating about ten long engineering books from German to French.-a Lots of idioms and basic incompatibilities that have to be ironed out.

    I was shooting for the end of 2026 but that ship has sailed.-a Maybe
    middle of 2027.-a Then I have to port to x64 but the port should be easy
    (he says with the ship sitting in ten feet of mud in the harbor).

    Lynn


    Love the flow sheet. Now from there, can you create a vector field?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Ross Finlayson@ross.a.finlayson@gmail.com to comp.lang.c++,comp.lang.c on Sat Aug 15 10:40:50 2026
    From Newsgroup: comp.lang.c

    On 08/14/2026 08:51 PM, Lynn McGuire wrote:
    On 8/14/2026 9:24 PM, Chris M. Thomasson wrote:
    On 8/14/2026 2:40 PM, Lynn McGuire wrote:
    On 8/14/2026 3:51 PM, Chris M. Thomasson wrote:
    On 8/14/2026 1:48 PM, Lynn McGuire wrote:
    On 8/14/2026 2:08 PM, Chris M. Thomasson wrote:
    On 8/13/2026 10:58 PM, Lynn McGuire wrote:
    On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:
    On 8/13/2026 4:59 PM, Lynn McGuire wrote:
    [...]
    Mine is coming from a chemical process simulator where
    chemicals are moving between the four phases of matter that we >>>>>>>>> support: vapor, hydrocarbon liquid, aqueous liquid, and solids, >>>>>>>>> based on temperature and pressure. The tables are incredibly >>>>>>>>> non-linear.

    This is my people and I:
    https://www.winsim.com/

    Notice any fractal growth in there?

    We don't do that.
    Let me clarify... Do you make renders of a simulation? If so, do
    some of them look fractal?

    In short, no. We have a diagrammatic user interface that allows
    our users to build a diagram of a chemical process flow diagram
    such as a refinery, a natural gas plan, a pipeline with compressor
    stations, or a chemical plant.
    https://www.winsim.com/screenshots.html

    And we have a calculation engine that takes a textual version of
    that diagram and solves it thermodynamically. If, it can be solved
    as not all chemical processes can be solved due to constraints or
    violation of the laws of thermodynamics.
    Ahhhh! So, you are not making any animations of the processes. Okay.
    But you have the data to do so...

    Fwiw, I bet you already have the data to make one of my 2d examples
    here:

    https://youtu.be/YS-tyDJVy4M

    Actually, I do make an animation of the process simulation diagram
    (PSD).

    Can you give me a link to some screenshots so I can get on the same
    page? Thanks. Are you almost done with your Fortran port?
    ...

    https://www.winsim.com/screenshots.html

    I am about 1/3rd of the way done with my 800,000 lines of F77 code to
    C++ code. My custom version of F2C is doing about 60 to 70% of the
    work. I am equating the task as equivalent to translating about ten
    long engineering books from German to French. Lots of idioms and basic incompatibilities that have to be ironed out.

    I was shooting for the end of 2026 but that ship has sailed. Maybe
    middle of 2027. Then I have to port to x64 but the port should be easy
    (he says with the ship sitting in ten feet of mud in the harbor).

    Lynn


    Translating the idioms right makes for "naturals" alignment and storage,
    and so on. Then the numerical methods one imagines are
    involved in solving linearities for invariants and process control,
    then that's involved itself, and the relevance of the compatibility
    of the numerical methods, for their mathematical guarantees, for
    their physical estimates, about how many traincars and truckloads
    of feeder stock under what conditions and augury make diapers or
    galoshes or legos or condoms or pipe or contact lenses or lacquer
    or petrochemicals or drugs or otherwise usually enough more refined
    materials from more raw materials.

    Here it's like "measure-twice cut-once" the old "build a fence
    a mile, could you move it a foot?"

    If the great difference for FORTRAN and C is the account of
    the column-major or row-major and that of arrays and loops,
    then besides a simplest sort of transpose, or organization
    and alignment and storage, then is for the model of computation
    the entry-points and the state & scope, the modules, point being here
    it's perceived as a quite impressive and thoroughgoing sort of
    account of quite very much the value the algorithms and numerical
    methods express as models of control theory.

    The Bessemer furnace, ....

    https://en.wikipedia.org/wiki/Bessemer_process

    Then, there was mentioned "violations of the thermo second law",
    or rather, "accommodations to effects of resonance theory",
    these sorts acconts of "effects", which are basically anything
    outside otherwise the theory, or "exceptions", yes one imagines
    that those make for the accounts of state & scope the quite
    complicated, which for example "exception specification" provides
    in higher-level languages with exception specification as a critical
    component of safety in the modules of software, quite invokes the
    deliberations of "why" instead of merely "because".


    The, "term-rewriting", or a bit more holistically the
    "term-graph-rewriting", is definitely a thing in software since that "generative programming" is a term from the 1960's, and "program
    translation" is is quite usual, then for "models of computation"
    and "modules of computation".


    Long story short such an endeavor is perceived to be a store of
    great _value_, and such porting effort is quite a study of both
    the numerical methods, which as usually approximations need
    their error-bounds modeled, like Runge-Kutta for example after
    Gregory & Coates as Newton's, or about Leontief and so on,
    numerical methods and linear systems and linear solvers,
    then with regards to standard and empirical units, which are
    not necessarily the same and where regimes of effect are
    according to their own units, good luck with that, it sounds
    like something vital to the real-world economy.




    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Sat Aug 15 11:41:09 2026
    From Newsgroup: comp.lang.c

    On 8/15/2026 10:40 AM, Ross Finlayson wrote:
    [...]
    Long story short such an endeavor is perceived to be a store of
    great _value_, and such porting effort is quite a study of both
    the numerical methods, which as usually approximations need
    their error-bounds modeled, like Runge-Kutta for example after
    Gregory & Coates as Newton's, or about Leontief and so on,
    numerical methods and linear systems and linear solvers,
    then with regards to standard and empirical units, which are
    not necessarily the same and where regimes of effect are
    according to their own units, good luck with that, it sounds
    like something vital to the real-world economy.

    Long story short... I am not using RK for the intermediate vector field integration points, but its still pretty good. Example:

    https://youtu.be/Doeci7xBYh0


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Sat Aug 15 13:00:22 2026
    From Newsgroup: comp.lang.c

    Lynn McGuire <lynnmcguire5@gmail.com> writes:

    I have found over the years that 200 points seems to be best when
    performing a numerical integration of a curve. For me, 200 points is
    the point where diminishing returns has set in. Of course, YMMV.

    Surely that depends on which integration method is being used.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Sat Aug 15 23:17:16 2026
    From Newsgroup: comp.lang.c

    On Sat, 15 Aug 2026 13:00:22 -0700
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

    Lynn McGuire <lynnmcguire5@gmail.com> writes:

    I have found over the years that 200 points seems to be best when performing a numerical integration of a curve. For me, 200 points
    is the point where diminishing returns has set in. Of course,
    YMMV.

    Surely that depends on which integration method is being used.

    That is smaller of my troubles with this post of Lynn.
    The bigger trouble is that my post, to which he "answered" did not talk
    at all about integration.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Sun Aug 16 07:33:42 2026
    From Newsgroup: comp.lang.c

    bart <bc@freeuk.com> writes:

    [a C version of someone's ipow() function]

    long long int ipow(long long a, int n) {
    long long int res;

    res = 1;
    if (n < 0) {
    res = 0;

    } else if (n == 0) {
    res = 1;

    } else if (n == 1) {
    res = a;

    } else if ((n & 1) == 0) { // n is even
    res = ipow(a*a, n/2);

    } else { // n is odd
    res = ipow(a*a, (n-1)/2)*a;
    }

    return res;
    }

    Two observations:

    One: one of the recursive calls is not properly tail recursive so
    the recursion isn't always optimized out.

    Two: it gets wrong answers for in some cases with negative
    exponents.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.c on Sun Aug 16 17:12:02 2026
    From Newsgroup: comp.lang.c

    On 2026-08-16 16:33, Tim Rentsch wrote:
    bart <bc@freeuk.com> writes:

    [a C version of someone's ipow() function]

    long long int ipow(long long a, int n) {
    long long int res;

    res = 1;
    if (n < 0) {
    res = 0;

    } else if (n == 0) {
    res = 1;

    } else if (n == 1) {
    res = a;

    } else if ((n & 1) == 0) { // n is even
    res = ipow(a*a, n/2);

    } else { // n is odd
    res = ipow(a*a, (n-1)/2)*a;
    }

    return res;
    }

    Two observations:

    One: one of the recursive calls is not properly tail recursive so
    the recursion isn't always optimized out.

    You could as well write that also from the beginning in an iterative
    form (and not rely on optimizations of recursive functions - in case
    that this is a problem for the compilers in mind).

    (But personally I find the recursive form clearer than an iterative.)


    Two: it gets wrong answers for in some cases with negative
    exponents.

    Ah, a typical non-answer! - Given that negative exponents are (here)
    generally handled to provide a result of 0 - and assuming that is
    accepted as result, since other libraries may provide an exception
    or error here - what are these "some cases with negative exponents"
    you have in mind; if you are so deign to give an answer this time.

    Thanks.

    Janis

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Sun Aug 16 17:51:25 2026
    From Newsgroup: comp.lang.c

    On 16/08/2026 17:12, Janis Papanagnou wrote:
    On 2026-08-16 16:33, Tim Rentsch wrote:
    bart <bc@freeuk.com> writes:

    [a C version of someone's ipow() function]

    -a long long int ipow(long long a, int n) {
    -a-a-a-a long long int res;

    -a-a-a-a res = 1;
    -a-a-a-a if (n < 0) {
    -a-a-a-a-a-a-a-a res = 0;

    -a-a-a-a } else if (n == 0) {
    -a-a-a-a-a-a-a-a res = 1;

    -a-a-a-a } else if (n == 1) {
    -a-a-a-a-a-a-a-a res = a;

    -a-a-a-a } else if ((n & 1) == 0) {-a-a-a-a-a-a-a // n is even
    -a-a-a-a-a-a-a-a res = ipow(a*a, n/2);

    -a-a-a-a } else {-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a // n is odd
    -a-a-a-a-a-a-a-a res = ipow(a*a, (n-1)/2)*a;
    -a-a-a-a }

    -a-a-a-a return res;
    -a }

    Two observations:

    One: one of the recursive calls is not properly tail recursive so
    the recursion isn't always optimized out.

    You could as well write that also from the beginning in an iterative
    form (and not rely on optimizations of recursive functions - in case
    that this is a problem for the compilers in mind).

    (But personally I find the recursive form clearer than an iterative.)


    Two: it gets wrong answers for in some cases with negative
    exponents.

    Ah, a typical non-answer! - Given that negative exponents are (here) generally handled to provide a result of 0 - and assuming that is
    accepted as result, since other libraries may provide an exception
    or error here - what are these "some cases with negative exponents"
    you have in mind; if you are so deign to give an answer this time.


    1 ** n will be 1, even for negative n. And -1 ** n will be 1 for even negative n, -1 for odd negative n. (Tim does not seem to give useful
    answers much these days - he does drive-bys every few months and leaves comments that are not much better than "I'm smarter than you". He used
    to take more active part in threads, so you'd at least get a more
    helpful response within a few days, but unfortunately that is now uncommon.)

    It might not be unreasonable to have fast special cases for n = 1 or -1
    at the start.

    gcc and clang have no problem generating iterative code from this
    function, but MSVC did not manage it (or possibly I don't know the right
    MSVC flags - "/O2" was not sufficient in a quick godbolt test).

    I don't know how Bart's own compiler copes with such recursive functions
    - I am curious if it can generate an iterative loop here.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.c on Sun Aug 16 18:35:24 2026
    From Newsgroup: comp.lang.c

    On 2026-08-16 17:51, David Brown wrote:
    On 16/08/2026 17:12, Janis Papanagnou wrote:
    On 2026-08-16 16:33, Tim Rentsch wrote:
    bart <bc@freeuk.com> writes:

    [a C version of someone's ipow() function]

    -a long long int ipow(long long a, int n) {
    -a-a-a-a long long int res;

    -a-a-a-a res = 1;
    -a-a-a-a if (n < 0) {
    -a-a-a-a-a-a-a-a res = 0;

    -a-a-a-a } else if (n == 0) {
    -a-a-a-a-a-a-a-a res = 1;

    -a-a-a-a } else if (n == 1) {
    -a-a-a-a-a-a-a-a res = a;

    -a-a-a-a } else if ((n & 1) == 0) {-a-a-a-a-a-a-a // n is even
    -a-a-a-a-a-a-a-a res = ipow(a*a, n/2);

    -a-a-a-a } else {-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a // n is odd
    -a-a-a-a-a-a-a-a res = ipow(a*a, (n-1)/2)*a;
    -a-a-a-a }

    -a-a-a-a return res;
    -a }

    Two observations:

    One: one of the recursive calls is not properly tail recursive so
    the recursion isn't always optimized out.

    You could as well write that also from the beginning in an iterative
    form (and not rely on optimizations of recursive functions - in case
    that this is a problem for the compilers in mind).

    (But personally I find the recursive form clearer than an iterative.)


    Two: it gets wrong answers for in some cases with negative
    exponents.

    Ah, a typical non-answer! - Given that negative exponents are (here)
    generally handled to provide a result of 0 - and assuming that is
    accepted as result, since other libraries may provide an exception
    or error here - what are these "some cases with negative exponents"
    you have in mind; if you are so deign to give an answer this time.


    1 ** n will be 1, even for negative n.

    For the integer-exponentiation case as topic of the thread - where
    negative exponents make little sense - and specifically for bart's
    presented code "negative n" is ruled out, or rather it leads always
    to 0.

    I'd assume you (and Tim) just missed that? (Or what did I miss?)

    And -1 ** n will be 1 for even negative n,

    I'd say it would be at best undefined. In the posted code it would
    be 0, which is not unsound if we'd read (now coming from the general
    case) x**-y as 1/(x**y), which goes (in the 'real' domain) towards 0.

    As said, other languages or libraries just bail out for the negative
    exponent case ipow: int x int -> int (or rather int x nat -> nat ).

    -1 for odd negative n.-a (Tim does not seem to give useful
    answers much these days - he does drive-bys every few months and leaves comments that are not much better than "I'm smarter than you".-a He used
    to take more active part in threads, so you'd at least get a more
    helpful response within a few days, but unfortunately that is now
    uncommon.)

    Yes, that's obvious. (But it's cumbersome and not worthwhile to talk
    about - crude or else - personalities.)

    [...]

    I don't know how Bart's own compiler copes with such recursive functions
    - I am curious if it can generate an iterative loop here.

    Well, Bart's tools are of little interest - to me at least. But his
    posted algorithm is sound, I'd say. And an iterative replacement not
    hard to derive. Maybe something like (replacing long long for brevity)

    long ipow (long a, int n)
    {
    if (n < 0) return 0;

    long res = 1;
    long base = a; // note: we could also operate on 'a'

    while (n > 0) {
    if (n & 1)
    res *= base;

    base *= base;
    n /= 2;
    }

    return res;
    }

    But as said, for _clarity_ of code I prefer the functional form.

    Janis

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.c on Sun Aug 16 18:41:20 2026
    From Newsgroup: comp.lang.c

    On 2026-08-16 18:35, Janis Papanagnou wrote:

    As said, other languages or libraries just bail out for the negative
    exponent case-a ipow: int x int -> int-a (or rather-a int x nat -> nat ).

    Oops, typo... ipow: int x int -> int (or rather int x nat -> int ).

    Janis

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Sun Aug 16 21:30:53 2026
    From Newsgroup: comp.lang.c

    On 16/08/2026 18:35, Janis Papanagnou wrote:
    On 2026-08-16 17:51, David Brown wrote:
    On 16/08/2026 17:12, Janis Papanagnou wrote:
    On 2026-08-16 16:33, Tim Rentsch wrote:
    bart <bc@freeuk.com> writes:

    [a C version of someone's ipow() function]

    -a long long int ipow(long long a, int n) {
    -a-a-a-a long long int res;

    -a-a-a-a res = 1;
    -a-a-a-a if (n < 0) {
    -a-a-a-a-a-a-a-a res = 0;

    -a-a-a-a } else if (n == 0) {
    -a-a-a-a-a-a-a-a res = 1;

    -a-a-a-a } else if (n == 1) {
    -a-a-a-a-a-a-a-a res = a;

    -a-a-a-a } else if ((n & 1) == 0) {-a-a-a-a-a-a-a // n is even
    -a-a-a-a-a-a-a-a res = ipow(a*a, n/2);

    -a-a-a-a } else {-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a // n is odd
    -a-a-a-a-a-a-a-a res = ipow(a*a, (n-1)/2)*a;
    -a-a-a-a }

    -a-a-a-a return res;
    -a }

    Two observations:

    One: one of the recursive calls is not properly tail recursive so
    the recursion isn't always optimized out.

    You could as well write that also from the beginning in an iterative
    form (and not rely on optimizations of recursive functions - in case
    that this is a problem for the compilers in mind).

    (But personally I find the recursive form clearer than an iterative.)


    Two: it gets wrong answers for in some cases with negative
    exponents.

    Ah, a typical non-answer! - Given that negative exponents are (here)
    generally handled to provide a result of 0 - and assuming that is
    accepted as result, since other libraries may provide an exception
    or error here - what are these "some cases with negative exponents"
    you have in mind; if you are so deign to give an answer this time.


    1 ** n will be 1, even for negative n.

    For the integer-exponentiation case as topic of the thread - where
    negative exponents make little sense - and specifically for bart's
    presented code "negative n" is ruled out, or rather it leads always
    to 0.

    I'd assume you (and Tim) just missed that? (Or what did I miss?)


    I can't speak for Tim, though I would assume he is entirely aware that
    using negative n usually makes little sense for an "ipow" function - and
    I suspect that since the function takes a signed int for "n" and does
    not specify that it is non-negative, he felt the return value should be correct for negative "n" even if it is never used.

    For my own part, I am entirely aware that negative "n" makes little
    sense in practice. In the example code I gave for "ipow" in a different thread, I specifically used an unsigned type for "n".


    And -1 ** n will be 1 for even negative n,

    I'd say it would be at best undefined.

    Why? (-1) ** n is well-defined mathematically for all integer "n". It
    turns up regularly in sum notation when you want to distinguish between
    odd and even terms. "a ** -n" is just "1 / (a ** n)", so the results
    here have a clear mathematical meaning.

    But I can agree that it would rarely be useful to have a negative "n"
    for an integer power function. And if you want to specify an "ipow"
    function that is for non-negative "n" only, fair enough.

    (The really problematic cases are of course "ipow(0, n)" when n <= 0.
    These are best left as UB in the specifications, but an implementation
    might find it easiest just to return 0. When there is no right answer,
    any answer is reasonable.)

    In the posted code it would
    be 0, which is not unsound if we'd read (now coming from the general
    case) x**-y as 1/(x**y), which goes (in the 'real' domain) towards 0.


    Yes, rounding "a ** n" to 0 for negative "n" is perfectly reasonable, in
    all cases except "a = 1" and "a = -1".

    As said, other languages or libraries just bail out for the negative
    exponent case-a ipow: int x int -> int-a (or rather-a int x nat -> nat ).


    They can choose to do that. That's fine. But it should either be part
    of the function declaration (such as using an unsigned type for "n"), or
    given in the documentation.

    [...]

    I don't know how Bart's own compiler copes with such recursive
    functions - I am curious if it can generate an iterative loop here.

    Well, Bart's tools are of little interest - to me at least.

    I have no use for his tools either, but I am interested in how well they
    work with code he writes himself in this style.

    But his
    posted algorithm is sound, I'd say.

    With the addition of documentation about negative "n" being UB, or a fix
    for those cases, I agree that his algorithm is fine.

    And an iterative replacement not
    hard to derive. Maybe something like (replacing long long for brevity)

    long ipow (long a, int n)
    {
    -a-a-a if (n < 0) return 0;

    -a-a-a long res = 1;
    -a-a-a long base = a;-a // note: we could also operate on 'a'

    -a-a-a while (n > 0) {
    -a-a-a-a-a-a-a if (n & 1)
    -a-a-a-a-a-a-a-a-a-a-a res *= base;

    -a-a-a-a-a-a-a base *= base;
    -a-a-a-a-a-a-a n /= 2;
    -a-a-a }

    -a-a-a return res;
    }

    But as said, for _clarity_ of code I prefer the functional form.


    Me too.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++,comp.lang.c on Sun Aug 16 14:58:10 2026
    From Newsgroup: comp.lang.c

    On 8/14/2026 2:40 PM, Lynn McGuire wrote:
    [...]

    Fwiw, check this out, another one of my field renders:

    https://youtu.be/ygmp_XvdaqQ
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.c on Sun Aug 16 23:41:27 2026
    From Newsgroup: comp.lang.c

    On 16/08/2026 20:30, David Brown wrote:
    On 16/08/2026 18:35, Janis Papanagnou wrote:

    Well, Bart's tools are of little interest - to me at least.

    I have no use for his tools either, but I am interested in how well they work with code he writes himself in this style.

    They do nothing clever. With the version below, one test I did had these results (with the ipow function in a different file from the test code):

    gcc -O3 0.56 s
    clang -O3 0.78 s
    bcc 1.12 s
    lccwin32 1.19 s
    DMC 1.4 s (32-bit code)
    tcc 1.43 s



    But his
    posted algorithm is sound, I'd say.

    With the addition of documentation about negative "n" being UB, or a fix
    for those cases, I agree that his algorithm is fine.


    It's not mine, I just found it somewhere.


    -----------------------------------

    long long int ipow(long long a, unsigned int n) {
    if (n == 0) {
    return 1;

    } else if (n == 1) {
    return a;

    } else if ((n & 1) == 0) { // n is even
    return ipow(a*a, n/2);

    } else { // n is odd
    return ipow(a*a, (n-1)/2)*a;
    }
    }


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c++,comp.lang.c on Sun Aug 16 22:49:05 2026
    From Newsgroup: comp.lang.c

    On Fri, 14 Aug 2026 13:54:54 -0500, Lynn McGuire wrote:

    BTW, in Smalltalk you can return any type of object from a method.
    But if the caller got a weird object back, it was a place of
    confusion and often a crash as the expected object type was not the
    actual object type.

    I way prefer strongly typed languages now.

    Smalltalk IS rCLstrongly typedrCY. I think you mean rCLstatically typedrCY, as opposed to rCLdynamically typedrCY.

    So, all objects had to have a common set of methods (read, write,
    print, add, etc) to keep weird crashes from happening. I ended up
    putting all methods at an object and the base object too. Our base
    object had hundreds of methods to handle weird cases.

    ShouldnrCOt you have cleaned up the code to deal properly with the
    different object types?

    This is why newer dynamic languages, like Python, are introducing type annotations. These are handled by a separate processor (|a la rCLlintrCY
    for C code) which tries to flag up inconsistencies between expected
    and actual types, as indicated by a static analysis of the
    annotations. This would let you fix up those inconsistencies even
    before the code gets a chance to run.

    Of course such a scheme is not perfect, and can never be, without
    giving up dynamic typing altogether. And then yourCOd probably end up
    with Java or something.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.c on Mon Aug 17 03:32:07 2026
    From Newsgroup: comp.lang.c

    On 2026-08-16 21:30, David Brown wrote:
    On 16/08/2026 18:35, Janis Papanagnou wrote:
    [...]

    But his posted algorithm is sound, I'd say.

    With the addition of documentation about negative "n" being UB, or a fix
    for those cases, I agree that his algorithm is fine.

    Actually, programming lots of Algol68 lately, I used a few patterns
    from that language also in my iterative code. (I had mentioned the
    unnecessary use of the "base" variable, and the 'int' parameter was
    also a remains.) In "C" (and forgetting Algol 68 for a moment) I'd
    probably have written it more "C-ish"; i.e. using an 'unsigned int'
    for the parameter 'n' to more clearly define its range as positive,
    operating directly on 'a', and condensing the 'while' loop by 'for'.

    long int ipow (long int a, unsigned int n)
    {
    long int res = 1;
    for ( ; n > 0; n /= 2) {
    if (n & 1)
    res *= a;
    a *= a;
    }
    return res;
    }

    The "n < 0" case can then also be omitted completely and adds to its
    brevity.

    I'd suppose the 'unsigned' wouldn't prevent a "C" user to nonetheless
    feed the 'ipow' function with '-1', but that's C's inherent problem.

    Janis

    --- Synchronet 3.22a-Linux NewsLink 1.2