With monday.comâ€™s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

Running Windows XP Home, VC 6 SP5

Why do both of these code fragments display "-1.#IND00, 33"?

errno = 0;

double c = 1.0 / pow (-27.0, 1.0 / 3.0);

printf ("%f, %d\r\n", c, errno);

errno = 0;

double d = pow (-27.0, -1.0 / 3.0);

printf ("%f, %d\r\n", d, errno);

If errno == 33, that means "EDOM" or "Math argument." (according to MSDN)

Is this the way pow is supposed to work? It seems to me that 1 / ((-27)^(1/3)) = -1/3. What am I missing?

Why do both of these code fragments display "-1.#IND00, 33"?

errno = 0;

double c = 1.0 / pow (-27.0, 1.0 / 3.0);

printf ("%f, %d\r\n", c, errno);

errno = 0;

double d = pow (-27.0, -1.0 / 3.0);

printf ("%f, %d\r\n", d, errno);

If errno == 33, that means "EDOM" or "Math argument." (according to MSDN)

Is this the way pow is supposed to work? It seems to me that 1 / ((-27)^(1/3)) = -1/3. What am I missing?

MSDN says that pow return INF if y (second parameter) is less than 0.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_CRT_pow.asp

pow returns INF if the second parameter is less than 0 AND the first parameter is equal to 0: "[if] x = 0.0 and y < 0 [then result is] INF"

Furthermore, if the following code is executed:

errno = 0;

double a = pow (4.0, -1.0 / 2.0);

printf ("%f, %d\r\n", a, errno);

you get the expected value of .5..., even though the second parameter is less than 0.

An exception also will occur if (a <= 0.0) and b is not equal to a whole number.

I guess what I am looking for is some authoritative website that says "yes, this is the way ANSI C defines pow (that is, pow need not handle these kinds of calculations)" or "no, ANSI C says pow should work in this case and it should return -.33333". If pow should work in this case, but isn't, then it's Microsoft's problem and I will have to come up with a workaround. If pow isn't supposed to work in this case, then at least it's not Microsoft's problem, but I'll still have to come up with a workaround.

>> Their description for java's Math.pow adds:

>> An exception also will occur if (a <= 0.0) and b is not equal to a whole number.

Since this is C++, I don't think the documentation for the Java equivalent is very relavent :)

ilikenine, powf produces the same exact results.

Now, in the one case you presented, pow(-27,1/3), we can easily say -3, since -3**3 is -27, just as we could for any kth odd root of any negative integer that's the kth power of some other integer.

But how would we express pow(-16,1/4) if not undefined without introducing some new data type akin to imaginary?

As to the comparison with Java, I would argue that, in this case, it is legitimate. This question does not deal with the implementation of iterations, conditionals, or other syntactic features that are naturally specific to any given language. Rather, this case deals with the definition of a well understood mathematical function, the invalid arguments of which I have found to be fully documented everywhere else I looked.

In any case, this, alas, is far from the only case of incomplete documentation from MS.

As to its' implementation, I don't know how MS does it in their current library, but it has been quite common over the decades to simplify library implementations by internally implementing as many functions as possible as some combination of calls to other functions. Presuming negligable performance degradation (i.e., speed, precision, or accuracy), this improves maintainability.

Historical side note of questionable interest: Some flavors of FORTRAN implemented IMAGINARY 30 years ago.

All Courses

From novice to tech pro — start learning today.

--==--=-=-=-=-=-=-=-=-=-=-

Computes (ST(1) ∗ log2 (ST(0))), stores the result in resister ST(1), and pops the FPU register stack. The source operand in ST(0) must be a non-zero positive number.

--==--=-=-=-=-=-=-=-=-=-=-

In the Microsoft library implementatiion, if pushes the 1/3 onto the stack, then pushed the -27 onto the stack, then it checks the high bit of -27 and thereby determines that it is a negative number. So it never actually executes the FYL2X opcode -- it jumps right into the error handler.

Although Intel is not the final arbitrator of what is valid and what is not valid, I think that there may have been at least one lowly Intel technician who went to the trouble of looking up the EEE spec before commiting the 80x87 FPU to silicon.

Finally, some people might blame Microsoft for implementing the pow() fn by following the Intel documentation, but you should not find me to be numbered among them.

-- Dan