Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I get a segmentation fault while assigning values to what looks to me a properly allocated array. Here is the code below:
int SpV = L*L*L;
int V = SpV*T;
int M = 16;
int Ns = 2;
int Np = 10;
float *twopBuf = (float*) malloc(Np*Ns*V*M*2*sizeof(float));
if(twopBuf == NULL){
fprintf(stderr,"Cannot allocate twopBuf. Exiting\n");
exit(-1);
}
for(int bar=0;bar<Np;bar++)
for(int pr=0;pr<Ns;pr++)
for(int t=0;t<T;t++)
for(int v=0;v<SpV;v++)
for(int gm=0;gm<M;gm++){
int pos = 2*gm + 2*M*v + 2*M*SpV*t + 2*M*SpV*T*pr + 2*M*SpV*T*Ns*bar;
twopBuf[ 0 + pos ] = 1.0; // Set to 1.0 for
twopBuf[ 1 + pos ] = 1.0; // testing purposes
}
L and T are input, so when say L = 32 and T = 64 it runs fine. But for L = 48 and T = 96 I get segmentation fault after bar becomes 2 and before it becomes 3. If there wasn't enough memory to allocate twopBuf wouldn't I already get the error message?
I'm running this on the head node of a large supercomputer, if it makes a difference. Thanks.
The expression
Np*Ns*V*M*2*sizeof(float)
is evaluated as
((((Np*Ns)*V)*M)*2)*sizeof(float)
due to the left-to-right associativity of * in C and C++. See C11 draft standard n1570, 6.5.5 Multiplicative operators.
The type of an expression E1 * E2 is the common real type of the operands (6.3.1.8 Usual arithmetic conversions). In this case, the types are
((((int*int)*int)*int)*int)*size_t
so all but the last multiplication is done at int-precision and range.
For L = 48, T = 96 and sizeof(float) == 4, the infinitely precise result of the int-precision multiplications is 6794772480, which is not representable in 16- or 32-bit int, so one of the multiplications must overflow on such an implementation, which is undefined behavior.
If the expression is reordered to:
sizeof(float)*Np*Ns*V*M*2
all of the multiplications are done at size_t precision, unless int can represent all values size_t can represent. If the multiplications are done at size_t-precision, the multiplication is well-defined even if it overflows, since size_t is unsigned. However, if it does overflow, malloc() will return an allocation that is significantly smaller than you expect, which causes undefined behavior if you access beyond the end of the allocated object.
For the numbers you have provided, 64-bit size_t will not overflow if size_t has less than 30 padding bits.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
need an programming logic to print an 4 decimal points
EX: scalar should be 0 to -5
value = 10006 , scalar = -3 then print result = 10.0060 (4 decimals)
value = 123 ,scalar = -5 then print result = 0.0012 (4 decimals)**
required value/divisor = 10 , value%divisor = 0060 (required logic after decimals )
I tried like this:
divisor = std::pow(10,std::abs(scalar));
**Result = snprintf(X,Y,"%d.%0*d",value/scalar,4,value%scalar);**
I'm not allowed to use float , setprecision() .
It does not necessarily represent the actual value , but we can format that value to print with logic like the original one (by using the logic , add ...subtract...pow etc)
std::int32_t divisor = static_cast(std::pow( 10.0F, std::abs( Scalar)) );
but int the above result modulus scalar value with 0 are not considering.
**Please provide me the logic to print the above result with scalar condition
In order to print decimals (easily), you need floating point:
printf("%10.6f", static_cast<double>(1) / 3);
If one of the arguments to division is floating point, the compiler will promote the expression to floating point.
Integral or scalar division will lose decimals.
You are always welcome to write your own division function.
Edit 1: Shifting
You don't need to use the pow function (especially since it's floating point).
Use a loop, in the loop multiply your divisor by 10 each time.
double result = (double) scalar / value;
int divisor = 10;
int i;
for (i = 0; i < NUMBER_OF_DECIMALS; ++)
{
// Isolate a digit using math.
// print the digit
divisor += 10;
}
The math part is left as an exercise for the OP.
In this homework exercise you are expected to perform your own number formatting, rather than using that of a library.
For instance, to format and output 100 as "100"
int accum = 100;
int position = 0;
while (accum > 0)
{
printf("%d", accum % 10);
accum /= 10;
position += 1;
}
For your homework assignment, you need to modify the above loop so that it puts a printf(".") in the correct place in the output number. Your answer is likely to involve multiplying accum before the loop and testing position relative to scalar
I was trying to solve the reverse integer problem, where we have to keep in mind to deal with overflow.
Reading others solutions and tried out, I wrote my solution
class Solution {
public:
int reverse(int x) {
int result = 0;
int old_result = 0;
while(x) {
old_result = result;
result = result*10 + x%10;
if ((result-old_result*10)!=x%10)
return 0;
x = x/10;
}
return result;
}
};
And the answer was not accepted because overflow was not handled well. It turned out changing
if ((result-old_result*10)!=x%10)
to
if ((result-x%10)/10!=old_result)
would make things work.
I feel these lines are doing the same check. Not sure why one passes and one fails.
Can anyone help explain?
I feel these lines are doing the same check. Not sure why one passes and one fails.
Not necessarily. If the value of old_result ever was more than (or equal to) std::numeric_limits<int>::max () / 10 + 1, the expression old_result*10 would overflow, which would give you the wrong answer.
Overflow of integral types are undefined behavior. This is the quite from C++ (C++11/C++14/C++17) standard draft (I don't have access for the full version of standard, and, in majority of cases, it is good enough):
If during the evaluation of an expression, the result is not mathematically defined or not in the range of
representable values for its type, the behavior is undefined.
The second form (reordered) of if removes the multiplication - effectively increasing the range of values, that can be used in old_result.
result = result*10 + x%10;
if ((result-old_result*10)!=x%10)
// or
if ((result-x%10)/10!=old_result)
Both are bad when coded after result*10 + x%10; as the overflow may already have happened.
int overflow is to be avoided for well behaved code.
Rather than depend on overflow behaving as certain way, detect if result*10 + x%10 will overflow before computing it.
// for positive numbers
int max = std::numeric_limits<int>::max
while(x) {
int digit = x%10;
if (result >= max/10 && (result > max/10 || digit > max%10)) {
Overflow();
}
result = result*10 + digit;
x = x/10;
}
Note that overflow with signed numbers is implementation specific UB, so I suggest to use unsigned instead. Then considering that it use similar property than unsigned, and assuming that result = result*10 + x%10; overflows. Then:
result -= old_result * 10;
"reverts" the overflow in the same way.
whereas the following is true
(result - x % 10) == old_result * 10; // With possible overflow in both side.
Dividing by 10 on both side removes the overflow only with the simplification
(result - x % 10) / 10 == old_result;
// overflow on left side (before division). No overflow on right side.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
Question:
Your task is to:
Write a function that prints to the standard output (stdout) the number of users who didn't leave the site after 10 seconds (i.e: the number of users who didn't bounce).
Please round the result downwards to the nearest integer (e.g both 7.1 and 7.9 are rounded to 7).
Note that your function will receive the following arguments:
n which is an integer representing the number of visitors
b which is an integer representing the bounce rate (i.e: the percentage of users who left the site in the first 10 seconds)
My code compiles just fine and I am pretty sure that my logic is correct, but my output is wrong and I don't know why. When n = 1000 and b = 25 then my result should be 750. I keep on getting 1000. Where am I going wrong?
I am also not exactly sure how to "round down" the way that they want me to. Could that also be the reason why I am not getting the correct output?
MY CODE:
void compute_active_users(int n, int b) {
int BounceConvert = (b / 100); //converts the value of b to a decimal
int BounceRate = (n * BounceConvert); // multiplys n times the b decimal
int TotalVisitors = (n - BounceRate); // subtract BounceRate
printf("%d", TotalVisitors); // print out the final result
}
This uses the truncating behaviour of integer division in C for positive integers, which is the goal of your exercise:
void compute_active_users(int nbPeople, int bounceRate) {
int totalVisitors = nbPeople * (100 - bounceRate) / 100;
printf("%d\n", totalVisitors);
}
Your solution does not work because this line:
int BounceConvert = (b / 100);
will produce BounceConvert=0 (25/100 -> 0)
Consider b/100. In Integer division, when b=25, it boils down to 0, not 0.25 as you expect. For that use floating point operation.
void compute_active_users(int n, int b) {
float BounceRate = ((float)n * b)/100; // floating point operation
int roundedBounceRate = (int) BounceRate; //Integer cast rounds it lowest integer
int TotalVisitors = (n - roundedBounceRate); // subtract BounceRate
printf("%d", TotalVisitors); // print out the final result
}
This question already has answers here:
How do I detect unsigned integer overflow?
(31 answers)
Closed 8 years ago.
How to correctly check if overflow occurs in integer multiplication?
int i = X(), j = Y();
i *= j;
How to check for overflow, given values of i, j and their type? Note that the check must work correctly for both signed and unsigned types. Can assume that both i and j are of the same type. Can also assume that the type is known while writing the code, so different solutions can be provided for signed / unsigned cases (no need for template juggling, if it works in "C", it is a bonus).
EDIT:
Answer of #pmg is the correct one. I just couldn't wrap my head around its simplicity for a while so I will share with you here. Suppose we want to check:
i * j > MAX
But we can't really check because i * j would cause overflow and the result would be incorrect (and always less or equal to MAX). So we modify it like this:
i > MAX / j
But this is not quite correct, as in the division, there is some rounding involved. Rather, we want to know the result of this:
i > floor(MAX / j) + float(MAX % j) / j
So we have the division itself, which is implicitly rounded down by the integer arithmetics (the floor is no-op there, merely as an illustration), and we have the remainder of the division which was missing in the previous inequality (which evaluates to less than 1).
Assume that i and j are two numbers at the limit and if any of them increases by 1, an overflow will occur. Assuming none of them is zero (in which case no overflow would occur anyway), both (i + 1) * j and i * (j + 1) are both more than 1 + (i * j). We can therefore safely ignore the roundoff error of the division, which is less than 1.
Alternately, we can reorganize as such:
i - floor(MAX / j) > float(MAX % j) / j
Basically, this tells us that i - floor(MAX / j) must be greater than a number in a [0, 1) interval. That can be written exactly, as:
i - floor(MAX / j) >= 1
Because 1 is just after the interval. We can rewrite as:
i - floor(MAX / j) > 0
Or as:
i > floor(MAX / j)
So we have shown equivalence of the simple test and the floating-point version. It is because the division does not cause significant roundoff error. We can now use the simple test and live happily ever after.
You cannot test afterwards. If the multiplication overflows, it triggers Undefined Behaviour which can render tests inconclusive.
You need to test before doing the multiplication
if (INT_MAX / x > y) /* multiplication of x and y will overflow */;
If your compiler has a type that is at least twice as big as int then you can do this:
long long r = 1LL * x * y;
if ( r > INT_MAX || r < INT_MIN )
// overflowed...
else
x = r;
For portability you should STATIC_ASSERT( sizeof(long long) >= 2 * sizeof(int) ); or something similar but more extreme if you're worried about padding bits!
Try this
bool willoverflow(uint32_t a, uint32_t b) {
size_t a_bits=highestOneBitPosition(a),
size_t b_bits=highestOneBitPosition(b);
return (a_bits+b_bits<=32);
}
It is possible to see if overflow occured postfacto by using a division. In the case of unsigned values, the multiplication z=x*y has overflowed if y!=0 and:
bool overflow_occured = (y!=0)? z/y!=x : false;
(if y did equal zero, no overflow occured). For the case of signed values, it is a little trickier.
if(y!=0){
bool overflow_occured = (y<0 && x=2^31) | (y!=0 && z/y != x);
}
We need the first part of the expression because the first test will fail if x=-2^31 and y=-1. In this case the multiplication overflows, but the machine may give a result of -2^31. Therefore we test for it seperately.
This is true for 32 bit values. Extending the code to the 64 bit case is left as an exercise for the reader.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Best way to detect integer overflow in C/C++
If I have an expression x + y (in C or C++) where x and y are both of type uint64_t which causes an integer overflow, how do I detect how much it overflowed by (the carry), place than in another variable, then compute the remainder?
The remainder will already be stored in the sum of x + y, assuming you are using unsigned integers. Unsigned integer overflow causes a wrap around ( signed integer overflow is undefined ). See standards reference from Pascal in the comments.
The overflow can only be 1 bit. If you add 2 64 bit numbers, there cannot be more than 1 carry bit, so you just have to detect the overflow condition.
For how to detect overflow, there was a previous question on that topic: best way to detect integer overflow.
For z = x + y, z stores the remainder. The overflow can only be 1 bit and it's easy to detect. If you were dealing with signed integers then there's an overflow if x and y have the same sign but z has the opposite. You cannot overflow if x and y have different signs. For unsigned integers you just check the most significant bit in the same manner.
The approach in C and C++ can be quite different, because in C++ you can have operator overloading work for you, and wrap the integer you want to protect in some kind of class (for which you would overload the necessary operators. In C, you would have to wrap the integer you want to protect in a structure (to carry the remainder as well as the result) and call some function to do the heavy lifting.
Other than that, the approach in the two languages is the same: depending on the operation you want to perform (adding, in your example) you have to figure out the worst that could happen and handle it.
In the case of adding, it's quite simple: if the sum of the two is going to be greater than some maximum value (which will be the case if the difference of that maximum value M and one of the operands is greater than the other operand) you can calculate the remainder - the part that's too big: if ((M - O1) > O2) R = O2 - (M - O1) (e.g. if M is 100, O1 is 80 and O2 is 30, 30 - (100 - 80) = 10, which is the remainder).
The case of subtraction is equally simple: if your first operand is smaller than the second, the remainder is the second minus the first (if (O1 < O2) { Rem = O2 - O1; Result = 0; } else { Rem = 0; Result = O1 - O2; }).
It's multiplication that's a bit more difficult: your safest bet is to do a binary multiplication of the values and check that your resulting value doesn't exceed the number of bits you have. Binary multiplication is a long multiplication, just like you would do if you were doing a decimal multiplication by hand on paper, so, for example, 12 * 5 is:
0110
0100
====
0110
0
0110
0
++++++
011110 = 40
if you'd have a four-bit integer, you'd have an overflow of one bit here (i.e. bit 4 is 1, bit 5 is 0. so only bit 4 counts as an overflow).
For division you only really need to care about division by 0, most of the time - the rest will be handled be your CPU.
HTH
rlc