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.
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.ÿ 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?
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.
On 8/11/2026 11:26 PM, Lawrence D?Oliveiro 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 aren?t integer log functions: it?s
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, it?s there in
the name, isn?t it?
This is why you calculate and return a long long int.ÿ Or maybe even a
128 bit int.
Lynn
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?
On 12/08/2026 2:37 PM, Lynn McGuire wrote:
On 8/11/2026 11:26 PM, Lawrence D?Oliveiro 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 aren?t integer log functions: it?s
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, it?s there in
the name, isn?t it?
This is why you calculate and return a long long int.ÿ 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?
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.ÿ 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?
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!
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 D?Oliveiro 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 aren?t integer log functions: it?s
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, it?s there in >>>> the name, isn?t it?
This is why you calculate and return a long long int.ÿ 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
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.ÿ For me, 200 points is
the point where diminishing returns has set in.ÿ 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.
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.
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 D?Oliveiro 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 aren?t integer log functions: it?s >>>>> 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, it?s there in >>>>> the name, isn?t it?
This is why you calculate and return a long long int.ÿ 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
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!
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 D?Oliveiro 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 aren?t integer log functions: it?s >>>>> 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, it?s there in >>>>> the name, isn?t it?
This is why you calculate and return a long long int.ÿ 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
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!
On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:Let me clarify... Do you make renders of a simulation? If so, do some of
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.
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.ÿ For me, 200 points
is the point where diminishing returns has set in.ÿ 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.
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.
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.
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 D?Oliveiro 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 aren?t integer log functions: it?s >>>>>> 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, it?s
there in
the name, isn?t it?
This is why you calculate and return a long long int.ÿ 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
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!
The have a nice day, and the -- are tell tale signs of an AI writing
your responses?
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 D?Oliveiro 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 aren?t integer log functions: it?s >>>>>>> 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, it?s
there in
the name, isn?t it?
This is why you calculate and return a long long int.ÿ 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
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!
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?
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 D?Oliveiro 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 aren?t integer log functions: >>>>>>>> it?s
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, it?s >>>>>>>> there in
the name, isn?t it?
This is why you calculate and return a long long int.ÿ 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
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!
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?
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!
On 8/14/2026 1:01 PM, Johann 'Myrkraverk' Oskarsson wrote:
[...]
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!
Huh. So, you are an "ass" all by yourself?
On 8/13/2026 10:58 PM, Lynn McGuire wrote:
On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:Let me clarify... Do you make renders of a simulation? If so, do some of them look fractal?
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.
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.ÿ 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!
Huh. So, you are an "ass" all by yourself?
The -- and the final "have a happy ..." aspects reek of AI all over...
On 8/14/2026 2:08 PM, Chris M. Thomasson wrote:Ahhhh! So, you are not making any animations of the processes. Okay. But
On 8/13/2026 10:58 PM, Lynn McGuire wrote:
On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:Let me clarify... Do you make renders of a simulation? If so, do some
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.
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.
On 8/14/2026 1:48 PM, Lynn McGuire wrote:
On 8/14/2026 2:08 PM, Chris M. Thomasson wrote:Ahhhh! So, you are not making any animations of the processes. Okay. But
On 8/13/2026 10:58 PM, Lynn McGuire wrote:
On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:Let me clarify... Do you make renders of a simulation? If so, do some
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.
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.
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
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:Ahhhh! So, you are not making any animations of the processes. Okay.
On 8/13/2026 10:58 PM, Lynn McGuire wrote:
On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:Let me clarify... Do you make renders of a simulation? If so, do
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.
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.
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.
Deal with it, you fucking cuck!
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:Ahhhh! So, you are not making any animations of the processes. Okay.
On 8/13/2026 10:58 PM, Lynn McGuire wrote:
On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:Let me clarify... Do you make renders of a simulation? If so, do
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.
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.
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?
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:Ahhhh! So, you are not making any animations of the processes. Okay.
On 8/13/2026 10:58 PM, Lynn McGuire wrote:
On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:Let me clarify... Do you make renders of a simulation? If so, do
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.
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.
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
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:Ahhhh! So, you are not making any animations of the processes. Okay.
On 8/13/2026 10:58 PM, Lynn McGuire wrote:
On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:Let me clarify... Do you make renders of a simulation? If so, do
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.
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.
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
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.
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 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.
[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;
}
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.
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.
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]
ÿ 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.
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.)
[...]
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.
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 ).
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]
ÿ 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.
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 ).
[...]
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.
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.
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.
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.
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.
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.
It makes code less readable for nearly no gain.
I would rather see a standard user interface toolkit for C++ first.
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.
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.
On 17/08/2026 03:32, Janis Papanagnou wrote:
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.
Some people see that as an advantage - being able to write "unsigned very_big = -1;".ÿ I dislike it personally, but styles and preferences
vary, and it has portability advantages over, say, 0xffff'ffff.
On 17/08/2026 03:32, Janis Papanagnou wrote:[...]
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.
Some people see that as an advantage - being able to write "unsigned
very_big = -1;". I dislike it personally, but styles and preferences
vary, and it has portability advantages over, say, 0xffff'ffff.
David Brown <david.brown@hesbynett.no> writes:
On 17/08/2026 03:32, Janis Papanagnou wrote:[...]
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.
Some people see that as an advantage - being able to write "unsigned
very_big = -1;". I dislike it personally, but styles and preferences
vary, and it has portability advantages over, say, 0xffff'ffff.
Sure, but the advantage isn't applicable in this case. If ipow's
second parameter is unsigned, ipow(n, -1) is going to overflow,
not compute 1/n.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
David Brown <david.brown@hesbynett.no> writes:
On 17/08/2026 03:32, Janis Papanagnou wrote:[...]
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.
Some people see that as an advantage - being able to write "unsigned
very_big = -1;". I dislike it personally, but styles and preferences
vary, and it has portability advantages over, say, 0xffff'ffff.
Sure, but the advantage isn't applicable in this case.
If ipow's
second parameter is unsigned, ipow(n, -1) is going to overflow,
not compute 1/n.
Well, it's not going to overflow if n is -1 or 1.
On Thu, 13 Aug 2026 18:10:12 +0200, Bonita Montero wrote:
It makes code less readable for nearly no gain.
Both C and C++ programmers seem to have this philosophy of ?if in
doubt, add more parentheses?.
On Thu, 13 Aug 2026 19:07:02 -0500, Lynn McGuire wrote:
I would rather see a standard user interface toolkit for C++ first.
With only one exception I?m aware of, there is no standard UI toolkit
for *any* cross-platform language, for obvious reasons.
Though interestingly, there has been a proposal knocking around among
the C++ standardization committee for some years for a standard 2D
graphics API. Like the one that has been incorporated in JavaScript,
this one is also based on Cairo <https://www.cairographics.org/>, but
unlike that, it seems to be even less complete, omitting even text functionality.
On 17/08/2026 03:32, Janis Papanagnou wrote:
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.
That was my thought, yes.
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.
Some people see that as an advantage - being able to write "unsigned >very_big = -1;". I dislike it personally, but styles and preferences
vary, and it has portability advantages over, say, 0xffff'ffff.
David Brown <david.brown@hesbynett.no> writes:
On 17/08/2026 03:32, Janis Papanagnou wrote:
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.
That was my thought, yes.
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.
Some people see that as an advantage - being able to write "unsigned
very_big = -1;". I dislike it personally, but styles and preferences
vary, and it has portability advantages over, say, 0xffff'ffff.
I also dislike that use of -1. I prefer using ~0ul to get all-ones.
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.
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).
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.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-16 16:33, Tim Rentsch wrote:
[...]
Ah, a typical non-answer! - [...]
What is typical is your usual fractious misdirection style. You
might consider trying to lower your talking-to-thinking ratio.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-16 16:33, Tim Rentsch wrote:
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).
I find it easier simply to write a properly tail-recursive
implementation from the outset,
where I know compilers will have
no difficulty optimizing out the tail calls.
On 2026-08-17 19:22, Tim Rentsch wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-16 16:33, Tim Rentsch wrote:
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).
I find it easier simply to write a properly tail-recursive
implementation from the outset,
Fair enough.
where I know compilers will have
no difficulty optimizing out the tail calls.
Not all might know whether and what sorts of constructs their
compilers are able to optimize. To me it's not obvious that
simple (but non-tail-) recursions are typically not optimized.
YMMV, but sensible optimizations is IMO task of the compilers;
it shouldn't be necessary that you have to formulate programs
using a specific programming pattern; ideally - but "C" as had
been discussed not long ago exposes anyway a peculiar view of
optimizations. (I'm sure YMMV.)
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:Ahhhh! So, you are not making any animations of the processes. Okay. >>>>> But you have the data to do so...
On 8/13/2026 10:58 PM, Lynn McGuire wrote:
On 8/13/2026 8:51 PM, Chris M. Thomasson wrote:Let me clarify... Do you make renders of a simulation? If so, do >>>>>>> some of them look fractal?
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.
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.
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 ofSorry, I lost you in the first part of your reply. If you are saying
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.
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 ?strongly typed?. I think you mean ?statically typed?, as opposed to ?dynamically typed?.
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 ?strongly typed?. I think you mean ?statically typed?, as opposed to ?dynamically typed?.
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.
Shouldn?t you have cleaned up the code to deal properly with the
different object types?
Michael S <already5chosen@yahoo.com> writes:
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.
Yeah. Not too surprising really, considering the general level
of the discussion -- an overly long thread for a problem that
should take at most 15 minutes to solve just by writing an
ipow() function.
David Brown <david.brown@hesbynett.no> writes:[...]
Some people see that as an advantage - being able to write "unsigned >>very_big = -1;". I dislike it personally, but styles and preferences >>vary, and it has portability advantages over, say, 0xffff'ffff.
I also dislike that use of -1. I prefer using ~0ul to get all-ones.
On 8/16/2026 5:49 PM, Lawrence D?Oliveiro wrote:
...
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 ?strongly typed?. I think you mean ?statically typed?,
as opposed to ?dynamically typed?.
Our particular variant of Smalltalk, Whitewater Actor, was not
strongly typed. You could have a var calling any gibberish that you
called a method and it was not linked until runtime with the
subsequent crash.
https://en.wikipedia.org/wiki/Actor_(programming_language)
The only thing that I miss about Smalltalk is the casual
heterogeneous collections. Those were immensely useful. I built
several classes in C++ to model them with a common ancestor class
but never got the same effect.
On Mon, 17 Aug 2026 14:56:59 -0500, Lynn McGuire wrote:
On 8/16/2026 5:49 PM, Lawrence D?Oliveiro wrote:
...
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 ?strongly typed?. I think you mean ?statically typed?,
as opposed to ?dynamically typed?.
Our particular variant of Smalltalk, Whitewater Actor, was not
strongly typed. You could have a var calling any gibberish that you
called a method and it was not linked until runtime with the
subsequent crash.
https://en.wikipedia.org/wiki/Actor_(programming_language)
Ah, I see. Looks like they were relying on a generic machine-code
linker to tie things together, instead of having their own
language-specific linking layer to avoid accidents like this.
The only thing that I miss about Smalltalk is the casual
heterogeneous collections. Those were immensely useful. I built
several classes in C++ to model them with a common ancestor class
but never got the same effect.
Is that just a list or table where the entries can have any type?
That?s a standard thing in any dynamic language, surely.
On 8/17/2026 6:53 PM, Lawrence D?Oliveiro wrote:
On Mon, 17 Aug 2026 14:56:59 -0500, Lynn McGuire wrote:
The only thing that I miss about Smalltalk is the casual
heterogeneous collections. Those were immensely useful. I built
several classes in C++ to model them with a common ancestor class
but never got the same effect.
Is that just a list or table where the entries can have any type?
That?s a standard thing in any dynamic language, surely.
Yup. Smalltalk had Dictionary, Bag, and Map. All heterogeneous.
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
longint ipow (longint base, longint exp)
{
ÿÿÿÿlongint result = 1;
ÿÿÿÿstd::string str;
ÿÿÿÿif (exp == 0 || base == 0) {
ÿÿÿÿÿÿÿ return result;
ÿÿÿÿ}
ÿÿÿÿif (exp < 0) {
ÿÿÿÿÿÿÿ scrwri ("");
ÿÿÿÿÿÿÿ str = "ERROR: exp is negative, " + asString (exp) + " (ipow)";
ÿÿÿÿÿÿÿ scrwri (str);
ÿÿÿÿÿÿÿ scrwri ("");
ÿÿÿÿÿÿÿ quit ();
ÿÿÿÿÿÿÿ return 0;
ÿÿÿÿ}
ÿÿÿÿfor (;;)
ÿÿÿÿ{
ÿÿÿÿÿÿÿ if (exp & 1)
ÿÿÿÿÿÿÿÿÿÿÿ result *= base;
ÿÿÿÿÿÿÿ exp >>= 1;
ÿÿÿÿÿÿÿ if (!exp)
ÿÿÿÿÿÿÿÿÿÿÿ break;
ÿÿÿÿÿÿÿ base *= base;
ÿÿÿÿ}
ÿÿÿÿreturn result;
}ÿ /* ipow */
On Mon, 17 Aug 2026 10:07:05 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
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.
Yeah. Not too surprising really, considering the general level
of the discussion -- an overly long thread for a problem that
should take at most 15 minutes to solve just by writing an
ipow() function.
Performance of ipow() is quite important in Elliptic Curve Cryptography (ECC). In this field it's worth spending much more than 15 minutes on optimization of this core primitive.
Of course, in case of ECC integers are wider than 64-bit (although not dramatically wider, IIRC, 192 bits are considered good enough in many real-world applications) and arithmetic is modular.
On 8/11/2026 3:01 AM, Lynn McGuire wrote:
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
Here is my code to date (longint is long long int):
//ÿ ipow.cpp
//ÿ calculate an longint power of a longint number
//ÿ INPUT:
//ÿÿÿÿ base - longint value of number
//ÿÿÿÿ exp - longint
//ÿ OUTPUT:
//ÿÿÿÿ longint value of base to the exp power
// REVISIONS:
// ==========
//ÿ 08/11/26ÿ Lynn McGuireÿ created using
// https://stackoverflow.com/questions/101439/the-most-efficient-way-to- implement-an-integer-based-power-function-powint-int
#include "dii.h"
longint ipow (longint base, longint exp)
{
ÿÿÿÿlongint result = 1;
ÿÿÿÿstd::string str;
ÿÿÿÿif (exp == 0 || base == 0) {
ÿÿÿÿÿÿÿ return result;
ÿÿÿÿ}
ÿÿÿÿif (exp < 0) {
ÿÿÿÿÿÿÿ scrwri ("");
ÿÿÿÿÿÿÿ str = "ERROR: exp is negative, " + asString (exp) + " (ipow)";
ÿÿÿÿÿÿÿ scrwri (str);
ÿÿÿÿÿÿÿ scrwri ("");
ÿÿÿÿÿÿÿ quit ();
ÿÿÿÿÿÿÿ return 0;
ÿÿÿÿ}
ÿÿÿÿfor (;;)
ÿÿÿÿ{
ÿÿÿÿÿÿÿ if (exp & 1)
ÿÿÿÿÿÿÿÿÿÿÿ result *= base;
ÿÿÿÿÿÿÿ exp >>= 1;
ÿÿÿÿÿÿÿ if (!exp)
ÿÿÿÿÿÿÿÿÿÿÿ break;
ÿÿÿÿÿÿÿ base *= base;
ÿÿÿÿ}
ÿÿÿÿreturn result;
}ÿ /* ipow */
On Mon, 17 Aug 2026 10:07:05 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
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.
Yeah. Not too surprising really, considering the general level
of the discussion -- an overly long thread for a problem that
should take at most 15 minutes to solve just by writing an
ipow() function.
Performance of ipow() is quite important in Elliptic Curve
Cryptography (ECC). In this field it's worth spending much more
than 15 minutes on optimization of this core primitive.
Of course, in case of ECC integers are wider than 64-bit (although
not dramatically wider, IIRC, 192 bits are considered good enough
in many real-world applications) and arithmetic is modular.
On 13/08/2026 00:52, Lawrence D?Oliveiro 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.
Doesn?t seem any more likely than writing ?1**32? 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.
Michael S <already5chosen@yahoo.com> writes:
On Mon, 17 Aug 2026 10:07:05 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
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.
Yeah. Not too surprising really, considering the general level
of the discussion -- an overly long thread for a problem that
should take at most 15 minutes to solve just by writing an
ipow() function.
Performance of ipow() is quite important in Elliptic Curve
Cryptography (ECC). In this field it's worth spending much more
than 15 minutes on optimization of this core primitive.
Of course, in case of ECC integers are wider than 64-bit (although
not dramatically wider, IIRC, 192 bits are considered good enough
in many real-world applications) and arithmetic is modular.
For the function originally being asked about, where the operations
are being done on basic integer types, I think 15 minutes (or so)
should be enough.
For applications like Elliptic Curve Cryptography, where the values
are multiple-precision integers rather than basic integer types, the
same algorithm should be okay, except that attention needs to be
given to the (modulo-ized) multi-precision multiplications used.
The bottleneck is multiplications, not the overall algorithm
structure.
As an experiment I took the C implementation I first wrote (which
had taken five or ten minutes) and wrote the same algorithm in
python, except that multiplications were done mod 2**192. I ran
trials with that, including for example
>>> ipow( 97,
>>> 33333333333333333333333333333333333333333333333333333333333 )
5528880020554650661730432042596473300798439881536715294689
All the trial invocations returned instantly. So I don't think the
original basic algorithm needs to be changed; as long as care is
given to how the multiplications are done (which python does a fair
job at, for this size of operands), a simple implementation should
be okay even for applications like ECC.
On 17/08/2026 23:35, Michael S wrote:
On Mon, 17 Aug 2026 10:07:05 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
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.
Yeah. Not too surprising really, considering the general level
of the discussion -- an overly long thread for a problem that
should take at most 15 minutes to solve just by writing an
ipow() function.
Performance of ipow() is quite important in Elliptic Curve
Cryptography (ECC). In this field it's worth spending much more
than 15 minutes on optimization of this core primitive.
Of course, in case of ECC integers are wider than 64-bit (although
not dramatically wider, IIRC, 192 bits are considered good enough
in many real-world applications) and arithmetic is modular.
Sure - but the key pointer there is that the arithmetic is modular.
A modular ipower() function is quite different from a non-modular
one, and used with very different values. I'd imagine a great deal
of effort goes into making them efficient for cryptography (ECC, RSA,
etc.)
On Tue, 18 Aug 2026 11:22:32 +0200
David Brown <david.brown@hesbynett.no> wrote:
On 17/08/2026 23:35, Michael S wrote:
On Mon, 17 Aug 2026 10:07:05 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
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.
Yeah. Not too surprising really, considering the general level
of the discussion -- an overly long thread for a problem that
should take at most 15 minutes to solve just by writing an
ipow() function.
Performance of ipow() is quite important in Elliptic Curve
Cryptography (ECC). In this field it's worth spending much more
than 15 minutes on optimization of this core primitive.
Of course, in case of ECC integers are wider than 64-bit (although
not dramatically wider, IIRC, 192 bits are considered good enough
in many real-world applications) and arithmetic is modular.
Sure - but the key pointer there is that the arithmetic is modular.
A modular ipower() function is quite different from a non-modular
one, and used with very different values. I'd imagine a great deal
of effort goes into making them efficient for cryptography (ECC, RSA,
etc.)
The only big difference that modular makes is that with non-modular you
can safely assume that big values of n do not matter (except of
trivial cases of a = 0 or 1).
Apart from that it's quite similar.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-16 16:33, Tim Rentsch wrote:
[snip]
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).
I find it easier simply to write a properly tail-recursive
implementation from the outset, where I know compilers will have
no difficulty optimizing out the tail calls.
Michael S <already5chosen@yahoo.com> writes:
On Mon, 17 Aug 2026 10:07:05 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
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.
Yeah. Not too surprising really, considering the general level
of the discussion -- an overly long thread for a problem that
should take at most 15 minutes to solve just by writing an
ipow() function.
Performance of ipow() is quite important in Elliptic Curve
Cryptography (ECC). In this field it's worth spending much more
than 15 minutes on optimization of this core primitive.
Of course, in case of ECC integers are wider than 64-bit (although
not dramatically wider, IIRC, 192 bits are considered good enough
in many real-world applications) and arithmetic is modular.
For the function originally being asked about, where the operations
are being done on basic integer types, I think 15 minutes (or so)
should be enough.
For applications like Elliptic Curve Cryptography, where the values
are multiple-precision integers rather than basic integer types, the
same algorithm should be okay, except that attention needs to be
given to the (modulo-ized) multi-precision multiplications used.
The bottleneck is multiplications, not the overall algorithm
structure.
As an experiment I took the C implementation I first wrote (which
had taken five or ten minutes) and wrote the same algorithm in
python, except that multiplications were done mod 2**192. I ran
trials with that, including for example
>>> ipow( 97, 33333333333333333333333333333333333333333333333333333333333 )
5528880020554650661730432042596473300798439881536715294689
All the trial invocations returned instantly. So I don't think the
original basic algorithm needs to be changed; as long as care is
given to how the multiplications are done (which python does a fair
job at, for this size of operands), a simple implementation should
be okay even for applications like ECC.
On Tue, 18 Aug 2026 08:38:43 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
On Mon, 17 Aug 2026 10:07:05 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
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.
Yeah. Not too surprising really, considering the general level
of the discussion -- an overly long thread for a problem that
should take at most 15 minutes to solve just by writing an
ipow() function.
Performance of ipow() is quite important in Elliptic Curve
Cryptography (ECC). In this field it's worth spending much more
than 15 minutes on optimization of this core primitive.
Of course, in case of ECC integers are wider than 64-bit (although
not dramatically wider, IIRC, 192 bits are considered good enough
in many real-world applications) and arithmetic is modular.
For the function originally being asked about, where the operations
are being done on basic integer types, I think 15 minutes (or so)
should be enough.
For applications like Elliptic Curve Cryptography, where the values
are multiple-precision integers rather than basic integer types, the
same algorithm should be okay, except that attention needs to be
given to the (modulo-ized) multi-precision multiplications used.
The bottleneck is multiplications, not the overall algorithm
structure.
As an experiment I took the C implementation I first wrote (which
had taken five or ten minutes) and wrote the same algorithm in
python, except that multiplications were done mod 2**192. I ran
trials with that, including for example
>>> ipow( 97,
>>> 33333333333333333333333333333333333333333333333333333333333 )
5528880020554650661730432042596473300798439881536715294689
All the trial invocations returned instantly. So I don't think the
original basic algorithm needs to be changed; as long as care is
given to how the multiplications are done (which python does a fair
job at, for this size of operands), a simple implementation should
be okay even for applications like ECC.
In my real world case the target was 32-bit microcontroller-class
soft core without hardware multiplier running at 100 MHz. Also,
we should not forget that a single ECDSA signature validation
contains plenty of ipow() steps. Right now I don't remember how
many.
I didn't try algorithm presented here by Bart, but tried something
that can be seen as its mirror image.
wword ipow(wword a, wword n)
{
if (n < 2)
return n == 0 ? 1 : a;
wword y = ipow(a, n/2);
y *= y;
if (n & 1)
y *= a;
return y;
}
Please, treat it as a pseudocode.
Real code was more complicated, with function calls instead of *
and recursion was manually converted to iteration.
The result was slower than the following (pseudo) code:
wword ipow(wword a, wword n)
{
wword y = 1, p = a;
while (1) {
if (n & 1)
y *= p;
n /= 2;
if (!n)
break;
p *= p;
}
return y;
}
I didn't try to investiagete reasons for the difference.
If I were to take a similar approach, I might write
something like this (disclaimer: not compiled):
wword
xpow( wword a, wword n ){
if( n < 2 ){
// handle powers less than 2
// exercise for the reader
}
wword r = 1;
do {
if( n & 1 ) r *= a;
a *= a;
} while( n /= 2, n > 1 );
return r*a;
}
On 2026-08-17 19:22, Tim Rentsch wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-16 16:33, Tim Rentsch wrote:
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).
I find it easier simply to write a properly tail-recursive
implementation from the outset,
Fair enough.
where I know compilers will have
no difficulty optimizing out the tail calls.
Not all might know whether and what sorts of constructs their
compilers are able to optimize.
To me it's not obvious that
simple (but non-tail-) recursions are typically not optimized.
YMMV, but sensible optimizations is IMO task of the compilers;
it shouldn't be necessary that you have to formulate programs
using a specific programming pattern;
ideally - but "C" as had
been discussed not long ago exposes anyway a peculiar view of
optimizations. (I'm sure YMMV.)
That isn't surprising, considering that the recursive call
is not tail recursive.
On Tue, 18 Aug 2026 15:42:54 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
That isn't surprising, considering that the recursive call
is not tail recursive.
As mentioned above, the presented pseudo-code serves for illustration.
The actual code executed the same multiplications in the same order but
was writen in iterative style.
Michael S <already5chosen@yahoo.com> writes:
On Tue, 18 Aug 2026 15:42:54 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
That isn't surprising, considering that the recursive call
is not tail recursive.
As mentioned above, the presented pseudo-code serves for
illustration. The actual code executed the same multiplications in
the same order but was writen in iterative style.
Right. Even though transformed into an iterative function body, the pseudocode being a non-tail-recursive formulation might induce a bad
result in the resulting iterative code. General recursion can easily
produce bad structure relative to a more linear method.
It might be interesting to see the iterative code that you actually
ran, assuming of course there isn't too much clutter from how the multiplications were done, etc.
On Wed, 19 Aug 2026 18:25:36 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
On Tue, 18 Aug 2026 15:42:54 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
That isn't surprising, considering that the recursive call
is not tail recursive.
As mentioned above, the presented pseudo-code serves for
illustration. The actual code executed the same multiplications in
the same order but was writen in iterative style.
Right. Even though transformed into an iterative function body, the
pseudocode being a non-tail-recursive formulation might induce a bad
result in the resulting iterative code. General recursion can easily
produce bad structure relative to a more linear method.
It might be interesting to see the iterative code that you actually
ran, assuming of course there isn't too much clutter from how the
multiplications were done, etc.
It was 8 years ago.
I didn't preserve intermediate variants that did not make it into
final solution.
You should also drop the C90 "declare all variables at the top of the function" style.ÿ It's a bad idea in C, and a terrible idea in C++.ÿ You don't want to be unnecessarily creating a std::string object and running
its constructor and destructor in a function that should be fast.
Instead, put the declaration where it is needed :
ÿÿÿÿconst std::string str = "ERROR ..."
On 8/18/2026 4:32 AM, David Brown wrote:
...
You should also drop the C90 "declare all variables at the top of the
function" style.ÿ It's a bad idea in C, and a terrible idea in C++.
You don't want to be unnecessarily creating a std::string object and
running its constructor and destructor in a function that should be
fast. Instead, put the declaration where it is needed :
ÿÿÿÿÿconst std::string str = "ERROR ..."
Real programmers can write Fortran code in any language.
[on using -1 to produce all ones in an unsigned type]
I also dislike that use of -1. I prefer using ~0ul to get all-ones.
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:
[...]
Some people see that as an advantage - being able to write "unsigned
very_big = -1;". I dislike it personally, but styles and preferences
vary, and it has portability advantages over, say, 0xffff'ffff.
I also dislike that use of -1. I prefer using ~0ul to get all-ones.
I'd use ~0ul to get all-ones, -1 or -1u to get the largest value
of the type (or preferably UINT_MAX, but -1 is good if it's not
obvious *which* unsigned type I'm using).
The fact that they happen to be the same value is a technical detail
that I don't necessarily want to worry about. Whether I use ~0ul
or -1 depends on which concept I want to express.
On 22/08/2026 00:22, Lynn McGuire wrote:
On 8/18/2026 4:32 AM, David Brown wrote:
...
You should also drop the C90 "declare all variables at the top of the
function" style.ÿ It's a bad idea in C, and a terrible idea in C++.
You don't want to be unnecessarily creating a std::string object and
running its constructor and destructor in a function that should be
fast. Instead, put the declaration where it is needed :
ÿÿÿÿÿconst std::string str = "ERROR ..."
Real programmers can write Fortran code in any language.
That may be true - but the real question is, should they?
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:[...]
Some people see that as an advantage - being able to write "unsigned
very_big = -1;". I dislike it personally, but styles and preferences
vary, and it has portability advantages over, say, 0xffff'ffff.
I also dislike that use of -1. I prefer using ~0ul to get all-ones.
I'd use ~0ul to get all-ones,
-1 or -1u to get the largest value
of the type (or preferably UINT_MAX, but -1 is good if it's not
obvious *which* unsigned type I'm using).
The fact that they happen to be the same value is a technical detail
that I don't necessarily want to worry about. Whether I use ~0ul
or -1 depends on which concept I want to express.
[ [tail] recursion optimisation of ipow()ÿ]
As I noted earlier, it will make very little difference in this case
because the recursion depth is not going to me more than a couple of
levels anyway.
On 2026-08-18 01:49, Keith Thompson wrote:
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:[...]
I'd use ~0ul to get all-ones,Some people see that as an advantage - being able to write "unsigned
very_big = -1;". I dislike it personally, but styles and preferences
vary, and it has portability advantages over, say, 0xffff'ffff.
I also dislike that use of -1. I prefer using ~0ul to get all-ones.
Exactly. As '~' is the bit-complement operator it's the most obvious,
most consistent, and thus to be expected to be understood by most if
not all C-programmers. But do we need the type qualification at all?
A quick test seems to indicate that '~0' can be used for all integral
types. (That's what my compiler says, don't know about the standard.)
-1 or -1u to get the largest value
of the type (or preferably UINT_MAX, but -1 is good if it's not
obvious *which* unsigned type I'm using).
Isn't SIZE_MAX supposed to cover that for size_t at least? Are there
other unsigned types that lack such a constant? (I haven't checked.)
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-18 01:49, Keith Thompson wrote:
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:[...]
I'd use ~0ul to get all-ones,Some people see that as an advantage - being able to write "unsigned >>>>> very_big = -1;". I dislike it personally, but styles and preferences >>>>> vary, and it has portability advantages over, say, 0xffff'ffff.
I also dislike that use of -1. I prefer using ~0ul to get all-ones.
Exactly. As '~' is the bit-complement operator it's the most obvious,
most consistent, and thus to be expected to be understood by most if
not all C-programmers. But do we need the type qualification at all?
A quick test seems to indicate that '~0' can be used for all integral
types. (That's what my compiler says, don't know about the standard.)
-1 or -1u to get the largest value
of the type (or preferably UINT_MAX, but -1 is good if it's not
obvious *which* unsigned type I'm using).
-1 is an expression of type int. Converting it to an unsigned type
always yields the largest value of that type. Same for -1 of any signed type.
-1u is of type unsigned int. Converting it to an unsigned type wider
than unsigned int will not give you the largest value of that type.
Using -1u makes sense only if you know you want a value of type unsigned
int.
[...]
On 2026-08-26 02:56, Keith Thompson wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-18 01:49, Keith Thompson wrote:
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:
[...]
Some people see that as an advantage - being able to write
"unsigned very_big = -1;". I dislike it personally, but styles
and preferences vary, and it has portability advantages over,
say, 0xffff'ffff.
I also dislike that use of -1. I prefer using ~0ul to get
all-ones.
I'd use ~0ul to get all-ones,
Exactly. As '~' is the bit-complement operator it's the most
obvious, most consistent, and thus to be expected to be understood
by most if not all C-programmers. But do we need the type
qualification at all? A quick test seems to indicate that '~0'
can be used for all integral types. (That's what my compiler
says, don't know about the standard.)
-1 or -1u to get the largest value
of the type (or preferably UINT_MAX, but -1 is good if it's not
obvious *which* unsigned type I'm using).
-1 is an expression of type int. Converting it to an unsigned type
always yields the largest value of that type. Same for -1 of any
signed type.
-1u is of type unsigned int. Converting it to an unsigned type
wider than unsigned int will not give you the largest value of that
type. Using -1u makes sense only if you know you want a value of
type unsigned int.
I'm not sure it was clear that my "But do we need the type
qualification at all?" remark was meant for the '~0' context and "all-bits-set case".
Mind, you had previously written: "I prefer using ~0ul". - And I
was asking whether that would be necessary here, i.e. for the
bits-case and unknown sizes of the underlying types. - I'd think
that a "generic" '~0' would suffice (and impose the least
surprises).
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-26 02:56, Keith Thompson wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-18 01:49, Keith Thompson wrote:
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:
[...]
Some people see that as an advantage - being able to write
"unsigned very_big = -1;". I dislike it personally, but styles
and preferences vary, and it has portability advantages over,
say, 0xffff'ffff.
I also dislike that use of -1. I prefer using ~0ul to get
all-ones.
I'd use ~0ul to get all-ones,
Exactly. As '~' is the bit-complement operator it's the most
obvious, most consistent, and thus to be expected to be understood
by most if not all C-programmers. But do we need the type
qualification at all? A quick test seems to indicate that '~0'
can be used for all integral types. (That's what my compiler
says, don't know about the standard.)
-1 or -1u to get the largest value
of the type (or preferably UINT_MAX, but -1 is good if it's not
obvious *which* unsigned type I'm using).
-1 is an expression of type int. Converting it to an unsigned type
always yields the largest value of that type. Same for -1 of any
signed type.
-1u is of type unsigned int. Converting it to an unsigned type
wider than unsigned int will not give you the largest value of that
type. Using -1u makes sense only if you know you want a value of
type unsigned int.
I'm not sure it was clear that my "But do we need the type
qualification at all?" remark was meant for the '~0' context and
"all-bits-set case".
Mind, you had previously written: "I prefer using ~0ul". - And I
was asking whether that would be necessary here, i.e. for the
bits-case and unknown sizes of the underlying types. - I'd think
that a "generic" '~0' would suffice (and impose the least
surprises).
The expression ~0 works for some conforming implementations.
[...]
Generally I tend to prefer code that always works over code
that only sometimes works.
On 2026-08-26 04:57, Tim Rentsch wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-26 02:56, Keith Thompson wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-18 01:49, Keith Thompson wrote:
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:
[...]
Some people see that as an advantage - being able to write
"unsigned very_big = -1;". I dislike it personally, but styles >>>>>>>> and preferences vary, and it has portability advantages over,
say, 0xffff'ffff.
I also dislike that use of -1. I prefer using ~0ul to get
all-ones.
I'd use ~0ul to get all-ones,
Exactly. As '~' is the bit-complement operator it's the most
obvious, most consistent, and thus to be expected to be understood
by most if not all C-programmers. But do we need the type
qualification at all? A quick test seems to indicate that '~0'
can be used for all integral types. (That's what my compiler
says, don't know about the standard.)
-1 or -1u to get the largest value
of the type (or preferably UINT_MAX, but -1 is good if it's not
obvious *which* unsigned type I'm using).
-1 is an expression of type int. Converting it to an unsigned type
always yields the largest value of that type. Same for -1 of any
signed type.
-1u is of type unsigned int. Converting it to an unsigned type
wider than unsigned int will not give you the largest value of that
type. Using -1u makes sense only if you know you want a value of
type unsigned int.
I'm not sure it was clear that my "But do we need the type
qualification at all?" remark was meant for the '~0' context and
"all-bits-set case".
Mind, you had previously written: "I prefer using ~0ul". - And I
was asking whether that would be necessary here, i.e. for the
bits-case and unknown sizes of the underlying types. - I'd think
that a "generic" '~0' would suffice (and impose the least
surprises).
The expression ~0 works for some conforming implementations.
Not sure I understand your formulation ("some conforming ...").
Are you implying that the following examples are non-portable,
undefined, or depending on the concrete (standard-)conforming
implementation, or something else?
short unsigned int sd = ~0;
unsigned int d = ~0;
long unsigned int ld = ~0;
long long unsigned int lld = ~0;
The comment in my K&R copy sounds as if it should work on any
integral type like that. - Have the C-standards changed that?
Can you provide some evidence or C-standard-quote where that is
documented? - I'm really interested to know.
[...]
Generally I tend to prefer code that always works over code
that only sometimes works.
I'd say that most people would agree to that triviality.
I think we can spare us such Kindergarten-rhetorics; it neither
supports or affirmates the answer nor provides any evidence for
the expressed statement. - Thanks.
On 2026-08-26 04:57, Tim Rentsch wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-26 02:56, Keith Thompson wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-18 01:49, Keith Thompson wrote:
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:
[...]
Some people see that as an advantage - being able to write
"unsigned very_big = -1;".ÿ I dislike it personally, but styles >>>>>>>> and preferences vary, and it has portability advantages over,
say, 0xffff'ffff.
I also dislike that use of -1.ÿ I prefer using ~0ul to get
all-ones.
I'd use ~0ul to get all-ones,
Exactly.ÿ As '~' is the bit-complement operator it's the most
obvious, most consistent, and thus to be expected to be understood
by most if not all C-programmers.ÿ But do we need the type
qualification at all?ÿ A quick test seems to indicate that '~0'
can be used for all integral types.ÿ (That's what my compiler
says, don't know about the standard.)
-1 or -1u to get the largest value
of the type (or preferably UINT_MAX, but -1 is good if it's not
obvious *which* unsigned type I'm using).
-1 is an expression of type int.ÿ Converting it to an unsigned type
always yields the largest value of that type.ÿ Same for -1 of any
signed type.
-1u is of type unsigned int.ÿ Converting it to an unsigned type
wider than unsigned int will not give you the largest value of that
type.ÿ Using -1u makes sense only if you know you want a value of
type unsigned int.
I'm not sure it was clear that my "But do we need the type
qualification at all?" remark was meant for the '~0' context and
"all-bits-set case".
Mind, you had previously written:ÿ "I prefer using ~0ul". - And I
was asking whether that would be necessary here, i.e. for the
bits-case and unknown sizes of the underlying types. - I'd think
that a "generic" '~0' would suffice (and impose the least
surprises).
The expression ~0 works for some conforming implementations.
Not sure I understand your formulation ("some conforming ...").
Are you implying that the following examples are non-portable,
undefined, or depending on the concrete (standard-)conforming
implementation, or something else?
short unsigned int sd = ~0;
unsigned int d = ~0;
long unsigned int ld = ~0;
long long unsigned int lld = ~0;
The expression ~0 works for some conforming implementations.
The expression -1 works for all conforming implementations.
Generally I tend to prefer code that always works over code
that only sometimes works.
On 2026-08-18 01:49, Keith Thompson wrote:
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:[...]
Some people see that as an advantage - being able to write "unsigned
very_big = -1;". I dislike it personally, but styles and preferences
vary, and it has portability advantages over, say, 0xffff'ffff.
I also dislike that use of -1. I prefer using ~0ul to get all-ones.
I'd use ~0ul to get all-ones,
Exactly. As '~' is the bit-complement operator it's the most obvious,
most consistent, and thus to be expected to be understood by most if
not all C-programmers. But do we need the type qualification at all?
A quick test seems to indicate that '~0' can be used for all integral
types. (That's what my compiler says, don't know about the standard.)
On 26/08/2026 05:33, Janis Papanagnou wrote:
On 2026-08-26 04:57, Tim Rentsch wrote:The behaviours of these are all defined, but are at least partially implementation-defined.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-26 02:56, Keith Thompson wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-18 01:49, Keith Thompson wrote:
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:
[...]
Some people see that as an advantage - being able to write
"unsigned very_big = -1;".ÿ I dislike it personally, but styles >>>>>>>>> and preferences vary, and it has portability advantages over, >>>>>>>>> say, 0xffff'ffff.
I also dislike that use of -1.ÿ I prefer using ~0ul to get
all-ones.
I'd use ~0ul to get all-ones,
Exactly.ÿ As '~' is the bit-complement operator it's the most
obvious, most consistent, and thus to be expected to be understood >>>>>> by most if not all C-programmers.ÿ But do we need the type
qualification at all?ÿ A quick test seems to indicate that '~0'
can be used for all integral types.ÿ (That's what my compiler
says, don't know about the standard.)
-1 or -1u to get the largest value
of the type (or preferably UINT_MAX, but -1 is good if it's not
obvious *which* unsigned type I'm using).
-1 is an expression of type int.ÿ Converting it to an unsigned type
always yields the largest value of that type.ÿ Same for -1 of any
signed type.
-1u is of type unsigned int.ÿ Converting it to an unsigned type
wider than unsigned int will not give you the largest value of that
type.ÿ Using -1u makes sense only if you know you want a value of
type unsigned int.
I'm not sure it was clear that my "But do we need the type
qualification at all?" remark was meant for the '~0' context and
"all-bits-set case".
Mind, you had previously written:ÿ "I prefer using ~0ul". - And I
was asking whether that would be necessary here, i.e. for the
bits-case and unknown sizes of the underlying types. - I'd think
that a "generic" '~0' would suffice (and impose the least
surprises).
The expression ~0 works for some conforming implementations.
Not sure I understand your formulation ("some conforming ...").
Are you implying that the following examples are non-portable,
undefined, or depending on the concrete (standard-)conforming
implementation, or something else?
short unsigned int sd = ~0;
unsigned int d = ~0;
long unsigned int ld = ~0;
long long unsigned int lld = ~0;
"0" is of type "int".ÿ So "~0" gives the "int" value where all bits are
set to 1.ÿ Given two's complement representation (since we are now on
C23), that means the initialisations are the same as if you had written
"= -1;", and in each case your variable gets the highest value of the
target unsigned integer type.
Prior to C23, two's complement was not the only representation
available.ÿ The bit-inversion of 0 is not necessarily the value 1.ÿ With sign-magnitude, it would (I think) be INT_MIN, and the conversion to an unsigned type would not be all ones.
(Padding bits, if any, should not affect the results here.)
On 2026-08-26 09:48, David Brown wrote:
On 26/08/2026 05:33, Janis Papanagnou wrote:
On 2026-08-26 04:57, Tim Rentsch wrote:The behaviours of these are all defined, but are at least partially
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-26 02:56, Keith Thompson wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-08-18 01:49, Keith Thompson wrote:
scott@slp53.sl.home (Scott Lurndal) writes:
David Brown <david.brown@hesbynett.no> writes:
[...]
Some people see that as an advantage - being able to write >>>>>>>>>> "unsigned very_big = -1;".ÿ I dislike it personally, but styles >>>>>>>>>> and preferences vary, and it has portability advantages over, >>>>>>>>>> say, 0xffff'ffff.
I also dislike that use of -1.ÿ I prefer using ~0ul to get
all-ones.
I'd use ~0ul to get all-ones,
Exactly.ÿ As '~' is the bit-complement operator it's the most
obvious, most consistent, and thus to be expected to be understood >>>>>>> by most if not all C-programmers.ÿ But do we need the type
qualification at all?ÿ A quick test seems to indicate that '~0'
can be used for all integral types.ÿ (That's what my compiler
says, don't know about the standard.)
-1 or -1u to get the largest value
of the type (or preferably UINT_MAX, but -1 is good if it's not >>>>>>>> obvious *which* unsigned type I'm using).
-1 is an expression of type int.ÿ Converting it to an unsigned type >>>>>> always yields the largest value of that type.ÿ Same for -1 of any
signed type.
-1u is of type unsigned int.ÿ Converting it to an unsigned type
wider than unsigned int will not give you the largest value of that >>>>>> type.ÿ Using -1u makes sense only if you know you want a value of
type unsigned int.
I'm not sure it was clear that my "But do we need the type
qualification at all?" remark was meant for the '~0' context and
"all-bits-set case".
Mind, you had previously written:ÿ "I prefer using ~0ul". - And I
was asking whether that would be necessary here, i.e. for the
bits-case and unknown sizes of the underlying types. - I'd think
that a "generic" '~0' would suffice (and impose the least
surprises).
The expression ~0 works for some conforming implementations.
Not sure I understand your formulation ("some conforming ...").
Are you implying that the following examples are non-portable,
undefined, or depending on the concrete (standard-)conforming
implementation, or something else?
short unsigned int sd = ~0;
unsigned int d = ~0;
long unsigned int ld = ~0;
long long unsigned int lld = ~0;
implementation-defined.
("defined", "partially", "implementation-defined", well... - what
can a C-user *reliably* deduce from that...)
"0" is of type "int".ÿ So "~0" gives the "int" value where all bits
are set to 1.ÿ Given two's complement representation (since we are now
on C23), that means the initialisations are the same as if you had
written "= -1;", and in each case your variable gets the highest value
of the target unsigned integer type.
Prior to C23, two's complement was not the only representation
available.ÿ The bit-inversion of 0 is not necessarily the value 1.
With sign-magnitude, it would (I think) be INT_MIN, and the conversion
to an unsigned type would not be all ones.
(Padding bits, if any, should not affect the results here.)
I had written a longish reply on that but abstain from sending it,
instead, for the moment, I just like to ask - to obtain a better understanding! - which of the following declarations are reliable
or unreliable, portable, depending on specific compilers - you know
what I mean - in your understanding.
All of the following declarations produce (with my GNU C-compiler)
no error diagnostics and no warning, not even with -Wall -Wpedantic
and with various standards from c89 to c2x defined). And they all
(i.e. the below printed subset) produce the same result (-1).
Without extending on details of my withheld post, the operation of
the '~' is in K&R speaking about the "integral types" not the 'int'
type, as opposed to other operators' context where specifically the
'int' type is addressed.
IOW, yet (and still) I have to observe any reliability issue with ~0.
Without extending on details of my withheld post, the operation of
the '~' is in K&R speaking about the "integral types" not the 'int'
type, as opposed to other operators' context where specifically the
'int' type is addressed.
wword ipow(wword a, wword n)
{
if (n < 2)
return n == 0 ? 1 : a;
wword y = ipow(a, n/2);
y *= y;
if (n & 1)
y *= a;
return y;
}
Please, treat it as a pseudocode.
Real code was more complicated, with function calls instead of *
and recursion was manually converted to iteration.
The result was slower than the following (pseudo) code:
wword ipow(wword a, wword n)
{
wword y = 1, p = a;
while (1) {
if (n & 1)
y *= p;
n /= 2;
if (!n)
break;
p *= p;
}
return y;
}
I didn't try to investiagete reasons for the difference.
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.
On Tue, 11 Aug 2026 16:56:04 +0200, 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 )
{
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.
float can not handle numbers ipow or ltor or powermod can...
example ipow(123456,123456) with the right trunched result...
Also maths functions should never return an optional. They should return the numeric result or NaN.There are no NaNs with integrals, so an optional is o.k..
Am 29.08.2026 um 17:43 schrieb boltar@caprica.universe:
Also maths functions should never return an optional. They should return the >> numeric result or NaN.There are no NaNs with integrals, so an optional is o.k..
Wtf are you talking about, its raising an integer to a power, integrals don't come into it.An integer pow can easily be out of bounds, that's while I'm
On Sun, 30 Aug 2026 05:33:31 +0200
Bonita Montero <Bonita.Montero@gmail.com> gabbled:
Am 29.08.2026 um 17:43 schrieb boltar@caprica.universe:
Also maths functions should never return an optional. They shouldThere are no NaNs with integrals, so an optional is o.k..
return the
numeric result or NaN.
Wtf are you talking about, its raising an integer to a power, integrals don't
come into it.
On 30/08/2026 15:02, boltar@caprica.universe wrote:
On Sun, 30 Aug 2026 05:33:31 +0200
Bonita Montero <Bonita.Montero@gmail.com> gabbled:
Am 29.08.2026 um 17:43 schrieb boltar@caprica.universe:
Also maths functions should never return an optional. They shouldThere are no NaNs with integrals, so an optional is o.k..
return the
numeric result or NaN.
Wtf are you talking about, its raising an integer to a power,
integrals don't
come into it.
I assume Bonita was using "integral" as an adjective - an alternative to "integer types" - rather than the term from calculus.
The discussion was about a function that raises an integer to an
integer, returning an integer - with various possible choices of the concrete integer types to use.ÿ Integer types in C and C++ do not have
NaNs or other error value indicators.ÿ So this kind of function cannot
use such returns to indicate errors.
Alternatives include :
1. Let overflow be UB, and don't care what you return on overflow.
2. Pick a specific integer value to return if there is an overflow.
3. Call an error-handling function of some sort.
4. Throw an exception (C++ only, obviously).
5. Use a side-channel indication, like errno.
6. Augment the return to include an indication of error or the validity
of the result.ÿ For C++, std::optional<> and std::expected<> are both
solid choices there.
On 30/08/2026 15:02, boltar@caprica.universe wrote:
The discussion was about a function that raises an integer to an
integer, returning an integer - with various possible choices of the >concrete integer types to use. Integer types in C and C++ do not have
NaNs or other error value indicators. So this kind of function cannot
use such returns to indicate errors.
Alternatives include :
4. Throw an exception (C++ only, obviously).
On 31/08/2026 09:04, David Brown wrote:
On 30/08/2026 15:02, boltar@caprica.universe wrote:
On Sun, 30 Aug 2026 05:33:31 +0200
Bonita Montero <Bonita.Montero@gmail.com> gabbled:
Am 29.08.2026 um 17:43 schrieb boltar@caprica.universe:
Also maths functions should never return an optional. They shouldThere are no NaNs with integrals, so an optional is o.k..
return the
numeric result or NaN.
Wtf are you talking about, its raising an integer to a power,
integrals don't
come into it.
I assume Bonita was using "integral" as an adjective - an alternative
to "integer types" - rather than the term from calculus.
The discussion was about a function that raises an integer to an
integer, returning an integer - with various possible choices of the
concrete integer types to use.ÿ Integer types in C and C++ do not have
NaNs or other error value indicators.ÿ So this kind of function cannot
use such returns to indicate errors.
Alternatives include :
1. Let overflow be UB, and don't care what you return on overflow.
Yes, I don't see the need for:
ÿÿ if (ipow(a, 2) + ipow(b, 2) == ipow(c, 2))
to behave any differently from:
ÿÿ if (a*a + b*b == c*c)
2. Pick a specific integer value to return if there is an overflow.
3. Call an error-handling function of some sort.
4. Throw an exception (C++ only, obviously).
5. Use a side-channel indication, like errno.
6. Augment the return to include an indication of error or the
validity of the result.ÿ For C++, std::optional<> and std::expected<>
are both solid choices there.
How would this even work for an example that looks like the above?
With NaNs, I believe a NaN result early in a expression will propagate through to the result, so can be tested for once, or can itself propagate.
'ipow' would be used where it is more convenient or appropriate than the alternative, or where the exponent is a variable, or where it imparts
useful extra information.
(Obviously, in my example, ipow needs more typing and is less convenient.)
| Sysop: | Tetrazocine |
|---|---|
| Location: | Melbourne, VIC, Australia |
| Users: | 9 |
| Nodes: | 8 (0 / 8) |
| Uptime: | 245:22:42 |
| Calls: | 220 |
| Files: | 21,513 |
| Messages: | 83,782 |