How '<<' operator does work with #define in C++ - 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;

Related

C++ while loop is not reading -1 from my file

I am writing a program that reads numbers from a .txt file and outputs a respective amount of asterisks (for even integers) and dollar signs (for odd integers). For example, a 3 would output $$$ and 2 would output **. The program works fine, except for when it reads the number -1. Other negative numbers work just fine, except for -1 for some reason..
Here is my code:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <Windows.h>
using namespace std;
int main()
{
int value, even, odd;
ifstream infile;
infile.open("lab6_input.txt");
while (infile >> value)
{
if (value % 2 == 0)
cout << string(abs(value), "*$"[value % 2]) << endl;
else
cout << string(abs(value), "*$"[value % 2]) << endl;
value++;
}
infile.close();
system("pause");
return 0;
}
Here is my output: https://imgur.com/a/favqrLv
The last number in the output is a -1, but it just displays an empty space.
Your code seems a bit odd. Your variables are not initialized, even and odd are not even used. Your if statement is unnecessary because you have in both cases the same code.
To your question:
You should use abs(value) twice.
Try
while(infile >> value){
cout << string(abs(value), "*$"[abs(value) % 2]) << endl;
value++;
}
Live example
The problem lies here
"*$"[value % 2]
In C++, the result of the modulo operator applied to a negative number is negative (well, technically is a bit more complicated than that). So, when value is negative, that instruction causes undefined behavior, accessing the array (string literal) out of bounds (the one at index -1).
You could solve the issue taking the absolute value of value or of the result, but consider writing a free function like the following, instead.
constexpr bool is_odd(int x)
{
return x % 2;
}
It will better express the intent and will help the compiler to optimize your code (see e.g. here), because it's like you are asking
Tell me if value is divisible by two (the remainder of its division by 2 is zero) or not.
Which is different from
Give me the remainder of the division of value by 2
You may have noted, in linked Compiler Explorer page, that the compilers end up using a simple
and edi, 1
Instead of performing an actual modulo operation. This is because what you really need is the less significant bit and you could directly use in your code
value & 1
Note, though, that the Standard (C++17, while I'm writing) doesn't mandates (yet, C++20 will require two's complement) a particular binary representation for type int, so the previous would be implementation defined (and wrong, if you happen to find a ones' complement still working int implementation).

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

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;

Fibonacci function doesn't calculate properly

I've defined this macro
#define FIB(n) (( 4 << n*(3+n))/((4 << (2*n)) - (2 << n) - 1))%(2 << n)
and when I try to get an answer, doesn't work properly, by example if I call FIB(7),it gives me 0, that clearly is wrong. I tested this function in python and it works perfectly. So, anyone can explain me why doesn't it work in C and C++?
4 << n*(3+n) becomes 4 << 7*(3+7) when replace n with 7.
It means 4 << 70. If the size of int is 32 bits or 64 bits, shifting 70 bits is too much and this invokes undefined behavior in C.
Python supports multiple-precision arithmetic, so it may work well.

Combining 2 Hex Values Into 1 Hex Value

I have a coordinate pair of values that each range from [0,15]. For now I can use an unsigned, however since 16 x 16 = 256 total possible coordinate locations, this also represents all the binary and hex values of 1 byte. So to keep memory compact I'm starting to prefer the idea of using a BYTE or an unsigned char. What I want to do with this coordinate pair is this:
Let's say we have a coordinate pair with the hex value [0x05,0x0C], I would like the final value to be 0x5C. I would also like to do the reverse as well, but I think I've already found an answer with a solution to the reverse. I was thinking on the lines of using & or | however, I'm missing something for I'm not getting the correct values.
However as I was typing this and looking at the reverse of this: this is what I came up with and it appears to be working.
byte a = 0x04;
byte b = 0x0C;
byte c = (a << 4) | b;
std::cout << +c;
And the value that is printing is 76; which converted to hex is 0x4C.
Since I have figured out the calculation for this, is there a more efficient way?
EDIT
After doing some testing the operation to combine the initial two is giving me the correct value, however when I'm doing the reverse operation as such:
byte example = c;
byte nibble1 = 0x0F & example;
byte nibble2 = (0xF0 & example) >> 4;
std::cout << +nibble1 << " " << +nibble2 << std::endl;
It is printout 12 4. Is this correct or should this be a concern? If worst comes to worst I can rename the values to indicate which coordinate value they are.
EDIT
After thinking about this for a little bit and from some of the suggestions I had to modify the reverse operation to this:
byte example = c;
byte nibble1 = (0xF0 & example) >> 4;
byte nibble2 = (0x0F & example);
std:cout << +nibble1 << " " << +nibble2 << std::endl;
And this prints out 4 12 which is the correct order of what I am looking for!
First of all, be careful about there are in fact 17 values in the range 0..16. Your values are probably 0..15, because if they actually range both from 0 to 16, you won't be able to uniquely store every possible coordinate pair into a single byte.
The code extract you submitted is pretty efficient, you are using bit operators, which are the quickest thing you can ask a processor to do.
For the "reverse" (splitting your byte into two 4-bit values), you are right when thinking about using &. Just apply a 4-bit shift at the right time.

C++: Big Integers

I am a writing a lexer as part of a compiler project and I need to detect if an integer is larger than what can fit in a int so I can print an error. Is there a C++ standard library for big integers that could fit this purpose?
The Standard C library functions for converting number strings to integers are supposed to detect numbers which are out of range, and set errno to ERANGE to indicate the problem. See here
You could probably use libgmp. However, I think for your purpose, it's just unnecessary.
If you, for example, parse your numbers to 32-bit unsigned int, you
parse the first at most 9 decimal numbers (that's floor(32*log(2)/log(10)). If you haven't more, the number is OK.
take the next digit. If the number you got / 10 is not equal to the number from the previous step, the number is bad.
if you have more digits (eg. more than 9+1), the number is bad.
else the number is good.
Be sure to skip any leading zeros etc.
libgmp is a general solution, though maybe a bit heavyweight.
For a lighter-weight lexical analyzer, you could treat it as a string; trim leading zeros, then if it's longer than 10 digits, it's too long; if shorter then it's OK, if exactly 10 digits, string compare to the max values 2^31=2147483648 or 2^32=4294967296. Keep in mind that -2^31 is a legal value but 2^31 isn't. Also keep in mind the syntax for octal and hexadecimal constants.
To everyone suggesting atoi:
My atoi() implementation does not set errno.
My atoi() implementation does not return INT_MIN or INT_MAX on overflow.
We cannot rely on sign reversal. Consider 0x4000...0.
*2 and the negative bit is set.
*4 and the value is zero.
With base-10 numbers our next digit would multiply this by 10.
This is all nuts. Unless your lexer is parsing gigs of numerical data, stop the premature optimization already. It only leads to grief.
This approach may be inefficient, but it's adequate for your needs:
const char * p = "1234567890123";
int i = atoi( p );
ostringstream o;
o << i;
return o.str() == p;
Or, leveraging the stack:
const char * p = "1234567890123";
int i = atoi( p );
char buffer [ 12 ];
snprintf( buffer, 12, "%d", i );
return strcmp(buffer,p) == 0;
How about this. Use atol, and check for overflow and underflow.
#include <iostream>
#include <string>
using namespace std;
main()
{
string str;
cin >> str;
int i = atol(str.c_str());
if (i == INT_MIN && str != "-2147483648") {
cout << "Underflow" << endl;
} else if (i == INT_MAX && str != "2147483647") {
cout << "Overflow" << endl;
} else {
cout << "In range" << endl;
}
}
You might want to check out GMP if you want to be able to deal with such numbers.
In your lexer as you parse the integer string you must multiply by 10 before you add each new digit (assuming you're parsing from left to right). If that running total suddenly becomes negative, you've exceeded the precision of the integer.
If your language (like C) supports compile-time evaluation of expressions, then you might need to think about that, too.
Stuff like this:
#define N 2147483643 // This is 2^31-5, i.e. close to the limit.
int toobig = N + N;
GCC will catch this, saying "warning: integer overflow in expression", but of course no individual literal is overflowing. This might be more than you require, just thought I'd point it out as stuff that real compilers to in this department.
You can check to see if the number is higher or lower than INT_MAX or INT_MIN respectively. You would need to #include <limits.h>