Why does 'std::cout << !+2 ' output 0? - c++

This line of code outputs 0:
std::cout << !+2;
I think it should be 35, since '!' has an ASCII code of 33 and adding 2 to it equals 35.
Why is it like that?

Let's quickly analyze what your code !+2 does. The bare exclamation mark is the logical not operator which negates the truth value of its operand. Integers, such as +2 can be converted to boolean, where 0 means false and every non-zero integer true. That means that !+2 is converted to !true. The negation of true is obviously false, so !+2 is converted to false. When you pipe this boolean into std::cout is is converted to integer again, i.e. true turns into 1 and false turns into 0. That is why you std::cout << !+2; prints 0.
What you wanted to do instead (add 2 to the ASCII code of !) can be achieved as well. Therefore you have to tell the compiler that you want the character ! by enclosing it in single quotes. Then the code std::cout << ('!' + 2); will print 35, as expected. I added some extra parentheses to not rely purely on operator precedence.
#include <iostream>
int main() {
std::cout << ('!' + 2) << '\n';
}
Output:
35
Live on Wandbox

If you want to get the ASCII value of exclamation mark, you need to surround it with single quotes like following.
std::cout << '!' + 0;
What you did is negating a value (this value can be either True or False). Making the value (here integer) positive or negative does not matter (here you explicitly specify 2 as positive), because everything other than zero means True. So, if you do the same thing for zero like following, you would get 1 as output.
std::cout << !+0;

Related

How '<<' operator does work with #define in C++

I have two operation, and I am assuming both are doing ShiftLeft bitwise operation.
#define TACH_MAX_OWN_ORDERS 1<<6
int myVal = 1<<6
cout<<"Value after operation|"<<myVal <<"|"<<TACH_MAX_OWN_ORDERS<<endl;
output of TACH_MAX_OWN_ORDERS value always surprise me.
Value after operation|64|16
Do anyone have any clue, how it comes???
Thanks
Macros replace text as is, so it will result in
cout<<"Value after operation|"<<myVal <<"|"<<1<<6<<endl;
the << won't result in (int)1<<6 but rather ([...] << 1) << 6 where [...] will have std::cout at the deepest level. This means your macro will always result in 16 when used in std::cout, because 1 and 6 are shifted into the out stream ("1" + "6") instead of the actual numerical value 64.
You should put parantheses around the statement to avoid this:
#define TACH_MAX_OWN_ORDERS (1<<6)
or even better, since you should avoid macros, if available try to use compile time constants:
constexpr int TACH_MAX_OWN_ORDERS = 1 << 6;

Operator !! producing unexpected result

I have a problem relative to some C++ code about the !! operator. It gives me an unexpected result and I don't understand why:
int x=-12;
x=!!x;
print("value=",x);
The output of this is 1. But i do not know how. Can anyone explain this ambiguous result?
!!x is grouped as !(!x).
!x is 0 if x is non-zero, and 1 if x is zero.
Applying ! to that reverses the result.
So, !!x can be viewed as a way of setting x to 1 if it's not zero, and remaining at 0 if it's zero. In other words x = !!x is the same as x = x ? 1 : 0.
... !(-12) kindly explain this expression.
It's "logical not of -12". In C++ numeric value 0 is false in logical way, and any non-zero value is true in logical way. This is how C and C++ evaluates numerical values in boolean context, like if (expression) ..., i.e. if (-12) exit(1); will exit your application, because -12 is "true".
When you typecast numeric value to bool type and then back to int, the true will become value 1, but most of the time you can avoid these conversions and use intermediate results of numerical calculations directly, where any non-zero value is "true".
So "not of true" is value false. I.e. !(-12) == false. And !false == true. And you convert the logical value "true" back to int, which will make x == 1.
The !!(numeric_value) is idiomatic way in C++ (and in C too) to "normalize" any numeric value into precisely 0 or 1 (and you may encounter it in source code of many applications).
The "logical" distinction is important, because C++ has also binary operators, where the calculation is working per individual bits, not with value as whole. In "binary" way the "!" operator sibling is ~. Similar example to yours with bit-complement operator x=~~x; would then result into original value -12, because every bit of x is flipped twice, ending with same value as it did start. So ~~x is not something to encounter in regular source, as it's basically "no operation" (contrary to !! which is "no operation" only if the original value was already 0 or 1).
Also this is sometimes source of bugs for people learning the language, as they forget about the distinction and write something like
if (4 & 2) { /* this is "and" so it should be true??? */ }
// it will be false, because in binary way 4&2 == 0
if (4 && 2) { /* this is logical "and" and will be "true" */ }
// because 4 is non-zero, 2 is non-zero, and "true and true" is "true"
I.e. binary operators are & | ~ ^ (and, or, not, xor), and their logical siblings are && || ! for "and, or, not", the logical "xor" doesn't have operator in C++.

