I am trying to do a division of :-
#include <bits/stdc++.h>
using namespace std;
int main(){
int A = -2147483648;
int B = -1;
int C = A/B;
// this is not working
cout<<C<<endl;
// nor this is working
cout<<A/B<<endl;
// But this is working
cout<<-2147483648/-1<<endl; // printing the result 2147483648;
}
I am confused why this happening. Please explain.
Assuming the int type is 32-bits and uses two's complement representation, the first two cases exhibit undefined behavior because both -2147483648 and -1 fit in a int but 2147483648 does not.
In the third case, the expression -2147483648/-1 contains the integer literal 2147483648 (before being negated), and has the first type in which the value can fit. In this case, that would be long int. The rest of the calculation keeps the type, so no undefined behavior occurs.
You can change the data type to long long.
long long A = -2147483648;
long long B = -1;
long long C = A/B;
If your you need fractional result, try 'double' instead of 'long long'.
Related
I was trying to solve a question on codeforces . I have to give input
1000000000 1000000000 1
to this code
#include <iostream>
using namespace std;
int main()
{
long n,m,a;
cin >> n >> m >>a ;
long b,c;
b = (n%a==0)?(n/a):((n/a)+1);
c = (m%a==0)?(m/a):((m/a)+1);
unsigned long long d ;
d = b*c ;
cout<<d;
But it gave me error
Diagnostics detected issues [cpp.clang++-diagnose]: p71.cpp:12:5: runtime error: signed
integer overflow: 1000000000 * 1000000000 cannot be represented in type 'long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior p71.cpp:12:5 in
Then I got to know that I should add ULL suffix on a numeric literal. But how should I use ULL in this type of code;
where should I use ULL in after variables?
You cannot use ULL after variables. It is a suffix for integer literals. You should use ULL after those integer literals that you wish to be of type unsigned long long because that's what the suffix does.
All integer types have an upper (as well as lower) limit. Exact maximum values are specific to each system although the language standard does specify a lower bound as a requirement. If you know that a calculation will exceed the limits of a particular type, then you must use a larger type. If you don't know maximum result of a calculation or you know that it would exceed the limit of the largest integer type, then you must change strategy and not use plain integer types: Instead, you would need to use arbitrary precision arithmetic.
... where should I use ULL in after variables?
ULL is not applicable to variables.
The type on the left of the = does not affect the calculation on the right.
long b, c;
...
unsigned long long d;
d = b*c; // long multiplication and long product.
To benefit with the potential extended range of unsigned long long, ensure a long long multiplication. Various approaches.
d = b; // in 2 steps
d *= c;
d = (long long) b * c; // Cast
d = 1LL * b * c; // let compiler form effect code
Note that the first above results differ form the 2nd and 3rd when b or c are negative.
In C++, why is long l = 0x80000000; positive?
C++:
long l = 0x80000000; // l is positive. Why??
int i = 0x80000000;
long l = i; // l is negative
According to this site: https://en.cppreference.com/w/cpp/language/integer_literal, 0x80000000 should be a signed int but it doesn't appear to be case because when it gets assigned to l sign extension doesn't occur.
Java:
long l = 0x80000000; // l is negative
int i = 0x80000000;
long l = i; // l is negative
On the other hand, Java has a more consistent behavior.
C++ Test code:
#include <stdio.h>
#include <string.h>
void print_sign(long l) {
if (l < 0) {
printf("Negative\n");
} else if (l > 0) {
printf("Positive\n");
} else {
printf("Zero\n");
}
}
int main() {
long l = -0x80000000;
print_sign(l); // Positive
long l2 = 0x80000000;
print_sign(l2); // Positive
int i = 0x80000000;
long l3 = i;
print_sign(l3); // Negative
int i2 = -0x80000000;
long l4 = i2;
print_sign(l4); // Negative
}
From your link: "The type of the integer literal is the first type in which the value can fit, from the list of types which depends on which numeric base and which integer-suffix was used." and for hexadecimal values lists int, unsigned int...
Your compiler uses 32 bit ints, so the largest (signed) int is 0x7FFFFFFF. The reason a signed int cannot represent 0x8000000...0xFFFFFFF is that it needs some of the 2^32 possible values of its 32 bits to represent negative numbers. However, 0x80000000 fits in an 32 bit unsigned int. Your compiler uses 64 bit longs, which can hold up to 0x7FFF FFFF FFFF FFFF, so 0x80000000 also fits in a signed long, and so the long l is the positive value 0x80000000.
On the other hand int i is a signed int and simply doesn't fit 0x80000000, so undefined behaviour occurs. What often happens when a signed number is too big to fit in C++ is that two-complement arithmetic is used and the number wraps round to a large negative number. (Do not rely on this behaviour; optimisations have been known to break this). In any case it appears the two's complement behaviour has indeed happened in this case, resulting in i being negative.
In your example code you use both 0x80000000 and -0x80000000 and in each case they have the same result. In fact, the are the same. Recall that 0x8000000 is an unsigned int. The 2003 C++ standard says in 5.3.1c7: "The negative of an unsigned quantity is computed by subtracting its value from 2^n, where n is the number of bits in the promoted operand." 0x80000000 is precisely 2^31, and so -0x80000000 is 2^32-2^31=2^31. To get the expected behaviours we would have to use -(long)0x80000000 instead.
With the help of the awesome people on SO, I think I can answer my own question now:
Just to correct the notion that 0x80000000 can't fit in an int:
It is possible to store, without loss or undefined behavior, the value 0x80000000 to an int (assuming sizeof(int) == 4). The following code can demonstrate this behavior:
#include <limits.h>
#include <stdio.h>
int main() {
int i = INT_MIN;
printf("%X\n", i);
return 0;
}
Assigning the literal 0x80000000 to a variable is little more nuanced, though.
What the other others failed to mention (except #Daniel Langr) is the fact that C++ doesn't have a concept of negative literals.
There are no negative integer literals. Expressions such as -1 apply the unary minus operator to the value represented by the literal, which may involve implicit type conversions.
With this in mind, the literal 0x80000000 is always treated as a positive number. Negations come after the size and sign have been determined. This is important: negations don't affect the unsigned/signedness of the literal, only the base and the value do. 0x80000000 is too big to fit in a signed integer, so C++ tries to use the next applicable type: unsigned int, which then succeeds. The order of types C++ tries depends on the base of the literal plus any suffixes it may or may not have.
The table is listed here: https://en.cppreference.com/w/cpp/language/integer_literal
So with this rule in mind let's work out some examples:
-2147483648: Treated as a long int because it can't fit in an int.
2147483648: Treated as a long int because C++ doesn't consider unsigned int as a candidate for decimal literals.
0x80000000: Treated as an unsigned int because C++ considers unsigned int as a candidate for non-decimal literals.
(-2147483647 - 1): Treated as an int. This is typically how INT_MIN is defined to preserve the type of the literal as an int. This is the type safe way of saying -2147483648 as an int.
-0x80000000: Treated as an unsigned int even though there's a negation. Negating any unsigned is undefined behavior, though.
-0x80000000l: Treated as a long int and the sign is properly negated.
This question already has answers here:
Why does long long n = 2000*2000*2000*2000; overflow?
(6 answers)
Closed 1 year ago.
Why the below code gives integer overflow warning:
#include <stdio.h>
int main()
{
long long int x = 100000 * 99999;
return 0;
}
Whereas below code works perfectly:
#include <stdio.h>
int main()
{
long long int x = 100000000000000;
return 0;
}
Because here
long long int x = 100000 * 99999;
two ints are multiplied. Try
long long int x = 100000LL * 99999;
Make it 100000LL * 99999LL for the warning to go away.
You should read this or this.
The type of the integer literal is the first type in which the value
can fit, from the list of types which depends on which numeric base
and which integer-suffix was used.
(Thanks to #UnHolySheep who makes me notice it).
If you want the compiler to interpret differently your literal, you have to add a suffix. For example, with int, you can add LL or ll to specify that it's a long long int. With unsigned numbers the suffix is u.
With floating point literals, it's the same: there's a default type, which is double, but if you want a float you can easily use the f (or f) suffix. With floating point you can even use exponential rappresentation (usign the e).
I read that conversion from int to long long int is promotion and hence thought that there shouldn't be any issue as there is no loss of data, unlike the vice versa conversion.
But when I multiply two ints of large value and store it in long long int, it is showing me negative number.
Eg:
int a=1000000, b=1000000;
long long int c=a*b;
cout<<c;
The above code gives me a negative value. Can someone explain why?
a*b is still of type int. Once it's evaluated, the result is then converted to long long int. At that point it's too late to avoid overflow. Convert one of your values to long long int before preforming the multiplication. Try this :
#include <iostream>
int main()
{
int a = 1000000, b = 1000000;
long long int c = static_cast<long long int>(a)*b;
std::cout << c;
return 0;
};
The multiplication is happening as an int, which overflows, giving Undefined Behaviour (in this case overflow, which is very normal - your combination of compiler+settings may even guarantee it), and after that the result is being converted to long long.
I think you want to do the conversion on one of the arguments before multiplication, so that the multiplication is performed using long longs:
long long c = static_cast<long long>(a)*b;
In this way, b will be promoted to long long before the multiplication takes place, and the whole operation will be performed safely, and with the desired result.
Because multiplying two ints will result in another int that comes with all the overflow problems attached. This int is then (after the fact) promoted to a long long int which still means it's not what you want.
Promote at least one of the operands to have the other promoted and get the result you want.
There's no real need for a solution to this, I just want to know why.
Let's take two numbers:
#include <iostream>
using namespace std;
int main()
{
unsigned long long int a = 17446744073709551615;
signed long long int b = -30000000003;
signed int c;
c = a/b;
cout << "\n\n\n" << c << endl;
}
Now, lately the answer I've been getting is zero. The size of my long long is 8 bytes, so more than enough to take it with the unsigned label. The C variable should also be big enough to handle the answer. (It should be -581 558 136, according to Google). So...
Edit I'd like to point out that on my machine...
Using numeric_limits a falls well withing the maximum of 18446744073709551615 and b falls within the minimum limits of -9223372036854775808.
You have a number of implicit conversions happening, most of them unnecessary.
unsigned long long int a = 17446744073709551615;
An unsuffixed decimal integer literal is of type int, long int, or long long int; it's never of an unsigned type. That particular value almost certainly exceeds the maximum value of a long long int (263-1). Unless your compiler has a signed integer type wider than 64 bits, that makes your program ill-formed.
Add a ULL suffix to ensure that the literal is of the correct type:
unsigned long long int a = 17446744073709551615ULL;
The value happens to be between 263-1 and 264-1, so it fits in a 64-bit unsigned type but not in a 64-bit signed type.
(Actually just the U would suffice, but it doesn't hurt to be explicit.)
signed long long int b = -30000000003;
This shouldn't be a problem. 30000000003 is of some signed integer type; if your compiler supports long long, which is at least 64 bits wide, there's no overflow. Still, as long as you need a suffix on the value of a, it wouldn't hurt to be explicit:
signed long long int b = -30000000003LL;
Now we have:
signed int c;
c = a/b;
Dividing an unsigned long long by a signed long long causes the signed operand to be converted to unsigned long long. In this case, the value being converted is negative, so it's converted to a large positive value. Converting -30000000003 to unsigned long long yields 18446744043709551613. Dividing 17446744073709551615 by 18446744043709551613 yields zero.
Unless your compiler supports integers wider than 64 bits (most don't), you won't be able to directly divide 17446744073709551615 by -30000000003 and get a mathematically correct answer, since there's no integer type that can represent both values. All arithmetic operators (other than the shift operators) require operands of the same type, with implicit conversions applied as necessary.
In this particular case, you can divide 17446744073709551615ULL by 30000000003ULL and then account for the sign. (Check the language rules for division of negative integers.)
If you really need to do this in general, you can resort to floating-point (which means you'll probably lose some precision) or use some arbitrary width integer arithmetic package like GMP.
b is getting treated as an unsigned number which is larger than a. Hence you are getting the answer as 0.
Try using it as
c = abs(a) / abs (b)
if ((a < 0 && b > 0 ) || (a> 0 && b < 0))
return -c;
return c;