I know this is stupid but I'm a quiet a noob in a programming world here is my code.
This one works perfectly:
#include <stdio.h>
int main() {
float x = 3153600000 ;
printf("%f", x);
return 0;
}
But this one has a problem:
#include <stdio.h>
int main() {
float x = 60 * 60 * 24 * 365 * 100 ;
printf("%f", x);
return 0;
}
So 60 * 60 * 24 * 365 * 100 is 3153600000 right ??? if yes then why does it produced different results ??? I got the overflow in the second one it printed "-1141367296.000000" as a result. Could anyone tell me why ?
You're multiplying integers, then putting the result in a float. By that time, it has already overflowed.
Try float x = 60.0f * 60.0f * 24.0f * 365.0f * 100.0f;. You should get the result you want.
60 is an integer, as are 24, 365, and 100. Therefore, the entire expression 60 * 60 * 24 * 365 * 100 is carried out using integer arithmetic (the compiler evaluates the expression before it sees what type of variable you're assigning it into).
In a typical 32-bit architecture, a signed integer can only hold values up to 2,147,483,647. So the value would get truncated to 32 bits before it gets assigned into your float variable.
If you tell the compiler to use floating-point arithmetic, e.g. by tacking f onto the first value to make it float, then you'll get the expected result. (A float times an int is a float, so the float propagates to the entire expression.) E.g.:
float x = 60f * 60 * 24 * 365 * 100;
Doesn't your compiler spit this warning? Mine does:
warning: integer overflow in
expression
The overflow occurs before the all-integer expression is converted to a float before being stored in x. Add a .0f to all numbers in the expression to make them floats.
If you multiply two integers, the result will be an integer too.
60 * 60 * 24 * 365 * 100 is an integer.
Since integers can go up to 2^31-1 (2147483647) such values overflows and becomes -1141367296, which is only then converted to float.
Try multiplying float numbers, instead of integral ones.
Related
There are 2 large integer numbers. When I multiply it the result is always wrong, even if I used long double and the result should be in valid range of long double:
long double f = 1000000000 * 99999;
I debugged, and the result is so strange: -723552768.00000000. Did I missed something? how can I multiple it?
Thanks and regard!
from the C++ standards:
4 An unsuffixed floating constant has type double. If suffixed by the
letter f or F, it has type float. If suffixed by the letter l or L, it
has type long double
auto fl = 1000000000.L * 99999.L;
std::cout << fl << "\n";
or
long double fl = 1000000000L * 99999.L;
std::cout <<"\n"<< fl << "\n";
Numeric literals are int by default in C++. Thus, the expression 1000000000 * 99999 is viewed as the multiplication of two int 's and therefore the result returned by the * operator is an int. This int is only converted to the long double variable f after the multiplication has taken place. Depending on your platform, the range of int is usually from -2147483648 to 2147483647 (or 4 bytes in size). However, the product of 1000000000 x 99999 is 9.9999 x 10^13 which falls outside this range and thus overflow occurs as the int variable is not large enough to hold the value.
To avoid this, at least one of the numbers the * operator operates on should be declared as a long double literal with the suffix .l or .L as follows:
long double f = 1000000000.L * 99999
In the above expression , the * operator will return a long double which is large enough to hold the resulting product before being assigned to f.
Agree with #feiXiang. You are basically multiplying two ints. To do correct calculations, you have to define large numbers as long double. See the code below:
#include <iostream>
using namespace std;
int main()
{
long double a = 1000000000;
long double b = 99999;
long double f = a * b;
cout<<f;
return 0;
}
Output:
9.9999e+13
Actually you invoke undefined behavior with:
long double f = 1000000000 * 99999;
First, evaluate 1000000000 * 99999, which is a multiplication of two int objects. Multiplying two int objects is always an int. Since int is not big enough to represent the result (most likely 32 bits), the upper bits are lost.
Since overflows in signed integer types is undefined, you just triggered undefined behavior. But in this case it is possible to explain what happened, even though it is UB.
The computation keeps only the lowest 32 bits, which should be (1000000000 * 99999) modulo (2**32) == 3571414528. But this value is too big for int. Since on PC int negatives are represented by two's complement, we have to subtract 2**32, every time 2**31<= result < 2**32. This gives -723552768
Now, the last step is:
long double f = -723552768
And that is what you see.
To overcome the issue, either use long long like this:
long double f = 1000000000LL * 99999;
Or double:
long double f = 1000000000.0 * 99999;
1000000000 and 99999 are integer numbers, then the result of 1000000000 * 99999 will be an integer before it is assigned to your variable, and the result is out of range of integer.
You should make sure that the result is a long double first:
long double f = (long double) 1000000000 * 99999;
Or
long double f = 1000000000LL * 99999;
I am at a loss with what is happening here. I need to convert a float to an int16_t and back. Here is the syntax:
int16_t val = (int16_t)round((float)0xFFFE/100 * angle);
//and back
float angle = ((float)100/0xFFFE * val;
When I use an initial angle value of -0.093081, it converts back. But when I use 182.241211 it converts back to -17.764824?
Any idea what is going on?
0xFFFE is almost the maximum 16-bit number; and only for an unsigned 16-bit number, at that. If you divide it by 100 and then multiply by 182, it's definitely going to overflow.
Let's do it fully in base 10 for clarity (0xFFFE is 65534):
65534 / 100 * -0.093081 = -60.99970254
65534 / 100 * 182.241211 = 119429.95521674
The full range of your signed 16-bit integer is almost certainly [-32768, 32767]. That last result won't fit.
Code in question:
std::stringstream cd;
int f = int((15 / allyCounter) * 100);
cd << f;
allyCounter is equal to 45. the idea is to get what percentage 15 is of allyCounter where allyCounter is a dynamic int that is constantly changing. i don't have much experience with c++ so I'm sure what I'm missing is something fundamental.
The problem here is almost certainly with integer vs. floating point math.
15/45 (when done in integer math) is 0.
Try
std::stringstream cd;
int f = int((15.0 / allyCounter) * 100);
cd << f;
...and see if things aren't better. 15.0 is a double precision floating point constant, so that'll force the math to be done in floating point instead of integers, so you'll get a percentage.
Another possibility would be to do the multiplication ahead of the division:
int f = 1500 / allyCounter;
If the numerator were a variable, this could lead to a problem from the numerator overflowing, but in this case we know it's a value that can't overflow.
In C++, 15 / 45 is 0. (It's called "integer division": the result of dividing two ints in C++ is also an int, and thus the real answer is truncated, and 15 / 45 is 0.)
If this is your issue, just make it a double before doing the division:
int f = static_cast<double>(15) / allyCounter * 100;
or even:
int f = 15. / allyCounter * 100;
(The . in 15. causes that to be a double.)
You are using integer division:
std::stringstream cd;
int f = int((15.0 / allyCounter) * 100);
cd << f;
The compiler sees 15/allyCounter and thinks it should return an integer (you passed it two integers, right?). 15/150 == 0 with integer division, you always round down. In this case the compiler sees 15.0 as a double, and uses decimal places.
mlAnswer = ( ( ( degreesPLato->text().toInt() * 1000000 ) * 3800 ) / answer );
is the code in quesition
mlAnswer out puts -8223, while my calculator puts out 228000
debug output
12 * 1000000 * 3800 / 200000 = -8223
all data types are ints Please tell me what I'm doing wrong.
12 * 1000000 * 3800 = 45.6 billion.
This is out of range for a 4 byte signed integer, which is what int usually is. Try using long long instead.
The default type of an integer literal is int, unless the number is too big to fit in an int. As long as you are doing math operations between ints, the results remain as ints. 12 is an int, 1000000 is an int, and 3800 is an int. When you multiply them together, the result is still an int, even though it no longer fits. Add the LL suffix to make the integer literal a long long. i.e. 12LL, 1000000LL, 3800LL, etc...
You can fix this by reordering your operations:
12 * 1000000 * 3800 / 200000
Will overflow an int, however:
12 * 1000000 / 200000 * 3800
will not.
Note that this will only give the same answer if the numerator is an integer multiple of the denominator. Using LL is a better solution on platforms that support it, but if you are constrained to a 4 byte int type, this will at least stop overflow in more situations.
I tried to add two digits with different weights. Here is my code:
void onTimeStepOp::updatePointsType1_2(boost::tuples::tuple<float,int,int,int> &_prev,
boost::tuples::tuple<float,int,int,int> &_result,
boost::tuples::tuple<float,float> weights)
{
_result.get<0>() = _result.get<0>() * weights.get<0>() + _prev.get<0>() * weights.get<1>();
std::cout<<"deb:"<<(float)_result.get<2>() * weights.get<0>()<<" "<<(float)_prev.get<2>() * weights.get<1>()<<std::endl;
_result.get<2>() = (int)((float)(_result.get<2>()) * weights.get<0>() + (float)(_prev.get<2>()) * weights.get<1>());
std::cout<<"deb2:"<<(float)_result.get<3>() * weights.get<0>() <<" "<< (float)_prev.get<3>() * weights.get<1>()<<std::endl;
_result.get<3>() = (int)((float)(_result.get<3>()) * weights.get<0>() + (float)(_prev.get<3>()) * weights.get<1>());
}
weights.get<0> = 0.3,weights.get<1> = 0.7.
The output I get looks like this:
resultBefore=36.8055 4 69 91 previousPPos=41.192 4 69 91
deb:20.7 48.3
deb2:27.3 63.7
resultAfter=39.8761 4 **68** 91
The third number should be 69(69 * 0.3 + 69 * 0.7). However, it is 68 instead. What's the problem with the type conversion expression?
Conversion to int truncates, so the slightest rounding error could cause you to be one off. Rather than converting directly to int, you might want to use the function round.
I might add that weights.get<0> is certainly not 0.3, and weights.get<1> is certainly not 0.7, since neither 0.3 nor 0.7 are representable in machine floating point (at least not on any machine you're likely to be using).
You should round() instead of just casting to int. Casting trims everything after the decimal point, and the number due to rounding error may be something like 68.99999999991 (just an example but gives the idea).
Casting to int will result the number before the dot, so 68.1..68.9 will be all 68 as written before.
Another solution could be, which is not so nice, that is to add 0.5 to your float value before casting. So 68.1 will be 68.6, which will be still 68, but 68.5 will be 69 which will be 69.