









 
 




 
 


So, I'm trying to write some macros that use pow(X, V).
I'm trying to make it past the "domain error" when pow(0,0) occurs.
So I tried:
#local PowX = select (X * V * (1X), 0, 0, pow(X, V) );
But that gave me the same error, presumably because select evaluates the full
expression even though the threshold switch won't implement the >0 result.
So I finally did the following:
#declare E = 0.0000001;
#local PowX = select ((X * V * (1X))E, 0, 0, pow(X+E, V) );
#local Pow1minX = select ((1X)*(NV), 0, 0, pow((1X),(NV)) );
At some point X=1, and so 11=0, and you'd expect to get the same domain error,
but that doesn't happen.
Is there a better, more elegant way to do this?
Is this a floating point thing again  out at the 15th decimal place?
Isn't there a pow function that tolerates / passes through pow(0,0) as 0, like
the magical atan2 ?
I must say that it get get REALLY frustrating to get bogged down in fixing
things that you wouldn't have thought needed fixing, just so you can get back to
the point of working on the ACTUAL math that you started trying to fix.
Post a reply to this message


 
 




 
 


Am 25.08.2018 um 18:41 schrieb Bald Eagle:
>
> So, I'm trying to write some macros that use pow(X, V).
> I'm trying to make it past the "domain error" when pow(0,0) occurs.
>
> So I tried:
> #local PowX = select (X * V * (1X), 0, 0, pow(X, V) );
> But that gave me the same error, presumably because select evaluates the full
> expression even though the threshold switch won't implement the >0 result.
>
> So I finally did the following:
>
> #declare E = 0.0000001;
> #local PowX = select ((X * V * (1X))E, 0, 0, pow(X+E, V) );
>
> #local Pow1minX = select ((1X)*(NV), 0, 0, pow((1X),(NV)) );
>
> At some point X=1, and so 11=0, and you'd expect to get the same domain error,
> but that doesn't happen.
Are you sure that NV=0, too?
> Is there a better, more elegant way to do this?
In a macro? Why, yes, of course! Why not use `#if` instead of `select`?
> Isn't there a pow function that tolerates / passes through pow(0,0) as 0, like
> the magical atan2 ?
And what result should that function return?
In some applications, you may want the result to be 1, to conform with
x^0=1; in other applications, a result of 0 would make more sense, to
conform with 0^x=0.
And in yet other applications, the most sensible thing to do is catch
this case further upstream and report that something's just totally wrong.
Post a reply to this message


 
 




 
 


clipka <ano### [at] anonymousorg> wrote:
I take it that's an implied confirmation that select() evaluates all the return
arguments before returning the conditional result.
> Are you sure that NV=0, too?
"Yes." #for (V, 0, N)....
So NV when V=N _should_ indeed "equal zero"
But I'm in the middle of debugging the chainlinked macros I've coded, so I
shall find out for certain.
Right now, I'm making them more svelt. More chainlink, less barbedwire.
> In a macro? Why, yes, of course! Why not use `#if` instead of `select`?
Because that seemed iffy? :P
I like to branch out and sample the different methods of doing things, and keep
my function {} skills unatrophied. :P
Because sometimes I just don't like the if[then]elseend block and select()
seemed visually neater. And every little thing that's not distracting helps.
> > Isn't there a pow function that tolerates / passes through pow(0,0) as 0, like
> > the magical atan2 ?
>
> And what result should that function return?
Bags of hundred dollar bills.
Oh, how I could have bet money that this question would be asked... :D
> In some applications, you may want the result to be 1, to conform with
> x^0=1;
pow1 (x, 0) = 1
> in other applications, a result of 0 would make more sense, to
> conform with 0^x=0.
pow0 (x,0) = 1
> And in yet other applications, the most sensible thing to do is catch
> this case further upstream and report that something's just totally wrong.
pow (x, 0) = undefined, out of range, error, nil, nul, whatever you'd like.
Maybe just make it a warning.
roll it up to include all three:
pow (x, 0, Mode)
Something. I just think that 25yearold legendary software ought to be mature
enough to not require the user to code their way out of something that should
only require a switch or the trivial documented use of an alternate function 
like with atan() and atan2().
Post a reply to this message


 
 




 
 


Am 25.08.2018 um 23:23 schrieb Bald Eagle:
> I take it that's an implied confirmation that select() evaluates all the return
> arguments before returning the conditional result.
I can confirm for `select()` in normal SDL expressions. For use of
`select()` in functions I'd have to dig deeper.
Post a reply to this message


 
 




 
 


Am 25.08.2018 um 23:23 schrieb Bald Eagle:
> Right now, I'm making them more svelt. More chainlink, less barbedwire.
I had to look that up.
> Something. I just think that 25yearold legendary software ought to be mature
> enough to not require the user to code their way out of something that should
> only require a switch or the trivial documented use of an alternate function 
Name any respectable programming language that provides workarounds for
the pow(0,0) problem out of the box.
> like with atan() and atan2().
That's a whole different game. Technically, `atan2()` is an answer to a
very different question than `atan()`.
`atan(x)` gives the answer to the quite academic question, "what is the
arcus tangens of x, as per the mathematical definition?"
`atan2(y,x)` gives the answer to the far more practical question, "what
is the angle between the X axis and a ray from (0;0) to (x;y) in
cartesian space, as per geometric properties?". Its name derives from
the fact that the answer /happens/ to coincide with `atan(y/x)` for
positive x (and that the function takes 2 arguments), but it really is a
fundamentally different question.
While this latter question could be rephrased in terms of the former one
plus some extra steps, it occurs so frequently that having a dedicated
stock function for it is perfectly warranted.
The `pow()` case is totally different: There is no corresponding
practical question that would require graceful handling of the special
case equivalent to `pow(0,0)` while also being asked frequently enough
to warrant a dedicated stock function.
And thus, to the best of my knowledge there is no program language of
any renown that has such a function. Whether you use POVRay's SDL,
C/C++, Fortran, Java, C#, Python, Ruby, Go, Lolcode, or whathaveyou,
you will always have to do special handling if your algorithm involves
computing `pow(a,b)` with a and b potentially being both zero.
In contrast, `atan2` has been around at least since the 1970s, and has
spread from Fortran 77 to pretty much any language of renown that is
frequently used for mathematicallyoriented applications (including
POVRay's SDL, C/C++, Java, C#, Python, Ruby and Go, and probably also
whathaveyou).
Fun fact: Although `atan2` (aka `arctan2`) originally started out as a
shortcut software function, nowadays it appears to be considered a
fullfledged mathematical function in its own right.
Post a reply to this message


 
 




 

