As i know binary equivalent of signed int is 11111111111111111111111111111111
and based on this, I'm trying to make Maximum and Minimum int value for my program without using limits.h header file. After run my below code i get Minimum value as -2147483648 and Maximum value is 0. Here below is my code:
int MaxInt(){
int MAX = -1;
MAX = 0 << ((sizeof(int)*8)-1);
return MAX;
}
int MinInt(){
int MIN = 0;
MIN = 1 << ((sizeof(int)*8)-1);
return MIN;
}
Whats wrong with my implementation.
Your implementation has several mistakes:
First, your representation of -1 assumes that int has a twos-complement 32 bit representation. This is not guaranteed for int. (It is for std::int32_t.)
Second, you assume that int has sizeof(int)*8 bits. This again is not guaranteed at all.
Under all these assumptions, you still have a mistake in your implementation:
0 << ((sizeof(int)*8)-1);
can be written (mathematically, not in c++) as:
0 * 2**((sizeof(int)*8)-1)
Now, as you know, multiplying something with 0 results in 0.
Assuming that twos-complement is given, the following simple implementations should work:
MIN = -1 << ((sizeof(int)*8)-1);
MAX = ~MIN;
In the function
int MaxInt(){
int MAX = -1;
MAX = 0 << ((sizeof(int)*8)-1);
return MAX;
}
you at first assigned -1 to MAX and then overwrote its value. So this assignment does not make sense.
Also if to shift left 0 then you will get again 0 independing on how long you will shift the 0.:)
The simplest way to get the maximum value of object of type int for the 2's complement internal representation is the following
int MaxInt()
{
int MAX = -1u >> 1;
return MAX;
}
Or you can write simply
int MaxInt()
{
return -1u >> 1;
}
Here is a demonstrative program
#include <iostream>
constexpr int MaxInt()
{
return -1u >> 1;
}
constexpr int MinInt()
{
return ~( -1u >> 1 );
}
int main()
{
std::cout << MaxInt() << std::endl;
std::cout << MinInt() << std::endl;
}
The program output might look like
2147483647
-2147483648
Whats wrong with my implementation
MAX = 0 << ((sizeof(int)*8)-1);
Shifting zero by any amount will always be zero.
This isn't specific to C++, but rather about 2's complement form. In 2's complement, the most-significant bit doesn't merely indicate the sign (that the value is negative) but is rather that power of 2 (that is, for an 8-bit 2's complement number, the most significant bit would represent -2^7).
To make the most negative number, only the most significant bit should be set.
// Disclaimer: this should work for *most* devices, but it
// is device-specific in that I am assuming 2's complement
// and I am also assuming that a char is 8-bits. In theory,
// you might find a custom chip where this isn't true,
// but any popular chip will probably have this behavior:
int number_of_digits_in_int = sizeof(int) * 8;
int most_significant_digit_index = number_of_digits_in_int - 1;
int most_negative_int = 1 << most_significant_digit_index;
To make the largest positive number, all positive bits should be set:
// The complement of 0 has all bits set. This value, by the way
// is the same as "-1" in 2s complement form, but writing it
// this way for clarity as to its meaning.
int all_bits_set = ~(static_cast<int>(0));
// Using an XOR with the most negative integer clears the
// most-signficant sign bit, leaving only positive bits.
int largest_positive_int = all_bits_set ^ most_negative_int;
Or, more simply:
// Since the most negative integer has only the negative bit set,
// its complement has only the positive bits set.
int largest_positive_int = ~most_negative_int;
As others have stated, though, you should just use std::numeric_limits. This will also make your code portable and work even on very bizaare devices that don't use 2s complement, for example, not to mention that the less code you write yourself, the fewer mistakes that you'll make.
Related
if i used nounce = 32766 it only gives 1 time output but for 32767 it goes to infinite loop..... why ?? same thing happen when i used int
#include<iostream>
using namespace std;
class Mining
{
short int Nounce;
};
int main()
{
Mining Mine;
Mine.Nounce = 32767;
for (short int i = 0; i <= Mine.Nounce; i++)
{
if (i == Mine.Nounce)
{
cout << " Nounce is " << i << endl;
}
}
return 0;
}
When you use the largest possible positive value, every other value will be <= to it, so this loop goes on forever:
for(short int i=0;i<=Mine.Nounce;i++)
You can see that 32767 is the largest value for a short on your platform by using numeric_limits:
std::cout << std::numeric_limits<short>::max() << std::endl; //32767
When i reaches 32767, i++ will attempt to increment it. This is undefined behavior because of signed overflow, however most implementations (like your own apparently) will simply roll over to the maximum negative value, and then i++ will happily increment up again.
Numeric types have a limit to the range of values they can represent. It seems like the maximum value a int short can store on your platform is 32767. So i <= 32767 is necessarily true, there exists no int short that is larger than 32767 on your platform. This is also why the compiler complains when you attempt to assign 100000 to Mine.Nounce, it cannot represent that value. See std::numeric_limits to find out what the limits are for your platform.
To increment a signed integer variable that already has the largest possible representable value is undefined behavior. Your loop will eventually try to execute i++ when i == 32767 which will lead to undefined behavior.
Consider using a larger integer type. int is at least 32 bit on the majority of platforms, which would allow it to represent values up to 2147483647. You could also consider using unsigned short which on your platform would likely be able to represent values up to 65535.
In your for loop, i will never be greater than the value of Mine.Nounce because of the way that shorts are represented in memory. Most implementations use 2 bytes for a short with one bit for the sign bit. Therefore , the maximum value that can be represented by a signed short is 2^15 - 1 = 32767.
It goes to infinite loop because your program exhibits undefined behavior due to a signed integer overflow.
Variable i of type short overflows after it reaches the value of Mine.Nounce which is 32767 which is probably the max value short can hold on your implementation. You should change your condition to:
i < Mine.Nounce
which will keep the value of i at bay.
I am not an advanced C++ programmer. But I have been using C++ for a long time now. So, I love playing with it. Lately I was thinking about ways to maximize a variable programmatically. So I tried Bitwise Operators to fill a variable with 1's. Then there's signed and unsigned issue. My knowledge of memory representation is not very well. However, I ended up writing the following code which is working for both signed and unsigned short, int and long (although int and long are basically the same). Unfortunately, for long long, the program is failing.
So, what is going on behind the scenes for long long? How is it represented in memory? Besides, Is there any better way to do achieve the same thing in C++?
#include <bits/stdc++.h>
using namespace std;
template<typename T>
void Maximize(T &val, bool isSigned)
{
int length = sizeof(T) * 8;
cout << "\nlength = " << length << "\n";
// clearing
for(int i=0; i<length; i++)
{
val &= 0 << i;
}
if(isSigned)
{
length--;
}
val = 1 << 0;
for(int i=1; i<length; i++)
{
val |= 1 << i;
cout << "\ni = " << i << "\nval = " << val << "\n";
}
}
int main()
{
long long i;
Maximize(i, true);
cout << "\n\nsizeof(i) = " << sizeof(i) << " bytes" << "\n";
cout << "i = " << i << "\n";
return 0;
}
The basic issue with your code is in the statements
val &= 0 << i;
and
val |= 1 << i;
in the case that val is longer than an int.
In the first expression, 0 << i is (most likely) always 0, regardless of i (technically, it suffers from the same undefined behaviour described below, but you will not likely encounter the problem.) So there was no need for the loop at all; all of the statements do the same thing, which is to zero out val. Of course, val = 0; would have been a simpler way of writing that.
The issue 1 << i is that the constant literal 1 is an int (because it is small enough to be represented as an int, and int is the narrowest representation used for integeral constants). Since 1 is an int, so is 1 << i. If i is greater than or equal to the number of value bits in an int, that expression has undefined behaviour, so in theory the result could be anything. In practice, however, the result is likely to be the same width as an int, so only the low-order bits will be affected.
It is certainly possible to convert the 1 to type T (although in general, you might need to be cautious about corner cases when T is signed), but it is easier to convert the 1 to an unsigned type at least as wide as Tby using the maximum-width unsigned integer type defined in cstdint, uintmax_t:
val |= std::uintmax_t(1) << i;
In real-world code, it is common to see the assumption that the widest integer type is long long:
val |= 1ULL << i;
which will work fine if the program never attempts to instantiate the template with a extended integer type.
Of course, this is not the way to find the largest value for an integer type. The correct solution is to #include <limits> and then use the appropriate specialization of std::numeric_limits<T>::max()
C++ allows only one representation for positive (and unsigned) integers, and three possible representations for negative signed integers. Positive and unsigned integers are simply represented as a sequence of bits in binary notation. There may be padding bits as well, and signed integers have a single sign bit which must be 0 in the case of positive integers, so there is no guarantee that there are 8*sizeof(T) useful bits in the representation, even if the number of bits in a byte is known to be 8 (and, in theory, it could be larger). [Note 1]
The sign bit for negative signed integers is always 1, but there are three different formats for the value bits. The most common is "two's complement", where the value bits interpreted as a positive number would be exactly 2k more than the actual value of the number, where k is the number of value bits. (This is equivalent to specifying a weight of 2-k to the sign bits, which is why it is called 2s complement.)
Another alternative is "one's complement", in which the value bits are all inverted individually. This differs by exactly one from two's-complement representation.
The third allowable alternative is "sign-magnitude", in which the value bits are precisely the absolute value of the negative number. This representation is frequently used for floating point values, but only rarely used in integer values.
Both sign-magnitude and one's complement suffer from the disadvantage that there is a bit pattern which represents "negative 0". On the other hand, two's complement representation has the feature that the magnitude of the most negative representable value is one larger than the magnitude of the most positive representable value, with the result that both -x and x/-1 can overflow, leading to undefined behaviour.
Notes
I believe that it is theoretically possible for padding to be inserted between the value bits and the sign bits, but I certainly do not know of any real-world implementation with that feature. However, the fact that attempting to shift a 1 into the sign bit position is undefined behaviour makes it incorrect to assume that the sign bit is contiguous with the value bits.
I was thinking about ways to maximize a variable programmatically.
You are trying to reinvent the wheel. C++ STL already has this functionality: std::numeric_limits::max()
// x any kind of numeric type: any integer or any floating point value
x = std::numeric_limits<decltype(x)>::max();
This is also better since you will not relay on undefined behavior.
As harold commented, the solution is to use T(1) << i instead of 1 << i. Also as Some programmer dude mentioned, long long is represented as consecutive bytes (typically 8 bytes) with sign bit at the MSB if it is signed.
int main()
{
unsigned n;
cin>>n;
for(int i=(1<<31);i>0;i/=2)
(i&n)?(cout<<1):(cout<<0);
}
I ran the following code with n=1 but it prints nothing on the console. Changing the type of variable i to unsigned did the trick and printed 00000000000000000000000000000001. Any idea why?
Assuming two's complement, 1 << 31 results in a negative value, so your test for i > 0 fails immediately with the first test. You most likely would have had more luck with i != 0 then.
But we aware that 1 << 31 is a signed integer overflow, which is undefined behaviour anyway! So you should do 1U << 31 instead, too. If you assign this then positive value to a signed int, which is not capable to hold it, you have again undefined behaviour. So the correct for loop would look like this:
for(unsigned int i = 1U << 31; i > 0; i /= 2)
Although i /= 2 for unsigned values is equivalent to a bitshift (and is likely to be compiled to), I would prefere the bitshift operation explicitly here (i >>= 1), as this is what you actually intend.
Given that your platform is a 32-bit one, int i with a value of (i<<31) is a negative number. So, the execution never enters for-loop because you want i>0.
I'm new to C++ and is trying to learn the concept of array. I saw this code snippet online. For the sample code below, does it make any difference to declare:
unsigned scores[11] = {};
unsigned grade;
as:
int scores[11] = {};
int grade;
I guess there must be a reason why score[11] = {}; and grade is declared as unsigned, but what is the reason behind it?
int main() {
unsigned scores[11] = {};
unsigned grade;
while (cin >> grade) {
if (0 <= grade <= 100) {
++scores[grade / 10];
}
}
for (int i = 0; i < 11; i++) {
cout << scores[i] << endl;
}
}
unsigned means that the variable will not hold a negative values (or even more accurate - It will not care about the sign-). It seems obvious that scores and grades are signless values (no one scores -25). So, it is natural to use unsigned.
But note that: if (0 <= grade <= 100) is redundant. if (grade <= 100) is enough since no negative values are allowed.
As Blastfurnace commented, if (0 <= grade <= 100) is not right even. if you want it like this you should write it as:
if (0 <= grade && grade <= 100)
Unsigned variables
Declaring a variable as unsigned int instead of int has 2 consequences:
It can't be negative. It provides you a guarantee that it never will be and therefore you don't need to check for it and handle special cases when writing code that only works with positive integers
As you have a limited size, it allows you to represent bigger numbers. On 32 bits, the biggest unsigned int is 4294967295 (2^32-1) whereas the biggest int is 2147483647 (2^31-1)
One consequence of using unsigned int is that arithmetic will be done in the set of unsigned int. So 9 - 10 = 4294967295 instead of -1 as no negative number can be encoded on unsigned int type. You will also have issues if you compare them to negative int.
More info on how negative integer are encoded.
Array initialization
For the array definition, if you just write:
unsigned int scores[11];
Then you have 11 uninitialized unsigned int that have potentially values different than 0.
If you write:
unsigned int scores[11] = {};
Then all int are initialized with their default value that is 0.
Note that if you write:
unsigned int scores[11] = { 1, 2 };
You will have the first int intialized to 1, the second to 2 and all the others to 0.
You can easily play a little bit with all these syntax to gain a better understanding of it.
Comparison
About the code:
if(0 <= grade <= 100)
as stated in the comments, this does not do what you expect. In fact, this will always evaluate to true and therefore execute the code in the if. Which means if you enter a grade of, say, 20000, you should have a core dump. The reason is that this:
0 <= grade <= 100
is equivalent to:
(0 <= grade) <= 100
And the first part is either true (implicitly converted to 1) or false (implicitly converted to 0). As both values are lower than 100, the second comparison is always true.
unsigned integers have some strange properties and you should avoid them unless you have a good reason. Gaining 1 extra bit of positive size, or expressing a constraint that a value may not be negative, are not good reasons.
unsigned integers implement arithmetic modulo UINT_MAX+1. By contrast, operations on signed integers represent the natural arithmetic that we are familiar with from school.
Overflow semantics
unsigned has well defined overflow; signed does not:
unsigned u = UINT_MAX;
u++; // u becomes 0
int i = INT_MAX;
i++; // undefined behaviour
This has the consequence that signed integer overflow can be caught during testing, while an unsigned overflow may silently do the wrong thing. So use unsigned only if you are sure you want to legalize overflow.
If you have a constraint that a value may not be negative, then you need a way to detect and reject negative values; int is perfect for this. An unsigned will accept a negative value and silently overflow it into a positive value.
Bit shift semantics
Bit shift of unsigned by an amount not greater than the number of bits in the data type is always well defined. Until C++20, bit shift of signed was undefined if it would cause a 1 in the sign bit to be shifted left, or implementation-defined if it would cause a 1 in the sign bit to be shifted right. Since C++20, signed right shift always preserves the sign, but signed left shift does not. So use unsigned for some kinds of bit twiddling operations.
Mixed sign operations
The built-in arithmetic operations always operate on operands of the same type. If they are supplied operands of different types, the "usual arithmetic conversions" coerce them into the same type, sometimes with surprising results:
unsigned u = 42;
std::cout << (u * -1); // 4294967254
std::cout << std::boolalpha << (u >= -1); // false
What's the difference?
Subtracting an unsigned from another unsigned yields an unsigned result, which means that the difference between 2 and 1 is 4294967295.
Double the max value
int uses one bit to represent the sign of the value. unsigned uses this bit as just another numerical bit. So typically, int has 31 numerical bits and unsigned has 32. This extra bit is often cited as a reason to use unsigned. But if 31 bits are insufficient for a particular purpose, then most likely 32 bits will also be insufficient, and you should be considering 64 bits or more.
Function overloading
The implicit conversion from int to unsigned has the same rank as the conversion from int to double, so the following example is ill formed:
void f(unsigned);
void f(double);
f(42); // error: ambiguous call to overloaded function
Interoperability
Many APIs (including the standard library) use unsigned types, often for misguided reasons. It is sensible to use unsigned to avoid mixed-sign operations when interacting with these APIs.
Appendix
The quoted snippet includes the expression 0 <= grade <= 100. This will first evaluate 0 <= grade, which is always true, because grade can't be negative. Then it will evaluate true <= 100, which is always true, because true is converted to the integer 1, and 1 <= 100 is true.
Yes it does make a difference. In the first case you declare an array of 11 elements a variable of type "unsigned int". In the second case you declare them as ints.
When the int is on 32 bits you can have values from the following ranges
–2,147,483,648 to 2,147,483,647 for plain int
0 to 4,294,967,295 for unsigned int
You normally declare something unsigned when you don't need negative numbers and you need that extra range given by unsigned. In your case I assume that that by declaring the variables unsigned, the developer doesn't accept negative scores and grades. You basically do a statistic of how many grades between 0 and 10 were introduced at the command line. So it looks like something to simulate a school grading system, therefore you don't have negative grades. But this is my opinion after reading the code.
Take a look at this post which explains what unsigned is:
what is the unsigned datatype?
As the name suggests, signed integers can be negative and unsigned cannot be. If we represent an integer with N bits then for unsigned the minimum value is 0 and the maximum value is 2^(N-1). If it is a signed integer of N bits then it can take the values from -2^(N-2) to 2^(N-2)-1. This is because we need 1-bit to represent the sign +/-
Ex: signed 3-bit integer (yes there are such things)
000 = 0
001 = 1
010 = 2
011 = 3
100 = -4
101 = -3
110 = -2
111 = -1
But, for unsigned it just represents the values [0,7]. The most significant bit (MSB) in the example signifies a negative value. That is, all values where the MSB is set are negative. Hence the apparent loss of a bit in its absolute values.
It also behaves as one might expect. If you increment -1 (111) we get (1 000) but since we don't have a fourth bit it simply "falls off the end" and we are left with 000.
The same applies to subtracting 1 from 0. First take the two's complement
111 = twos_complement(001)
and add it to 000 which yields 111 = -1 (from the table) which is what one might expect. What happens when you increment 011(=3) yielding 100(=-4) is perhaps not what one might expect and is at odds with our normal expectations. These overflows are troublesome with fixed point arithmetic and have to be dealt with.
One other thing worth pointing out is the a signed integer can take one negative value more than it can positive which has a consequence for rounding (when using integer to represent fixed point numbers for example) but am sure that's better covered in the DSP or signal processing forums.
I want to write the program that Calculate 2^x mod n = 1 we have n is an integer but, we should calculate x.I wrote the code but my code work too slow in big n.Can you suggest me a good way that work less than 1 second to solve this problem.
here is my code:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long int n,cntr=1,cheak;
cin >> n;
while (1)
{
if (n % 2 == 0)
{
break;
}
cheak=pow(2, cntr);
if (cheak % n == 1)
break;
cntr++;
}
cout << cntr << endl;
}
Some suggested modifications to your current approach: Note: a better approach follows!
Change your long long int to unsigned long long int. This will give you one more bit.
Change while (1) to while (cntr < 64). The size of unsigned long long is likely only 64 bits. (It's guaranteed to be at least 64 bits, but not larger than that.) You would then need to check whether your loop succeeded, however.
Change cheak to calculate 2n as 1ull << cntr. Make sure to include the ull suffix, which says this is an unsigned long long.
The << operator shifts bits to the left. Shifting all the bits to the left by 1 doubles the integer value of the number, assuming no bits "shifted away" off the left of the value. So, 1 << n will compute 2n.
The suffix ull indicates an integer constant is an unsigned long long. If you omit this suffix, 1 will be treated as an integer, and shift values above 31 will not do what you want.
However, all of the above are merely refinements on your current approach. It's worth understanding those refinements to better understand the language. They don't, however, look at the bigger picture.
Modular multiplication allows you to find (A * B) mod C as ( (A mod C) * (B mod C) ) mod C. How does that help us here?
We can rewrite the entire algorithm in a way that only limits N and X to the precision of the machine integers, and not 2N:
int main()
{
unsigned int modulus;
unsigned int raised = 2;
int power = 1;
std::cin >> modulus;
if (modulus % 2 == 1)
{
while (raised % modulus != 1)
{
raised = ((unsigned long long)raised * 2) % modulus;
power++;
}
std::cout << power << std::endl;
} else
{
std::cout << "modulus must be odd" << std::endl;
}
}
The cast to unsigned long long above allows modulus to be as large as 232 - 1, assuming unsigned int is 32 bits, without the computation overflowing.
With this approach, I was able to very quickly find answers even for very large inputs. For example, 111111111 returns 667332. I verified 2677332 mod 111111111 == 1 using the arbitrary precision calculator bc.
It's very fast. It computed 22323860 mod 4294967293 == 1 in less than 0.07 seconds on my computer.
Epilog: This highlights an important principle in programming: Really, this was a math problem more than a programming problem. Finding an efficient solution required knowing more about the problem domain than it did knowing about C++. The actual C++ code was trivial once we identified the correct mathematical approach.
It often goes this way, whether it's the mathematics or some other algorithmic aspect. And, it shouldn't surprise you to learn that discrete mathematics is where many of our graph and set algorithms come from. The programming language itself is a small piece of the big picture.
For each k between 1 and ceil(sqrt(n)), compute 2^k mod n and 2^(k ceil(sqrt(n))) mod n. Then compute the modular inverse of each 2^k. Sort all of the inverse(2^k)s into an array foo and the 2^(k ceil(sqrt(n))s into an array bar. There will be at least one value in common between the two arrays; find it. Say inverse(2^a) = 2^(b ceil(sqrt(n))). Then 2^(a + b ceil(sqrt(n))) = 1 (mod n).
How's your professor's sense of humor?
#include <iostream>
int main() { std::cout << 0 << '\n'; }
always prints a correct answer to the problem as stated.
pow is quite expensive in calculations, but if you have 2 as its first argument, you can better do a shift left, as shift left is equal to multiplying by 2:
cheak = (1 << cntr);