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.
Related
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;
This question already has answers here:
#define SQR(x) x*x. Unexpected Answer
(4 answers)
Closed 1 year ago.
I was trying to do some newbie competitive programming problems (because currently i am a newbie :D).
I got this strange error with constant and long long division... And watched carefully about tipe conversion problems (can't see any).
I don't understand why such division, gives 1e18 instead of desired result...
#include <iostream>
#define ll long long
#define UPPER (ll)1e18 + 1
ll mult(ll first, ll second)
{
ll div = UPPER / second;
std::cout << UPPER / second << " " << UPPER << std::endl;
if (first > div)
{
return UPPER;
}
return first * second;
}
int main()
{
//51e10
ll first = 510000000000, second = 510000000000;
std::cout << mult(first, second);
}
And the output i get is:
1000000000000000000 1000000000000000001
908560695322214400
Macros are just simple text replacements. UPPER / second will be replaced with (ll)1e18 + 1 / second which is always equal to (ll)1e18 unless second is 1
You must use parentheses around that
#define UPPER ((ll)1e18 + 1)
Why are you using long long? I think this datatype refers to an integer right? I think you expect out of the divison a floating point number. I would suggest to try your approach with long double (which has the same size like long long). Type long double is a floating point type that is larger than or equal to type double.
I am trying to write a program to solve a quadratic equation whose coefficients' values do not exceed 100 by absolute value and it is guaranteed that if any roots exist, they are integers. Here's what I've tried:
#include <cmath>
#include <iostream>
int main() {
int a, b, c; // coefficients of quadratic equation
std::cin >> a >> b >> c;
int d = b * b - 4 * a * c; // discriminant
if (d < 0)
std::cout << "No roots";
else if (d == 0)
std::cout << "One root: " << -b / (2 * a);
else
std::cout << "Two roots: " << (-b - std::sqrt(d)) / (2 * a) << " "
<< (-b + std::sqrt(d)) / (2 * a);
return 0;
}
It works fine, however, Visual Studio 2019 shows this warning:
Arithmetic overflow: Using operator '*' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator '*' to avoid overflow (io.2).
Exactly why does this warning pop up and what is it trying to tell me? What am I doing wrong and how can I fix the problem?
I've seen this on SO, but I don't believe it's a bug.
It's not a bug. Here:
(-b - std::sqrt(d)) / (2 * a)
The result of the expression is a double. But result of 2 * a is an int and it's eventually converted to a double. It is possible that 2 * a overflows if a is too large before it's converted to double. But since the eventual result is already a double, you could cast 2 or a to double as well and avoid the risk of overflow once and for all. So the compiler is telling you that the Right ThingTM to do is:
(-b - std::sqrt(d)) / (2.0 * a)
It won't overflow (result of (2.0 * a) is a double) and it's probably already what you want.
The root cause here (pun very much accepted) is that the quadratic equation is not a Diophantine equation. It applies to real numbers, and in particular sqrt(d) is usually not an integer.
In C++, the return type of sqrt(IntegralType) is double. Thus 2*a is converted to double too, but only after multiplying. And Visual Studio very reasonably notes that you're better off doing the conversion before multiplying. It just doesn't note that you can even make a,b,c all doubles from the start.
The way to fix this is to static_cast<long long> because long long is 8 bytes and it is large enough to hold the information in the event of an overflow. An overflow occurs when you try to hold a number when you do not have enough bits to do so and as a result some of them get chopped off.
Here is an example without the warning:
std::cout << "Two roots: " << (-b - std::sqrt(d)) / (2 * static_cast<long long>(a)) << " "
<< (-b + std::sqrt(d)) / (2 * static_cast<long long>(a));
It no longer shows the warning in VS2022.
Apparently Microsoft concluded it produces more noise than useful information.
See my answer to the similar problem you linked to here:
Warning C26451: Arithmetic overflow
This question already has answers here:
Purpose of a ".f" appended to a number?
(5 answers)
Closed 5 years ago.
I am following a tutorial on how to make a game with SDL. At a certain point in the tutorial I need to calculate the game's FPS. The tutorial does the following:
caption << "Average Frames Per Second: " << frame / ( fps.get_ticks() / 1000.f );
Now, I know exactly what the code does, except for the part where it divides by 1000.f. I've been looking but just can't find what .f means.
So my question is, what does .f mean? And why is it there?
1000 is an int literal.
1000. is a double literal.
1000.f is a float literal.
It means this is a float constant rather than a double constant. As for the effect, on most C++ compilers, it will have no effect as the float will be converted to a double to do the divide.
.f makes the number float type.
Just see this interesting demonstration:
float a = 3.2;
if ( a == 3.2 )
cout << "a is equal to 3.2"<<endl;
else
cout << "a is not equal to 3.2"<<endl;
float b = 3.2f;
if ( b == 3.2f )
cout << "b is equal to 3.2f"<<endl;
else
cout << "b is not equal to 3.2f"<<endl;
Output:
a is not equal to 3.2
b is equal to 3.2f
Do experiment here at ideone: http://www.ideone.com/WS1az
Try changing the type of the variable a from float to double, see the result again!
It is telling you the literal 1000. should be treated as a float. Look here for details.
It means 1000.f is treated as a float.
A floating point literal can have a suffix of (f, F, l or L). "f and F" specify a float constant and "l and L" a double.
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.