I want to use the following code in my program but gcc won't allow me to left shift my 1 beyond 31.
sizeof(long int) displays 8, so doesn't that mean I can left shift till 63?
#include <iostream>
using namespace std;
int main(){
long int x;
x=(~0 & ~(1<<63));
cout<<x<<endl;
return 0;
}
The compiling outputs the following warning:
left shift `count >= width` of type [enabled by default] `x=(~0 & ~(1<<63))`;
^
and the output is -1. Had I left shifted 31 bits I get 2147483647 as expected of int.
I am expecting all bits except the MSB to be turned on thus displaying the maximum value the datatype can hold.
Although your x is of type long int, the 1 is not. 1 is an int, so 1<<63 is indeed undefined.
Try (static_cast<long int>(1) << 63), or 1L << 63 as suggested by Wojtek.
You can't use 1 (int by default) to shift it beyond the int boundaries.
There's an easier way to get the "all bits except the MSB turned on" for a specific datatype
#include <iostream>
#include <limits>
using namespace std;
int main(){
unsigned long int max = std::numeric_limits<unsigned long int>::max();
unsigned long int max_without_MSB = max >> 1;
cout<< max_without_MSB <<endl;
return 0;
}
note the unsigned type. Without numeric_limits:
#include <iostream>
using namespace std;
int main() {
long int max = -1;
unsigned long int max_without_MSB = ((unsigned long int)max) >> 1;
cout << max_without_MSB << endl;
return 0;
}
Your title is misleading; a long can shift beyond 31 bits if a long is indeed that big. However your code shifts 1, which is an int.
In C++, the type of an expression is determined by the expression itself. An expression XXXXX has the same type regardless; if you later go double foo = XXXXX; it doesn't mean XXXXX is a double - it means a conversion happens from whatever XXXXX was, to double.
If you want to left-shift a long, then do that explicitly, e.g. 1L << 32, or ((long)1) << 32. Note that the size of long varies between platforms, so if you don't want your code to break when run on a different system then you'll have to take further measures, such as using fixed-width types, or shifting by CHAR_BIT * sizeof(long) - 1.
There is another issue with your intended code: 1L << 63 causes undefined behaviour if long is 64-bit or less. This is because of signed integer overflow; left-shift is defined the same as repeated multiplication of two, so attempting to "shift into the sign bit" causes an overflow.
To fix this, use unsigned types where it is fine to shift into the MSB, e.g. 1ul << 63.
Technically there is another issue in that ~0 doesn't do what you want if you are not on a 2's complement system, but these days it's pretty safe to ignore that case.
Looking at your overall intention with long x = ~0 & ~(1 << 63). A shorter way to write this is:
long x = LONG_MAX;
which is defined by <climits>. If you wanted 64-bit on all platforms then
int64_t x = INT64_MAX;
NB. If you do not intend to work with negative values then use unsigned long x and uint64_t respectively.
First let me state a few things about the shift, which is the source of your problem:
There is no guarantee that long int is actually 64 bit wide.
The most generic way I can think of is using std::numeric_limits:
static_cast<long int>(1) << (std::numeric_limits<long int>::digits - 1);
Now you can even make that a constexpr templated function:
template <typename Integer>
constexpr Integer foo()
{
return static_cast<Integer>(1) << (std::numeric_limits<Integer>::digits - 1);
}
So replacing the shift with static_cast<long int>(1) << (std::numeric_limits<long int>::digits - 1) will fix your issue, however there is a far better way:
std::numeric_limits includes a bunch of useful stuff, including:
std::numeric_limits<T>::max(); // the maximum value T can hold
std::numeric_limits<T>::min(); // the minimum value T can hold
std::numeric_limits<T>::digits; // the number of binary digits
std::numeric_limits<T>::is_signed(); // well, do I have to explain? ;-)
See cppreference.com for a complete list. You should prefer the facilities provided by the standard library, because it will most likely have fewer mistakes and other developers immediately know it.
The default datatype for a numeric value in C is integer unless explicitly mentioned.
Here you have to type cast the 1 as long int which would otherwise be an int.
Related
I have a simple program. Notice that I use an unsigned fixed-width integer 1 byte in size.
#include <cstdint>
#include <iostream>
#include <limits>
int main()
{
uint8_t x = 12;
std::cout << (x << 1) << '\n';
std::cout << ~x;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
return 0;
}
My output is the following.
24
-13
I tested larger numbers and operator << always gives me positive numbers, while operator ~ always gives me negative numbers. I then used sizeof() and found...
When I use the left shift bitwise operator(<<), I receive an unsigned 4 byte integer.
When I use the bitwise not operator(~), I receive a signed 4 byte integer.
It seems that the bitwise not operator(~) does a signed integral promotion like the arithmetic operators do. However, the left shift operator(<<) seems to promote to an unsigned integral.
I feel obligated to know when the compiler is changing something behind my back. If I'm correct in my analysis, do all the bitwise operators promote to a 4 byte integer? And why are some signed and some unsigned? I'm so confused!
Edit: My assumption of always getting positive or always getting negative values was wrong. But from being wrong, I understand what was really happening thanks to the great answers below.
[expr.unary.op]
The operand of ~ shall have integral or unscoped enumeration type; the
result is the one’s complement of its operand. Integral promotions are
performed.
[expr.shift]
The shift operators << and >> group left-to-right. [...] The operands shall be of integral or unscoped enumeration type and integral promotions are performed.
What's the integral promotion of uint8_t (which is usually going to be unsigned_char behind the scenes)?
[conv.prom]
A prvalue of an integer type other than bool, char16_t, char32_t, or
wchar_t whose integer conversion rank (4.13) is less than the rank of
int can be converted to a prvalue of type int if int can represent all
the values of the source type; otherwise, the source prvalue can be
converted to a prvalue of type unsigned int.
So int, because all of the values of a uint8_t can be represented by int.
What is int(12) << 1 ? int(24).
What is ~int(12) ? int(-13).
For performance reasons the C and C++ language consider int to be the "most natural" integer type and instead types that are "smaller" than an int are considered sort of "storage" type.
When you use a storage type in an expression it gets automatically converted to an int or to an unsigned int implicitly. For example:
// Assume a char is 8 bit
unsigned char x = 255;
unsigned char one = 1;
int y = x + one; // result will be 256 (too large for a byte!)
++x; // x is now 0
what happened is that x and one in the first expression have been implicitly converted to integers, the addition has been computed and the result has been stored back in an integer. In other words the computation has NOT been performed using two unsigned chars.
Likewise if you have a float value in an expression the first thing the compiler will do is promoting it to a double (in other words float is a storage type and double is instead the natural size for floating point numbers). This is the reason for which if you use printf to print floats you don't need to say %lf int the format strings and %f is enough (%lf is needed for scanf however because that function stores a result and a float can be smaller than a double).
C++ complicated the matter quite a bit because when passing parameters to functions you can discriminate between ints and smaller types. Thus it's not ALWAYS true that a conversion is performed in every expression... for example you can have:
void foo(unsigned char x);
void foo(int x);
where
unsigned char x = 255, one = 1;
foo(x); // Calls foo(unsigned char), no promotion
foo(x + one); // Calls foo(int), promotion of both x and one to int
I tested larger numbers and operator << always gives me positive
numbers, while operator ~ always gives me negative numbers. I then
used sizeof() and found...
Wrong, test it:
uint8_t v = 1;
for (int i=0; i<32; i++) cout << (v<<i) << endl;
gives:
1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
1073741824
-2147483648
uint8_t is an 8-bit long unsigned integer type, which can represent values in the range [0,255], as that range in included in the range of int it is promoted to int (not unsigned int). Promotion to int has precedence over promotion to unsigned.
Look into two's complement and how computer stores negative integers.
Try this
#include <cstdint>
#include <iostream>
#include <limits>
int main()
{
uint8_t x = 1;
int shiftby=0;
shiftby=8*sizeof(int)-1;
std::cout << (x << shiftby) << '\n'; // or std::cout << (x << 31) << '\n';
std::cout << ~x;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
return 0;
}
The output is -2147483648
In general if the first bit of a signed number is 1 it is considered negative. when you take a large number and shift it. If you shift it so that the first bit is 1 it will be negative
** EDIT **
Well I can think of a reason why shift operators would use unsigned int. Consider right shift operation >> if you right shift -12 you will get 122 instead of -6. This is because it adds a zero in the beginning without considering the sign
I want to use the following code in my program but gcc won't allow me to left shift my 1 beyond 31.
sizeof(long int) displays 8, so doesn't that mean I can left shift till 63?
#include <iostream>
using namespace std;
int main(){
long int x;
x=(~0 & ~(1<<63));
cout<<x<<endl;
return 0;
}
The compiling outputs the following warning:
left shift `count >= width` of type [enabled by default] `x=(~0 & ~(1<<63))`;
^
and the output is -1. Had I left shifted 31 bits I get 2147483647 as expected of int.
I am expecting all bits except the MSB to be turned on thus displaying the maximum value the datatype can hold.
Although your x is of type long int, the 1 is not. 1 is an int, so 1<<63 is indeed undefined.
Try (static_cast<long int>(1) << 63), or 1L << 63 as suggested by Wojtek.
You can't use 1 (int by default) to shift it beyond the int boundaries.
There's an easier way to get the "all bits except the MSB turned on" for a specific datatype
#include <iostream>
#include <limits>
using namespace std;
int main(){
unsigned long int max = std::numeric_limits<unsigned long int>::max();
unsigned long int max_without_MSB = max >> 1;
cout<< max_without_MSB <<endl;
return 0;
}
note the unsigned type. Without numeric_limits:
#include <iostream>
using namespace std;
int main() {
long int max = -1;
unsigned long int max_without_MSB = ((unsigned long int)max) >> 1;
cout << max_without_MSB << endl;
return 0;
}
Your title is misleading; a long can shift beyond 31 bits if a long is indeed that big. However your code shifts 1, which is an int.
In C++, the type of an expression is determined by the expression itself. An expression XXXXX has the same type regardless; if you later go double foo = XXXXX; it doesn't mean XXXXX is a double - it means a conversion happens from whatever XXXXX was, to double.
If you want to left-shift a long, then do that explicitly, e.g. 1L << 32, or ((long)1) << 32. Note that the size of long varies between platforms, so if you don't want your code to break when run on a different system then you'll have to take further measures, such as using fixed-width types, or shifting by CHAR_BIT * sizeof(long) - 1.
There is another issue with your intended code: 1L << 63 causes undefined behaviour if long is 64-bit or less. This is because of signed integer overflow; left-shift is defined the same as repeated multiplication of two, so attempting to "shift into the sign bit" causes an overflow.
To fix this, use unsigned types where it is fine to shift into the MSB, e.g. 1ul << 63.
Technically there is another issue in that ~0 doesn't do what you want if you are not on a 2's complement system, but these days it's pretty safe to ignore that case.
Looking at your overall intention with long x = ~0 & ~(1 << 63). A shorter way to write this is:
long x = LONG_MAX;
which is defined by <climits>. If you wanted 64-bit on all platforms then
int64_t x = INT64_MAX;
NB. If you do not intend to work with negative values then use unsigned long x and uint64_t respectively.
First let me state a few things about the shift, which is the source of your problem:
There is no guarantee that long int is actually 64 bit wide.
The most generic way I can think of is using std::numeric_limits:
static_cast<long int>(1) << (std::numeric_limits<long int>::digits - 1);
Now you can even make that a constexpr templated function:
template <typename Integer>
constexpr Integer foo()
{
return static_cast<Integer>(1) << (std::numeric_limits<Integer>::digits - 1);
}
So replacing the shift with static_cast<long int>(1) << (std::numeric_limits<long int>::digits - 1) will fix your issue, however there is a far better way:
std::numeric_limits includes a bunch of useful stuff, including:
std::numeric_limits<T>::max(); // the maximum value T can hold
std::numeric_limits<T>::min(); // the minimum value T can hold
std::numeric_limits<T>::digits; // the number of binary digits
std::numeric_limits<T>::is_signed(); // well, do I have to explain? ;-)
See cppreference.com for a complete list. You should prefer the facilities provided by the standard library, because it will most likely have fewer mistakes and other developers immediately know it.
The default datatype for a numeric value in C is integer unless explicitly mentioned.
Here you have to type cast the 1 as long int which would otherwise be an int.
While trying to come up with a scheme for a bitboard class, I decided use global compile time variables to represent key bit board configurations, ex. the initial position of all black rooks.
constexpr uint64_t BLACK_ROOK_INIT = 0x1 | (0x1 << 56);
However I am getting compiler errors. The compiler appears to be treating this value as a 32 bit value and type casting or adding additional 0's does not seem to make a difference. The type definition is from .
As soon as I drop constexp from this expression it compiles, however still produces the equivalent warning. Why is this happening? I thought it might be a limitation of the pre-processor, but the problem persists without constexp.
chess.cpp:16:64: error: right operand of shift expression ‘(1 << 56)’ is >= than the precision of the left operand [-fpermissive]
FYI, this also does not compile
constexpr int64_t BLACK_ROOK_INIT = (int64_t)0x1 | (int64_t)(0x1 << 32);
This is what you want:
#include <iostream>
int main(){
constexpr uint64_t BLACK_ROOK_INIT = 0x1ULL | (0x1ULL << 56);
std::cout<<BLACK_ROOK_INIT<<std::endl;
}
Your 0x1 value is, by default, an int, which is usually implemented as a 32-bit integer.
The suffixes are discussed here. If they make you a bit uncomfortable, as they do me, you can cast as follows:
#include <iostream>
int main(){
constexpr uint64_t BLACK_ROOK_INIT = (uint64_t)(0x1) | ((uint64_t)(0x1) << 56);
std::cout<<BLACK_ROOK_INIT<<std::endl;
}
here 1 is int and after shifting it crosses the limit of int.
so firstly we need to convert int to long long int(a/c to your requirements)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
ll l=(long long int)1<<n;
cout<<l<<endl;
}
I wanted to write a program that computes the number of zones made by n lines.
The first example is my code, and the second is my friend's code. I think they are trying to do the same thing, but for the case n=65535 my code gives me the wrong answer. Where is the problem in my code?
my code:
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
unsigned long long ans;
ans = (n*(n + 1) / 2) + 1;
cout << ans << endl;
return 0;
}
my friend's code:
#include <iostream>
using namespace std;
int main(void){
double n,sum;
cin>>n;
sum=n*(n+1)/2+1;
cout<<(long)sum<<endl;
return 0;
}
In your code:
int n;
ans = (n*(n + 1) / 2) + 1;
All values in the calculation are ints: n is declared as int, and plain integer constants are ints as well. Therefore the result of this calculation will also be an int. The fact that you later assign this result to a long long variable doesn't change this.
Now the result of the multiplication 65535*65536 does not fit in a 32-bit signed int, so you get a nonsense answer. Fix your program by making n a 64-bit long long.
As #Dithermaster suggests, the problem here is probably one of integer overflow.
As it stands right now, your code doesn't actually make much sense. In particular, since you've defined n as an int, and all the integer literals in the expression: (n*(n + 1) / 2) + 1 are also small enough to fit in an int, the calculation will be carried out on ints, and then (after the calculation is complete) the result will be converted to long long and assigned to ans (because you've defined ans as a long long).
What you almost certainly want is to carry out the entire calculation on long long to avoid overflow. The most obvious way to do this would be to define n as a long long instead of an int.
Your friend has avoided this by defining n as a double. This works up to a point--a typical implementation of double has a 53-bit significand, so it can be used as (essentially) a 53-bit integer type. That's obviously quite a bit more than the 16 bits that's mandated for an int, but equally obviously less than the 64 bits mandated for a long long.
There's also no point in supporting n being negative, so you could consider defining n and ans as unsigned long long instead.
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;