Char Subtraction in c++

I am fairly new to C++ and i have some trouble in understanding character subtraction in c++.
I had this code intially
char x='2';
x-='0';
if(x) cout << "More than Zero" << endl;
This returned More than Zero as output so to know the value of x i tried this code.
char x='2';
x-='0';
if(x) cout << x << endl;
And i am getting null character(or new line) as output.
Any help is appreciated.
According to the C++ Standard (2.3 Character sets)
...In both the source and execution basic character sets, the value of
each character after 0 in the above list of decimal digits shall be
one greater than the value of the previous.
So the codes of adjacent digits in any character set differ by 1.
Thus in this code snippet
char x='2';
x-='0';
if(x) cout << x << endl;
the difference between '2' and '0' (the difference between codes that represent these characters; for example in ASCII these codes are 0x32 and 0x30 while in EBCDIC they are 0xF2 and 0xF0 correspondingly) is equal to 2.
You can check this for example the following way
if(x) cout << ( int )x << endl;
or
if(x) cout << static_cast<int>( x ) << endl;
If you just write
if(x) cout << x << endl;
then the operator << tries to output x as a printable character image of the value 2 because x is of type char.
In C/C++ characters are stored as 8-bit integers with ASCII encoding. So when you do x-='0'; you're subtracting the ASCII value of '0' which is 48 from the ASCII value of '2' which is 50. x is then equal to 2 which is a special control character stating STX (start of text), which is not printable.
If you want to perform arithmetic on characters it's better to subtract '0' from every character before any operation and adding '0' to the result. To avoid problems like running over the range of the 8bit value I'd suggest to cast them on ints or longs.
char x = '2';
int tempVal = x - '0';
/*
Some operations are performed here
*/
x = tempValue % 10 + '0';
// % 10 - in case it excedes the range reserved for numbers in ASCII
cout << x << endl;
It's much safer to perform these operations on larger value types, and subtracting the '0' character allows you to perform operations independent on the ASCII encoding like you'd do with casual integers. Then you add '0' to go back to the ASCII encoding, which alows you to print a number.
You are substracting 48 (ascii char '0') to the character 50 (ascii '2')
50 - 48 = 2
if (x) ' true
In C++, characters are all represented by an ASCII code (see http://www.asciitable.com/)
I guess that doing :
'2' - '0'
is like doing
50 - 48 = 2
According to the ASCII table, the ASCII code 2 stands for start of text, which is not displayed by cout.
Hope it helps.
So what your code is doing is the following:
x = '2', which represents 50 as a decimal value in the ASCII table.
then your are basically saying:
x = x - '0', where zero in the ASCII table is represented as 48 in decimal, which equates to x = 50 - 48 = 2.
Note that 2 != '2' . If you look up 2(decimal) in the ASCII table that will give you a STX (start of text). This is what your code is doing. So keep in mind that the subtraction is taking place on the decimal value of the char.

Distinguishing between numbers and other symbols [c++]

I'm reading a text file and extracting pieces of information of it by means of parsing (line by line).
Here is an example of the text file:
0 1.1 9 -4
a #!b .c. f/
a4 5.2s sa4.4 -2lp
So far, I'm able to split each line using empty spaces ' ' as separators. So I can save, for example, the value of "1.1" into a string variable.
What I want to do (and here is where I'm stuck) is to determine if the piece of information that I'm reading represents a number. Using the previous example, these strings do not represent numbers: a #!b .c. f/ a4 5.2s sa4.4 -2lp
Alternatively, these strings do represent numbers: 0 1.1 9 -4
Then I would like store the strings that represent numbers into a double type variable (I know how to do the conversion to double part).
So, How can I distinguishing between numbers and other symbols? I'm using c++.
You can do this:
// check for integer
std::string s = "42";
int i;
if(!s.empty() && (std::istringstream(s) >> i).eof())
{
// number is an integer
std::cout << "i = " << i << '\n';
}
// check for real
s = "4.2";
double d;
if(!s.empty() && (std::istringstream(s) >> d).eof())
{
// number is real (floating point)
std::cout << "d = " << d << '\n';
}
The eof() check makes sure that the number is not followed by non numeric characters.
Assuming a current (C++11) compiler, the easiest way to handle this is probably to do the conversion using std::stod. You can pass this the address of a size_t that indicates the location of the first character that could not be used in the conversion to double. If the entire input converted to double, it will be the end of the string. If it's any other value, at least part of the input didn't convert.
size_t pos;
double value = std::stod(input, &pos);
if (pos == input.length())
// the input was numeric
else
// at least part of the input couldn't be converted.

determining True/False

the following code
#include <iostream>
using namespace std;
int main(){
char greeting[50] = "goodmorning everyone";
char *s1 = greeting;
char *s2 = &greeting[7];
bool test = s2-s1;
cout << "s1 is: " << s1 << endl;
cout << "s2 is: " << s2 << endl;
if (test == true ){
cout << "test is true and is: " << test << endl;
}
if (test == false){
cout<< "test is false and is: " << test << endl;
}
return 0;
}
outputs:
s1 is: goodmorning everyone
s2 is: ning everyone
test is true and is: 1
here what does the line bool test = s2-s1; actually evaluate?, is it the length of the string?. If so, then seeing as s2 is a smaller than s1 it should be negative correct?, and yet the output is true?.
Also if i change it to bool test = s1-s2; I still end up with the same result. So it doesnt matter whether its negative or positive the it will be true? and only false when 0?.
what does the s2-s1 mean?
-cheers (trying to get rid of doubts:))
If the result of the subtraction is zero, test will be false; otherwise it will be true.
Any value that is of a numeric type, enumeration type, or is a pointer can be converted to a boolean; if the value is zero (or null, for pointers), the result is false; otherwise the result is true.
Integer types, floating point types, and pointer types are all convertable to bool. For all of them, a value of 0 converts to false, and a non-zero value converts to true.
So, if s2 - s1 evaluates to 0, then test is false. Otherwise, test is true.
Since s1 and s2 are pointers, s2 - s1 is giving the difference between them (how far apart the addresses are). If they point to the same address, then the difference will be 0. If they point to different addresses, then the result will be non-zero. So, really all test indicates is whether s1 and s2 point to different addresses. s1 != s2 would give exactly the same result and would probably make more sense.
However, given that the values for s1 and s2 are hard-coded and are guaranteed to point to different addresses, the test doesn't really make any sense. It could make sense in another program though - particularly one where s1 and s2 are being passed into a function and you have no way of knowing ahead of time whether they're really the same.
The line bool test = s2-s1 does pointer subtraction, giving the number of chars separating s2 from s1. This result is then converted to a bool by converting to false if and only if the result is 0, otherwise converting to true.
For a detailed description of what's going on when you add/subtract pointers, see:
http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/BitOp/pointer.html
C++ allows implicit conversions, so what it is doing is subtracting the pointer values of one array from another and if the result is null, then it is implicitly casting null to false. Anything else will be true, as bools work such that it's either zero (false) or true.
Thanks to Nathan S. and indiv for correcting me.