int temp1,temp2,temp3;
temp1 = 199;
temp2 = 200;
temp3 = 199%temp2;
CString txt;
txt.Format(_T("temp3 = %d"),temp3);
AfxMessageBox(txt);
Output is 199 as expected.
#define WIDTH 100
#define BUFFERWIDTH 200
int temp1,temp2,temp3;
temp1 = 199;
temp2 = BUFFERWIDTH;
temp3 = 199%BUFFERWIDTH;
CString txt;
txt.Format(_T("temp3 = %d"),temp3);
AfxMessageBox(txt);
Output is 199 as expected.
#define WIDTH 100
#define BUFFERWIDTH 2*WIDTH
int temp1,temp2,temp3;
temp1 = 199;
temp2 = BUFFERWIDTH;
temp3 = 199%BUFFERWIDTH;
CString txt;
txt.Format(_T("temp3 = %d"),temp3);
AfxMessageBox(txt);
Output is 100...
Just wondering what is causing this :)
Read up about operator precedence, and note that you are saying 199 % 2 * 100.
.
.
.
or should I say, (199 % 2) * 100...
This is a classic problem with the preprocessor. The issue is that when you write
#define BUFFERWIDTH 2*WIDTH
temp3 = 199%BUFFERWIDTH;
The preprocessor expands this out to
#define BUFFERWIDTH 2*WIDTH
temp3 = 199 % 2 * WIDTH;
Notice that this is interpreted as
temp3 = (199 % 2) * WIDTH;
instead of the intended
temp3 = 199 % (2 * WIDTH);
To fix this, you have multiple options. First, you could parenthesize your definition of BUFFERWIDTH like this:
#define BUFFERWIDTH (2*WIDTH)
temp3 = 199%BUFFERWIDTH;
Now, this expands out to
temp3 = 199 % (2 * WIDTH);
as expected. However, a better option would be to use const to define your constants:
const int BUFFERWIDTH = 2 * WIDTH;
temp3 = 199%BUFFERWIDTH;
This is now interpreted correctly, because constants are understood by the compiler rather than the preprocessor.
More generally, I strongly urge you not to use #define to define constants. #define is essentially a search-and-replace mechanism over the source code that has no semantic or syntactic understanding of what it replaces. It doesn't play well with operator precedence, and so you can easily run into bugs like this. const, on the other hand, is understood by the compiler to define a constant, and so expressions will be evaluated correctly when operator precedence comes into play.
Hope this helps!
One of the most common pitfalls when using MACROS is not realizing that MACROS are code replacement units. So, your code:
#define BUFFERWIDTH 2*WIDTH
// ...
temp3 = 199%BUFFERWIDTH;
After preprocessing converts to:
temp3 = 199%2*100;
If you apply operator precedence, you get the number you showed.
In the last case,
temp3 = 199%BUFFERWIDTH;
becomes
temp3 = 199%2*WIDTH
which is
temp3 = 199%2*100
so
temp3 = (199%2) * 100
which means
temp3 = 100.
Rewrite it:
#define BUFFERWIDTH (2*WIDTH)
In your last example, 199%BUFFERWIDTH expands to 199 % 2 * 100 which evaluates to 100.
The preprocessor transforms this to 199*2%200.
Since * has a higher precedence than %, this is parsed as (199 * 2) % 200.
This is one of the many reasons where non-trivial #DEFINEs are evil.
In this particular case, you can fix it with parentheses:
#define BUFFERWIDTH (2*WIDTH)
You fallen into the Operator Precedence Macro Trap:
temp3 = 199%BUFFERWIDTH;
Becomes:
temp3 = 199%2*WIDTH;
Which becomes:
temp3 = 199%2*100;
Since % and * have equal precedence they are evaluated left to right and you get temp3 = 1*100;
This line:
temp3 = 199%BUFFERWIDTH;
resolves to
temp3 = 199%2*WIDTH;
which is not what you want. Enclose 2*WIDTH in parentheses, and you get the desired result:
#define BUFFERWIDTH (2*WIDTH)
Whilst macros as considered evil, but there are instances where they cannot be avoided at all, and ease if programming a lot. All macros should be fully parenthesized no matter how small:
#define BUFFERWIDTH ( 2 * (WIDTH) )
Which would adapt any changes you make to WIDTH later:
#define WITDH (10+12*55)
Related
I have some code that I wrote up that will successfully return me a binary number. For example, running the code below with an input of 101 will return 5. However, the problem arises when I add 0 bits to the left of MSB, thus not changing the value. When I input 0101 into the system, I should expect 5 to be returned again, but it returns 17 instead.
Here is my code:
int dec1 = 0, rem1=0, num1, base1 = 1;
int a = 101;
while (a > 0){
rem1 = a % 10;
dec1 = dec1 + (rem1 * base1);
base1 = base1 * 2;
a = a / 10;
}
cout << dec1 << endl;
The output of this is 5. Correct.
However, when 'a' is changed to 0101, the output becomes 17. I believe my error has to do with a misunderstanding of the modulo operator.
101%10 = 1 right? Does the compiler typically read 0101%10 the same way?
I added a cout statement to my code to see what value is stored in rem1 after the value of 0101%10 is calculated.
int dec1 = 0, rem1=0, num1, base1 = 1;
int a = 101;
while (a > 0){
rem1 = a % 10;
cout << rem1 << endl;
dec1 = dec1 + (rem1 * base1);
base1 = base1 * 2;
a = a / 10;
}
cout << dec1 << endl;
From this, I was able to see that right after 0101%10 is calculated, a value of 5 is stored in rem1, instead of 1.
Does adding this 0 in front of the MSB tell the compiler "hey, this number is in binary?" because if the compiler is reading 5%10 instead of 0101%10, then I guess the error makes sense.
Upon testing my theory, I changed 'a' to 1000 and the output was 8, which is correct.
Changing 'a' to 01000 gives a result of 24. rem1= 01000%10 should be 0, however rem1 is storing 2. 01000 binary = 8 decimal. 8%10=8? not 2?
I'm an unsure of what is going on and any help is appreciated!
101 is parsed as a decimal (base 10) number, so you get your expected output.
0101 is parsed as an octal (base 8) number due to the leading zero. The leading zero here works just like the leading 0x prefix that denotes a hexadecimal (base 16) number, except that without the x it's base 8 instead of base 16.†
1018 = 82 + 80 = 64 + 1 = 65
65 % 10 = 5
65 / 10 = 6
6 % 10 = 7
5 * 2 + 7 = 17
If I were you, I'd add an assert(rem1 == 0 || rem1 == 1) inside your loop right after your assignment to rem1 as a sanity check. If you ever get a remainder larger than one or less than zero then there's obviously something wrong.
As rbaleksandar points out in his comment above, the easiest way to avoid this issue is probably to store your input as a c-string (char[]) rather than using an integer literal. This is also nice because you can just iterate over the characters to compute the value instead of doing % and / operations.
Alternatively, you could use hex literals (e.g., 0x101 or 0x0101) for all of your inputs, and change your math to use base 16 instead of base 10. This has the added advantage that base 10 division and remainder functions can be optimized by the compiler into much cheaper bit-shift and bit-mask operations since 16 is a power of 2. (E.g., 0x101 % 16 ==> 0x101 & 15, and 0x101 / 16 ==> 0x101 >> 4).
† For more info
see http://en.cppreference.com/w/cpp/language/integer_literal
0101 is Octal number, which value is 17.
This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 6 years ago.
Why this code give to me value "4" instead of "0"?
#define PLUGIN_PPQ 96
#define MIDIENGINE_SCORE_LENGTH PLUGIN_PPQ * 4
int main ()
{
int mCurrentPatternPulse = 97;
int patternBar = (int)floor(mCurrentPatternPulse / MIDIENGINE_SCORE_LENGTH);
cout << "value: " << patternBar << " (" << MIDIENGINE_SCORE_LENGTH << ")";
}
97/384 (with/without floor) should give to me 0.
But it seems it divides by 96 instead of 384? Even if I print MIDIENGINE_SCORE_LENGTH is 384...
If you unpick the macro, then you get
floor(mCurrentPatternPulse / PLUGIN_PPQ * 4);
Since / and * have the same precedence, evaluation is from left to right, so the expression is equivalent to
floor((mCurrentPatternPulse / PLUGIN_PPQ) * 4)
Note that (mCurrentPatternPulse / PLUGIN_PPQ) is performed in integer arithmetic, so any remainder is discarded prior to the multiplication.
Imagine it being a "string-replace" and not a math operation.
So MIDIENGINE_SCORE_LENGTHis not 384 but 96 *4
so your code looks like:
floor(mCurrentPatternPulse / 96 *4 );
and the mCurrentPatternPulse / 96 will be evaluated first.
Just add some brackets:
floor(mCurrentPatternPulse / ( MIDIENGINE_SCORE_LENGTH ) );
Edit:
Or even better put them in the define directly:
#define MIDIENGINE_SCORE_LENGTH ( PLUGIN_PPQ * 4 )
#defines are just text substitution. You need to look up operator precedence.
I was playing around with C++ today and this is what I found after doing some tests:
#include <iostream>
using namespace std;
int main()
{
int myInt = 100;
int myInt2 = myInt + (0.5 * 17); // the math inside the parentheses should go first
int difference = myInt2 - myInt; // get the difference of the two numbers
cout << difference << endl; // difference is 8
}
the output is 8
#include <iostream>
using namespace std;
int main()
{
int myInt = 100;
int myInt2 = myInt - (0.5 * 17); // the math inside the parentheses should still go first
int difference = myInt - myInt2; // get the difference of the two numbers
cout << difference << endl; // difference is 9?
}
The output is 9?
So according to my first code sample, 0.5 * 17 = 8, but according to my second code sample, 0.5 * 17 = 9. I am aware that I would get the same results without the parentheses, but I am using them to help illustrate what I am doing in my code.
To help narrow down the problem, I tried this:
#include <iostream>
using namespace std;
int main()
{
int myInt = 100;
int myInt2 = 0.5 * 17; // use a variable instead of parentheses
int myInt3 = myInt + myInt2;
int difference = myInt3 - myInt; // get the difference of the two numbers
cout << difference << endl; // difference is 8
}
the output is 8
#include <iostream>
using namespace std;
int main()
{
int myInt = 100;
int myInt2 = 0.5 * 17; // continue using a variable
int myInt3 = myInt - myInt2;
int difference = myInt - myInt3; // get the difference of the two numbers
cout << difference << endl; // difference is 8 again!
}
the output is 8 again!
So my question is, if the math in the parentheses always comes first, then why am I getting different results? Shouldn't the first two trials have the same results as the second two trials? Another thing I should mention is that I have had these same results with other decimal numbers like 0.1 and 0.3.
The expression 0.5 * 17 results in a floating point value by virtue of the fact that one of its components, 0.5, is floating point.
However, when you assign a floating point number like 8.5 to an integer, it's truncated to 8. And, to be clear about this, it's truncated at the point of assignment.
So the first code segment calculates the value 100 + 8.5 = 108.5 and truncates that to 108 when you assign it to the integer(a). The subtraction of 100 from that then gives you 8.
In the second code segment, you calculate the value 100 - 8.5 = 91.5 and truncate that to 91 when assigning to the integer. The subtraction of that from 100 gives you 9.
The reason the final two code segments work is because the 8.5 is being truncated earlier in int myInt2 = 0.5 * 17, before being added to or subtracted from 100. In that case, 100 + 8 = 108 and 100 - 8 = 92, both which are different from 100 by exactly 8 (sign notwithstanding).
(a) It may help to think of it graphically:
int myInt2 = myInt + (0.5 * 17);
^ int + double * int
| \ \__________/
| \ |
| \ double
| \_____________/
| |
+- truncate <- double
The 0.5 * 17 is calculated first to give the floating point 8.5.
This is then added to the integer myInt = 100 to give the floating point 108.5.
This is then truncated to 108 when being assigned to the integer myInt2.
.5 * 17 is not 8, it is 8.5
int myInt = 100;
int myInt2 = myInt + (0.5 * 17);
This computes 100 + (0.5 * 17) or 108.5, which gets truncated to 108.
int difference = myInt2 - myInt;
This computes 108 - 100, or 8, which is the result you see.
In your second example:
int myInt = 100;
int myInt2 = myInt - (0.5 * 17);
This calculates 100 - 8.5, or 91.5, which gets truncated to 91.
int difference = myInt - myInt2;
This calculates 100 - 91, or 9.
In the same fashion you can work through the rest of your examples.
There's a very useful tool on your computer. It's called a "debugger". Using this tool you can step through any of your programs, one line at a time, and see for yourself the values of all variables at each step of the way.
When doing maths with integers any decimal parts are lost AT EACH STEP.
So .5 * 17 gives 8.5, but the result stored in an integer variable is 8 which is used in subsequent steps, including output.
I recently faced a problem on a C++ code of mine making me wonder whether I had some misunderstanding of what the compiler would do with long operations...
Just look at the following code:
#include <iostream>
int main() {
int i = 1024, j = 1024, k = 1024, n = 3;
long long l = 5;
std::cout << i * j * k * n * l << std::endl; // #1
std::cout << ( i * j * k * n ) * l << std::endl; // #2
std::cout << l * i * j * k * n << std::endl; // #3
return 0;
}
For me the order in which the multiplications will happen in any of these 3 lines is undefined. However, here is what I thought would happen (assuming int is 32b, long long is 64b and they both follow the IEEE rules):
For line #2, the parenthesis is evaluated first, using ints as intermediate results, leading to an overflow and to store -1073741824. This intermediate result is promoted to long long for the last multiplication and the printed result should therefore be -5368709120.
Lines #1 and #3 are "equivalent" since the order of evaluation is undefined.
Now, for lines #1 and #3 here is were I'm unsure: I thought that although the order of evaluation was undefined, the compiler would "promote" all operations to the type of the largest operand, namely long long here. Therefore, no overflow would happen in this case since all computations would be made in 64b... But this is what GCC 5.3.0 gives me for this code:
~/tmp$ g++-5 cast.cc
~/tmp$ ./a.out
-5368709120
-5368709120
16106127360
I would have expected 16106127360 for the first result too. Since I doubt there is a compiler bug of this magnitude in GCC, I guess the bug lies between the keyboard and the chair.
Could anyone please confirm / infirm this is undefined behaviour and GCC is correct in giving me whatever it gives (since this is undefined)?
GCC is correct.
Associativity for multiplication is left to right. This means that all of these expression are evaluated left to right.
Promotion to higher type is only between two operands of different types of single binary operator.
For example, first expression is parsed as i * j * k * n * l = ((((i * j) * k) * n) * l) and the promotion happens only when last of multiplications is computed, but at this moment left operand is already incorrect.
The Standard unambiguously defines the grouping as follows:
5.6 Multiplicative operators [expr.mul]
1 The multiplicative operators *, /, and % group left-to-right.
This means that a * b * c is evaluated as (a * b) * c. A conforming compiler has no freedom to evaluate it as a * (b * c).
I have this preprocessor directive:
#define INDEXES_PER_SECTOR BYTES_PER_SECTOR / 4
where BYTES_PER_SECTOR is declared in another header file as:
#define BYTES_PER_SECTOR 64
I have this simple math equation that I wrote where after executing I get an assertion error as the value assigned to iTotalSingleIndexes is incorrect.
int iTotalSingleIndexes = (iDataBlocks - 29) / INDEXES_PER_SECTOR;
Now I believe this to be because of the preprocessor directive INDEXES_PER_SECTOR. Upon executing my equation iDataBlocks is 285 which is correct. I have confirmed this with gdb. The problem is that the value that gets assigned to iTotalSingleIndexes is 1 when it ought to be 16. I really have no idea why this is happening.
When I do something like:
int iIndexesInASector = INDEXES_PER_SECTOR;
int iTotalSingleIndexes = (iDataBlocks - 29) / iIndexesInASector;
the correct value gets assigned to iTotalSingleIndexes.
On other notes I use preprocessor directives in other equations and they work just fine so I am even more puzzled.
Any help would be much appreciated.
The preprocessor simply performs token replacement - it doesn't evaluate expressions. So your line:
int iTotalSingleIndexes = (iDataBlocks - 29) / INDEXES_PER_SECTOR;
expands to this sequence of tokens:
int iTotalSingleIndexes = ( iDataBlocks - 29 ) / 64 / 4 ;
...which, due to the associativity of the / operator, is then parsed by the compiler as:
int iTotalSingleIndexes = ((iDataBlocks - 29) / 64) / 4;
...which results in the value of 1. As leppie says, you want:
#define INDEXES_PER_SECTOR (BYTES_PER_SECTOR / 4)
This makes INDEXES_PER_SECTOR expand to a complete subexpression.
#define INDEXES_PER_SECTOR (BYTES_PER_SECTOR / 4)
Both of the given answers so far are correct,so accept one of them, but I thought I should expand on what they are saying
Number 1 rule of preprocessor macros.
If a macro expands to an expression, always enclose the expansion in parentheses
Number 2 rule of preprocessor macros
Always enclose macro arguments in parentheses where they are used in the expansion
For example, consider the macro below
#define X_PLUS_4(X) X + 4
foo = 1;
y = 3 * X_PLUS_4(foo + 2) * 4; // naively expect y to be 84
the second line expands to
y = 3 * foo + 2 + 4 * 4; // y is 13
which is probably not what you want
Applying the rules
#define X_PLUS_4(X) ((X) + 4)
The use above then becomes
y = 3 * ((foo + 2) + 4) * 4;
If you want to accomplish preprocessing-time operations with the preprocessor, you can use the Boost preprocessing library. However, you should REALLY be using const data for this.
const int BytesPerSector = 64;
const int IndexesPerSector = BytesPerSector / 4;
The preprocessor should be reserved for when you have absolutely no other choice. Performing arithmetic at compile-time is easily done with const ints.