negation operator !

J

jimmij

Question about c++ standard:
On which types negation operator (!) can act?
In particular can it act on double variables?

// Is the bellow code 'standard c++' or not?
#include <iostream>

using namespace std;

int main()
{
double x=4.8;
if(!x) cout<<x<<endl;

return 0;
}
 
J

John Carson

jimmij said:
Question about c++ standard:
On which types negation operator (!) can act?
In particular can it act on double variables?

// Is the bellow code 'standard c++' or not?
#include <iostream>

using namespace std;

int main()
{
double x=4.8;
if(!x) cout<<x<<endl;

return 0;
}


! operates on boolean variables. However, by Section 3.9.1/8 of the
Standard,

"Integral and floating types are collectively called arithmetic types".

and by Section 4.12 of the Standard,

"An rvalue of arithmetic, enumeration, pointer, or pointer to member type
can be converted to an rvalue of type bool. A zero value, null pointer
value, or null member pointer value is converted to false; any other value
is converted to true."

Thus a double is convertable to bool and so if(!x) is legal.
 
I

Ivan Novick

John said:
Thus a double is convertable to bool and so if(!x) is legal.
However, is it not possible that your double variable could easily
contain some value such as .00000000001 and that !x would return false.
I think it is generally unsafe to do exact compares on floating point
variables. Even this if (x == 5)
 
J

John Carson

Ivan Novick said:
However, is it not possible that your double variable could easily
contain some value such as .00000000001 and that !x would return
false.

With 16 bit doubles, .00000000001 is non-zero so converts to true, which
means that the negation of it converts to false. No surprises there.

However, if you run this code:

#include <iostream>
using namespace std;

int main()
{
double x = .00000000001;
while(x)
{
x *= x;
cout << "x is " << x << endl;
if(!x)
cout << "!x evaluates to true\n";
else
cout << "!x evaluates to false\n";
}

return 0;
}

then eventually x becomes zero and !x becomes true because of the
limitations of the representation of a double. This is in spite of the fact
that, in terms of the mathematics of real numbers, squaring a non-zero
number always produces a non-zero result.

An example of the reverse sort of error is the following:

double a = 5.7987982749832, b = 3.27498327984;
double x = (a+b)*(a+b) - (a*a + 2*a*b + b*b);
cout << "x is " << x << endl;
if(!x)
cout << "!x evaluates to true\n";
else
cout << "!x evaluates to false\n";

Here x is zero in terms of the mathematics of real numbers, but (running on
Windows) evaluates to non-zero in terms of the arithmetic of doubles.
I think it is generally unsafe to do exact compares on
floating point variables. Even this if (x == 5)

Floating point representations are in general imprecise and hence
comparisons must be done with caution. Neither "exact compares" nor "inexact
compares" are guaranteed to give the right answer. However, either one may
be appropriate in particular situations.

None of this affects the legality of using a double in a situation that
calls for a bool.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top