- **C Programming**
(*http://www.velocityreviews.com/forums/f42-c-programming.html*)

- - **computing t = pow(-11.5, .333)**
(*http://www.velocityreviews.com/forums/t442780-computing-t-pow-11-5-333-a.html*)

computing t = pow(-11.5, .333)In a C program I need to do exponentiation where the base is
negative and the exponent is a fraction. In standard C this would be something like t = pow(-11.5, .333), but with this combination of arguments there is a domain error and the result is a percolating NaN. I worked around the problem by putting the standard function in a wrapper: double xpow(double b, double x) { double p; if(b < 0) { p = pow(-b, x); p *= -1.0; } else p = pow(b, x); return p; } Is there any particular reason for this limitation in the standard library function? Has anyone else had a problem with this and found a better solution? JS |

Re: computing t = pow(-11.5, .333)John Smith wrote:
> > In a C program I need to do exponentiation where the base is > negative and the exponent is a fraction. In standard C this would > be something like t = pow(-11.5, .333), but with this combination > of arguments there is a domain error and the result is a > percolating NaN. > > I worked around the problem by putting the standard function in a > wrapper: > > double xpow(double b, double x) > { > double p; > > if(b < 0) > { > p = pow(-b, x); > p *= -1.0; > } > else p = pow(b, x); > > return p; > } > > Is there any particular reason for this limitation in the > standard library function? Has anyone else had a problem with > this and found a better solution? -11.5 has a third root which is negative, if that's what you're really trying to find. However, if you consider that a negative number raised to an even integer power, is positive, and that a negative number raised to an odd integer power, is negative, then it just seems natural that the sign of a negative number raised to a non integer, should be undefined. -- pete |

Re: computing t = pow(-11.5, .333)John Smith wrote:
> In a C program I need to do exponentiation where the base is > negative and the exponent is a fraction. In standard C this would > be something like t = pow(-11.5, .333), but with this combination > of arguments there is a domain error and the result is a > percolating NaN. > > I worked around the problem by putting the standard function in a > wrapper: > > double xpow(double b, double x) > { > double p; > > if(b < 0) > { > p = pow(-b, x); > p *= -1.0; > } > else p = pow(b, x); > > return p; > } > > Is there any particular reason for this limitation in the > standard library function? Has anyone else had a problem with > this and found a better solution? I don't know why the pow function is defined this way and there is little insight in the rationale. You can obtain the expected result of pow(-11.5, .333) by using the cube root function from C99 if your implementation provide it: cbrt(-11.5);. Robert Gamble |

Re: computing t = pow(-11.5, .333)Robert Gamble wrote:
> John Smith wrote: > > In a C program I need to do exponentiation where the base is > > negative and the exponent is a fraction. In standard C this would > > be something like t = pow(-11.5, .333), but with this combination > > of arguments there is a domain error and the result is a > > percolating NaN. > > > > I worked around the problem by putting the standard function in a > > wrapper: > > > > double xpow(double b, double x) > > { > > double p; > > > > if(b < 0) > > { > > p = pow(-b, x); > > p *= -1.0; > > } > > else p = pow(b, x); > > > > return p; > > } > > > > Is there any particular reason for this limitation in the > > standard library function? Has anyone else had a problem with > > this and found a better solution? > > I don't know why the pow function is defined this way and there is > little insight in the rationale. I obviously didn't give enough thought to that. Any negative number raised to a fractional power that is not the reciprocal of an odd number (1/3, 1/5, 1/7, etc) will have a complex result. C99 provides support for complex numbers and you can perform such calculations with the cpow family of functions. > You can obtain the expected result of > pow(-11.5, .333) by using the cube root function from C99 if your > implementation provide it: cbrt(-11.5);. Robert Gamble |

Re: computing t = pow(-11.5, .333)John Smith wrote:
> > In a C program I need to do exponentiation where the base is > negative and the exponent is a fraction. In standard C this would > be something like t = pow(-11.5, .333), but with this combination > of arguments there is a domain error and the result is a > percolating NaN. > > I worked around the problem by putting the standard function in a > wrapper: > > double xpow(double b, double x) > { > double p; > > if(b < 0) > { > p = pow(-b, x); > p *= -1.0; > } > else p = pow(b, x); > > return p; > } > > Is there any particular reason for this limitation in the > standard library function? Has anyone else had a problem with > this and found a better solution? Yes. What you are doing has no meaning. You are actually returning -(b**x) instead of (-b)**x, where I am using ** to represent exponentiation. What is the real problem? Consider: what is the square root of -1/2? There is no answer in the real plane. You need complex variables for this. Yet this is just the value of (-0.5)**0.5. -- "If you want to post a followup via groups.google.com, don't use the broken "Reply" link at the bottom of the article. Click on "show options" at the top of the article, then click on the "Reply" at the bottom of the article headers." - Keith Thompson More details at: <http://cfaj.freeshell.org/google/> Also see <http://www.safalra.com/special/googlegroupsreply/> |

Re: computing t = pow(-11.5, .333)John Smith wrote:
> In a C program I need to do exponentiation where the base is negative > and the exponent is a fraction. In standard C this would be something > like t = pow(-11.5, .333), but with this combination of arguments there > is a domain error and the result is a percolating NaN. > > I worked around the problem by putting the standard function in a wrapper: > > double xpow(double b, double x) > { > double p; > > if(b < 0) > { > p = pow(-b, x); > p *= -1.0; > } > else p = pow(b, x); > > return p; > } > > Is there any particular reason for this limitation in the standard > library function? Has anyone else had a problem with this and found a > better solution? The reason for the limitation is mathematical: The proper result of pow(-1,1.5) is -i, where i is the square root of -1. That imaginary value is not in the range of double, so the pow function cannot return it. You define xpow(-1,1.5) as -pow(1,1.5), or -1. C allows you to do so, but notice that you've now violated the usual laws of exponents: pow(x,a) * pow(x,b) == pow(x, a+b) /* mathematically */ so pow(-1,1.5) * pow(-1,1.5) == pow(-1,3.0) == -1 but xpow(-1,1.5) * xpow(-1,1.5) == -pow(1,1.5) * -pow(1,1.5) == -1 * -1 == 1 If you're happy with this state of affairs, go ahead and be happy -- but don't ask the rest of the world to join in your rejoicing. -- Eric Sosman esosman@acm-dot-org.invalid |

Re: computing t = pow(-11.5, .333)In article <xd9ag.165458$7a.11533@pd7tw1no>,
John Smith <JSmith@mail.net> wrote: > In a C program I need to do exponentiation where the base is > negative and the exponent is a fraction. In standard C this would > be something like t = pow(-11.5, .333), but with this combination > of arguments there is a domain error and the result is a > percolating NaN. > > I worked around the problem by putting the standard function in a > wrapper: > > double xpow(double b, double x) > { > double p; > > if(b < 0) > { > p = pow(-b, x); > p *= -1.0; > } > else p = pow(b, x); > > return p; > } > > Is there any particular reason for this limitation in the > standard library function? Has anyone else had a problem with > this and found a better solution? You might try something more along the lines of: double root(double b, int x) { if(b < 0 && !(x & 1)) return 0./0.; if (b < 0) return -pow(-b, 1./x); return pow(b, 1./x); } This will give you correct results for both: root(-11.5, 3); root(-11.5, 2); root( 11.5, 2); root( 11.5, 3); -Howard |

Re: computing t = pow(-11.5, .333)In article <xd9ag.165458$7a.11533@pd7tw1no> John Smith <JSmith@mail.net> writes:
> In a C program I need to do exponentiation where the base is > negative and the exponent is a fraction. In standard C this would > be something like t = pow(-11.5, .333), but with this combination > of arguments there is a domain error and the result is a > percolating NaN. Rightly so. > I worked around the problem by putting the standard function in a > wrapper: > double xpow(double b, double x) > { > double p; > > if(b < 0) > { > p = pow(-b, x); > p *= -1.0; > } > else p = pow(b, x); > > return p; > } What is xpow(-1, 2) with your function? Does it divert from reality? Or (talking about fractions) what about xpow(-1, 0.5)? > Is there any particular reason for this limitation in the > standard library function? Yes, there is a pretty good reason. When the 'b' argument is negative there may not even be a solution within the reals when the 'x' argument is a fraction. -- dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131 home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/ |

Re: computing t = pow(-11.5, .333)On 2006-05-16, Robert Gamble <rgamble99@gmail.com> wrote:
> Robert Gamble wrote: >> John Smith wrote: >> > In a C program I need to do exponentiation where the base is >> > negative and the exponent is a fraction. In standard C this would >> > be something like t = pow(-11.5, .333), but with this combination >> > of arguments there is a domain error and the result is a >> > percolating NaN. >> > >> > I worked around the problem by putting the standard function in a >> > wrapper: >> > >> > double xpow(double b, double x) >> > { >> > double p; >> > >> > if(b < 0) >> > { >> > p = pow(-b, x); >> > p *= -1.0; >> > } >> > else p = pow(b, x); >> > >> > return p; >> > } >> > >> > Is there any particular reason for this limitation in the >> > standard library function? Has anyone else had a problem with >> > this and found a better solution? >> >> I don't know why the pow function is defined this way and there is >> little insight in the rationale. > > I obviously didn't give enough thought to that. Any negative number > raised to a fractional power that is not the reciprocal of an odd > number (1/3, 1/5, 1/7, etc) will have a complex result. Or with such reciprocals - I believe that, traditionally, raising a negative number to the fractional power yields the root with the lowest [counterclockwise] angle on the complex plane from the positive real axis - which is going to be less than pi (the angle for negative numbers), while the nth-root operator yields the negative real root. > C99 provides > support for complex numbers and you can perform such calculations with > the cpow family of functions. > >> You can obtain the expected result of >> pow(-11.5, .333) by using the cube root function from C99 if your >> implementation provide it: cbrt(-11.5);. > > Robert Gamble > |

Re: computing t = pow(-11.5, .333)John Smith wrote:
> In a C program I need to do exponentiation where the base is negative > and the exponent is a fraction. In standard C this would be something > like t = pow(-11.5, .333), but with this combination of arguments there > is a domain error and the result is a percolating NaN. > > I worked around the problem by putting the standard function in a wrapper: > > double xpow(double b, double x) > { > double p; > > if(b < 0) > { > p = pow(-b, x); > p *= -1.0; > } > else p = pow(b, x); > > return p; > } > > Is there any particular reason for this limitation in the standard > library function? Has anyone else had a problem with this and found a > better solution? > > JS To understand this you must look under the hood. The power function with an exponent specified as a decimal fraction almost certainly will do this: pow(a,b) = exp(b*ln(a)); since the ordinary (real) logarithm of a negative number is undefined in many implementations it will return NaN. I myself would make it abort immediately with an error message such as "Can't take logarithm of negative number!" (and I have done just that in floating point libraries I have written) but de gustibus non est disputandum, and others doubtless had good reasons for going the NaN route. Although I have not looked into <math.h> for the details, I would not be surprised to find that in many C implementations pow can tell whether the exponent b is a floating point number or a positive (or negative) integer smaller in magnitude than some value N, for which a^b = a*...*a (computed via the minimal-multiplication algorithm) is faster than computing two transcendental functions. That is, I would expect a properly written pow function to compute pow(a,2) = a*a; pow(a,-2) = 1/(a*a); whereas pow(a,2.0) = exp(2.0*ln(a)); -- Julian V. Noble Professor Emeritus of Physics University of Virginia |

All times are GMT. The time now is 04:26 AM. |

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.

SEO by vBSEO ©2010, Crawlability, Inc.