|
From: | Daniel J Sebald |
Subject: | Re: signbit and logical tests |
Date: | Sat, 16 Feb 2013 00:30:36 -0600 |
User-agent: | Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111108 Fedora/3.1.16-1.fc14 Thunderbird/3.1.16 |
On 02/15/2013 11:42 PM, Michael D. Godfrey wrote:
On 02/10/2013 02:16 PM, Daniel J Sebald wrote:On 02/10/2013 12:54 PM, Daniel J Sebald wrote:On 02/10/2013 10:05 AM, Mike Miller wrote:On Sun, Feb 10, 2013 at 12:48 AM, Daniel J Sebald <address@hidden> wrote:On 02/09/2013 09:02 PM, Michael D. Godfrey wrote:This does not quite appear to be the case because this problem started with bug #38291 which showed that on at least one 32bit system (Ubuntu) the returned value for true is 512. That is why my test for == 1 failed.Just curious how that is coming about. Any guess? I would think that C defines a logical true as 1.The return value for signbit is defined as zero for false, non-zero for true. You can easily verify this with a C program: address@hidden:~/src$ cat signbit.c #include<math.h> #include<stdio.h> int main() { printf ("signbit(-12.0) = %d\n", signbit(-12.0)); } address@hidden:~/src$ gcc -m64 -o signbit signbit.c -lm; ./signbit signbit(-12.0) = 128 address@hidden:~/src$ gcc -m32 -o signbit signbit.c -lm; ./signbit signbit(-12.0) = -2147483648As usual, this is a bit more complex/confusing than first meets the eye. I see now it looks like C (not C++, but C) defined "signbit()" so that the compiler could generate adequate information about the sign bit with minimal amounts of assembly instructions. That is, whatever combination of shifting, register manipulations, etc. that is minimum is adequate. No need to make that signbit() result be 1 because more than likely, the programmer writing C code will do something like if (signbit(x)) { } So, if the compiler does some extra step to make signbit() 0 or 1, it's a bit like doing the same conditional test twice. Now, here is the monkey wrench. There is a standard C++ (not C, but C++) library function std:signbit which DOES produce a logical 0 or 1. Observe: address@hidden cat signbit.c #include <math.h> #include <stdio.h> int main() { printf ("signbit(-12.0) = %d\n", signbit(-12.0)); } [1]+ Done gvim signbit.c address@hidden gcc -m64 -o signbit signbit.c address@hidden ./signbit signbit(-12.0) = 128 address@hidden cat signbit.c /*#include <math.h>*/ #include <stdio.h> int main() { printf ("signbit(-12.0) = %d\n", signbit(-12.0)); } address@hidden gcc -m64 -o signbit signbit.c address@hidden ./signbit signbit(-12.0) = 1Actually, I'm not sure what the second result is returning because the C++ signbit routine is defined in cmath.hpp which isn't being included. Perhaps without a definition the compiler is treating signbit() as some kind of generic function and then fills in global variable for the function call with whatever symbol "signbit" it can find in the intermediate object file??? DanI took a look at mappers.cc and it appears that if people can accept signbit() returning logical (0,1) then the attached patch will do it. Could it be this simple? Works for me. Michael
Yes, I think it is that simple. That is the one or two extra machine cycles I suggested. To illustrate, say the instruction you added is in place:
+ retval = retval != 0; }then upon returning from the function, the user (or C programmer) does something like
if (signbit(x) != 0) { z = x + y; }Then it's basically doing the same conditional test back-to-back and a waste of machine cycles. Granted there are optimizing compilers and such these days, but my guess is someone way back thought this through and realized by not making the requirement that the output be logical 1 or 0 can save a few cycles--and that is what the goal of C was initially, i.e., to be very efficient and not worry about boundary checking, etc. (I think Jordi used a term to describe this a while back, but I forget.)
Real-time processing minds (like me) love this kind of thinking: save 0.5% CPU, yes! However, I think for the user of Octave who doesn't think at such low level, to see a signbit output of 0 or (254, 1068, 40502, whatever else other than 0) just confuses the person. Saving signbit result to a datafile might look strange and possibly have different results on different machines. Sure the user could save or examine something like signbit(x) != 0, but he or she would first have to spend time realizing what the signbit is actually returning.
That's why I'm concluding in this case it might make sense to just let Octave signbit() have the extra test you propose. Forgo efficiency to avoid any confusion for the user.
There could be a variant, csignbit() for which signbit() = csignbit() != 0;which is the wrapper for the C function in case the user wants to see what the actual non-zero number is. But I can't conceive of why the general user would want to know the output of csignbit(). I think the user's expectation is the logical 0 or 1.
Dan
[Prev in Thread] | Current Thread | [Next in Thread] |