#include <iostream>
#include <math.h>
using namespace std;
// converting from decimal to binary
int main()
{
int n, bit, ans = 0, i = 0;
cout << "enter a number: ";
cin >> n;
while (n > 0)
{
bit = n & 1;
ans = round(bit * pow(10, i)) + ans; /* we used 'round' bcoz pow(10, 2) give 99.99999
it differs from compiler to compiler */
n = n >> 1;
i++;
}
cout << ans;
return 0;
}
I am unable to understand that in while(n>0), n will be stored as binary form or decimal form.
That is if n=5, so whether while loop check for (5>0) or (101>0).
Can anyone explain what is happening here?
I am new to this platform, please don't delete my question. My earlier questions are also gets deleted due enough dislikes. I am here to learn and am still learning.
"Decimal" and "Binary" are text representations of a value. n is an int, not text, so it holds the value 5. If I have 5 apples on a desk, then there is no "decimal" or "binary" involved. THere's just 5 apples. Same with int.
cin >> n;
while (n > 0)
This loop continues because 5 > 0.
n = n >> 1;
This is just a fancy way of writing n = n / 2, so then n becomes 2. Since 2 > 0, the loop continues. On the third run, n becomes 1, and since 1 > 0, the loop continues a third time. On the fourth run, n becomes 0, and 0 == 0, so the while loop exits.
Both n and ans are integers that your computer stores in a binary format. If n = 5 then n is both 5 and 0b0101. Your loop converts one integer n into a second integer ans which only uses the digits 1 and 0 and looks like the integer n in binary.
It does this by converting each power of two in n into a power of ten and adding it into ans. The integer 5 will become the integer 101 (one hundred and one).
In the loop, when you use the bitwise operator >> you are manipulating the underlying binary representation of the number directly, in this case, shifting all of the bits in the integer to the right and feeding in zeros on the left to replace the bits that have moved.
So, if n is 5 then:
0b0101 >> 1 gives 0b0010, or 2
0b0101 >> 2 gives 0b0001, or 1
0b0101 >> 3 gives 0b0000, or 0
When you use the bitwise operator & (bitwise and) you are again operating directly on the binary representation. This time you are and-ing all of the bits in one number with the bit in another number. For example:
0b01100110 & 0b10101110 = 0b00100110
0b01100110 & 0b10011001 = 0b00000000
In your loop you are doing four things:
1. bit = n & 1
And-ing the integer n with one will mean that bit is equal to:
1 when there is a 1 in the 2^0 place (the least significant bit) and,
0 when there is not a 1 in the 2^0 place.
2. ans = round(bit * pow(10, i)) + ans
You take 10^i and multiply it by bit. So:
bit is zero this is zero
if bit is one this is some power of ten.
3. n = n >> 1
Shift one place to the right. The bit that was in the 2^1 place is now in the 2^0 place.
4. i++
Increment i which tracks both your current power of 2 and current power of ten.
#Mooing Duck has explained it incredibly well. I'd just add that you are being confused about the Number System
Decimal numbers are called the base 10 numbers (digits: 0 - 9, total: 10)
Binary numbers are called the base 2 numbers(digits/bits: 0 - 1, total: 2)
101 (base 10) is very different from 101 (base 2)
When we use bitwise operators such as (<<, >>, &, ^, |) we manipulate the bits of the decimal (hence the name bitwise operators)
So, when you are doing 5 >> 1 you are actually doing 101 (base 2) >> 1 which results in 010 (base 2)
When you keep shifting the bits to the right(equivalent to dividing by 2), at one point you'll be left with no 1s and only 0s. And what's 0 (base 2)? Its 0(base 10). Hence, the loop breaks.
Related
I have a question, which is to find the modulo 11 of a large number. The number is stored in a string whose maximum length is 1000. I want to code it in c++. How should i go about it?
I tried doing it with long long int, but its impossible that it can handle the corner case value.
A number written in decimal positional system as a_na_{n-1}...a_0 is the number
a_n*10^n+a_{n-1}*10^{n-1}+...+a_0
Note first that this number and the number
a_0-a_{1}+a_{2}+...+(-1)^{n}a_n
which is the sum of its digits with alternating signs have the same remainder after division by 11. You can check that by subtracting both numbers and noting that the result is a multiple of 11.
Based on this, if you are given a string consisting of the decimal representation of a number, then you can compute the remainder modulo 11 like this:
int remainder11(const std::string& s) {
int result{0};
bool even{true};
for (int i = s.length() - 1; i > -1; --i) {
result += (even ? 1 : -1) * ((int)(s[i] - '0'));
even = !even;
}
return ((result % 11) + 11) % 11;
}
Ok, here is the magic (math) trick.
First imagine you have a decimal number that consists only of 1s.
Say 111111, for example. It is obvious that 111111 % 11 is 0. (Since you can always write it as the sum of a series of 11*10^n). This can be generalized to all integers consists purely of even numbers of ones. (e.g. 11, 1111, 11111111). For those with odd number of ones, just subtract one from it and you will get a 10 times some number that consists of odd numbers of one (e.g 111=1+11*10), so their modulo to 11 would be 1.
A decimal number can be always written as the form of
where a0 is the least significant digit and an is the most significant digit. Note that 10^n can be written as 10^n - 1 + 1, and 10^n - 1 is a number consists of n nines. If n is even, then you will get 9 times some even number of ones, and its modulo to 11 is always 0. If n is odd, then we get 9 times some odd number of ones, and its modulo to 11 is always 9. And don't forget we've still got a +1 after 10^n - 1 + 1 so we need to add a to the result.
We are very close to our results now: we just have to add things up and do a final modulo to 11. The pseudo-code would be like:
Initialize sum to 0.
Initialize index to 0.
For every digit d from the least to most significant:
If the index is even, sum += d
Otherwise, sum += 10 * d
++index
sum %= 11
Return sum % 11
I'm being requested to write a C++ program that computes the n-th number that doesn't contain a given digit and the time execution to be lower than 0.1 seconds. Memory doesn't seem to be an issue, as I'm allowed the use of up to 64 MB.
The original text of the problem goes like this:
Cifra4
To represent numbers, it was decided not to use the digit C
again.
Thus, from the array of natural numbers, all numbers containing the
digit C will be erased. Let the new array be S.
Requirements
1) Determine the N-th number in S.
2) Y and Z are two natural
numbers from the array of all natural numbers. Determine the number of
natural numbers removed from Y to Z.
Input data
The input file cifra4.in contains the first number T representing the
type of requirement. If T == 1, the second row will contain
the digit C and the number N. If T == 2, the
second line will contain the digit C and two natural numbers Yand
Z.
Output data
In the output file cifra4.out will contain in the first row
one natural number according to the type of requirement.
Restrictions and clarifications
1 ≤ N ≤ 10 ^ 13
0 ≤ C ≤ 9
1 ≤ Y ≤ 10 ^ 13
1 ≤ Z ≤ 10 ^ 13
for 20% of the tests, N will have a maximum of 5 digits
for 20% of the tests, Y and Z will have a maximum of 6 digits
Example 1
cifra4.in
1
0 11
cifra4.out
12
Example 2
cifra4.in
2
1 3 20
cifra4.out
10
My best try was a code that determined (or at least was supposed to) the n-th number that doesn't contain the digit "0", but for 10 ^ 13 it returned 23210987654321, which obviously contains 0.
My slower, but correct approach was what I ended up keeping. Here is the code:
#include <fstream>
std::ifstream in("cifra4.in");
std::ofstream out("cifra4.out");
const long long pow_of_10[14] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
10000000000, 100000000000, 1000000000000};
void req_1 ()
{
short digit;
long long n;
in >> digit >> n;
for (long long i = 0; i <= n; i++)
{
long long nr = i;
if (nr)
{
long k = 1;
do
{
if (nr % 10 == digit)
{
n += pow_of_10[k];
i += pow_of_10[k] - 1;
break;
}
nr /= 10;
k++;
}
while (nr);
}
else if (digit == 0) n++;
}
out << n - 1;
}
void req_2()
{
short digit;
long long lhs, rhs;
long long elim = 0;
in >> digit >> lhs >> rhs;
for (long long i = lhs; i <= rhs; i++)
{
long long nr = i;
while (nr)
{
if (nr % 10 == digit)
{
elim++;
break;
}
nr /= 10;
}
}
out << elim;
}
int main()
{
short requirement;
in >> requirement;
if (requirement == 1)
req_1();
else
req_2();
}
NOTE
I'm not asking for code necesarily, but for ideas, possible algorithms that can execute up to 10 ^ 13 in decent time, preferably the time requested by the problem, but 1 second will do fine for me.
Imagine that 9 is the forbidden digit. In this case you can just convert your number to base-9 and you're done.
Now, what happens when the forbidden digit is different, say d? It's still a base-9 number but you have to map your digits, such that digits below d remain unaffected, and d and above are mapped to the digit d + 1.
For example, when the forbidden digit is 7 and n is 125.
Step 1: convert to base-9: 12510 = 1489
Step 2: map the digits. 1 → 1, 4 → 4, 8 → 9
The solution is 149.
Since the decimal digits of a number are "independent" of each other, in that setting one digit does not affect any other digits - once you've fixed a prefix of (at least one) more-significant digits, leaving n' less-significant digits, you know you have exactly (10 - 1)^n' = 9^n' numbers with that prefix and no forbidden digits in the unfixed part. For example, for 3-digit numbers beginning with 1, there are exactaly 81 numbers with no 0 in them.
The only 'snag' here is that setting the most-significant digit to zero means that you get the same number for different numbers of digits (012, 0012 etc.). But you should be able to work around this issue as well - by determining how many digits you're going to need for the n'th number without your forbidden digit. Very similar to the argument I described above. Then you know you have 10-1 = 9 options there if your forbidden digit is 0 or 10-2 = 8 otherwise.
Suppose I have two numbers(minimum and maximum) . `
for example (0 and 9999999999)
maximum could be so huge. now I also have some other number. it could be between those minimum and maximum number. Let's say 15. now What I need to do is get all the multiples of 15(15,30,45 and so on, until it reaches the maximum number). and for each these numbers, I have to count how many 1 bits there are in their binary representations. for example, 15 has 4(because it has only 4 1bits).
The problem is, I need a loop in a loop to get the result. first loop is to get all multiples of that specific number(in our example it was 15) and then for each multiple, i need another loop to count only 1bits. My solution takes so much time. Here is how I do it.
unsigned long long int min = 0;
unsigned long long int max = 99999999;
unsigned long long int other_num = 15;
unsigned long long int count = 0;
unsigned long long int other_num_helper = other_num;
while(true){
if(other_num_helper > max) break;
for(int i=0;i<sizeof(int)*4;i++){
int buff = other_num_helper & 1<<i;
if(buff != 0) count++; //if bit is not 0 and is anything else, then it's 1bits.
}
other_num_helper+=other_num;
}
cout<<count<<endl;
Look at the bit patterns for the numbers between 0 and 2^3
000
001
010
011
100
101
110
111
What do you see?
Every bit is one 4 times.
If you generalize, you find that the numbers between 0 and 2^n have n*2^(n-1) bits set in total.
I am sure you can extend this reasoning for arbitrary bounds.
Here's how I do it for a 32 bit number.
std::uint16_t bitcount(
std::uint32_t n
)
{
register std::uint16_t reg;
reg = n - ((n >> 1) & 033333333333)
- ((n >> 2) & 011111111111);
return ((reg + (reg >> 3)) & 030707070707) % 63;
}
And the supporting comments from the program:
Consider a 3 bit number as being 4a + 2b + c. If we shift it right 1 bit, we have 2a + b. Subtracting this from the original gives 2a + b + c. If we right-shift the original 3-bit number by two bits, we get a, and so with another subtraction we have a + b + c, which is the number of bits in the original number.
The first assignment statement in the routine computes 'reg'. Each digit in the octal representation is simply the number of 1’s in the corresponding three bit positions in 'n'.
The last return statement sums these octal digits to produce the final answer. The key idea is to add adjacent pairs of octal digits together and then compute the remainder modulus 63.
This is accomplished by right-shifting 'reg' by three bits, adding it to 'reg' itself and ANDing with a suitable mask. This yields a number in which groups of six adjacent bits (starting from the LSB) contain the number of 1’s among those six positions in n. This number modulo 63 yields the final answer. For 64-bit numbers, we would have to add triples of octal digits and use modulus 1023.
I have the following code
int n = 50;
while(n) { //1
if(n & 1) cout << "1" << endl; //2
//right shift the number so n will become 0 eventually and the loop will terminate
n >>= 1; //3
}
When we use bitwise and 1 (& 1) with a number we get back the same number.
Now my question is how does c++ evaluates the following expression: n & 1.
Since:
n = 50
In binary form 50 is: 110010
If we bitwise 1 then we get: AND 1 = 110010
Now in c++ (2) the expression evaluates like this:
Instead of getting the whole sequence of bits (110010) bitwise anded with 1
it evaluates only the number of right bits we bitwise. In my example:
n=50, 110010, use n & 1 ==> 0 AND 1 instead of 110010 AND 1.
Is there a reason that c++ treats the bitwise and like this? My guess would be it has to do with the compiler ?
When we use bitwise and 1 (& 1) with a number we get back the same number.
No we don't. We get back the number consisting of the bits that are set in both the original number and in 1. Since only the lowest bit of 1 is set, the result is the lowest bit of the original number.
Now my question is how does c++ evaluates the following expression: n & 1.
If n is 50, then in binary:
n: 110010
1: 000001
n&1: 000000 // no bits set in both
If n is 51, then in binary:
n: 110011
1: 000001
n&1: 000001 // one bit set in both
From Wikipedia:
The bitwise AND operator is a single ampersand: &. It is just a representation of AND which does its work on the bits of the operands rather than the truth value of the operands. Bitwise binary AND does the logical AND (as shown in the table above) of the bits in each position of a number in its binary form.
In your example 110010 & 1, 1 is considered as 000001, and then each bit is anded and you get the result. In fact, I use this method: 1&number to check for even and odd numbers. This is how:
if(1 & num)
printf("it is odd");
else
printf("it is even");
This is how it works: suppose you have an 8 bit number. Now, the 8 bit notation of 1 will be 00000001.
If I now perform and on each bit, for all the first seven bits I will get 0, because it will be 0 & anything will be 0. Now, the last bit of 1 is 1. So, if my number also has last bit as 1, then 1 & 1 = 1, and if my last bit is 0, then 1 & 0 = 0.
When will the last bit in my number be 1? And when 0? When converting to decimal form, the last bit is multiplied by 20. And, 20 = 1. If this 1 is multiplied with 1, we get an odd number, and if it is multiplied with 0, we get an even number.
This code converts decimal integer into binary. This is working perfectly. I know this has been done using recursion method...but I am not understanding how the parameter is working on the line 8 of this function. thanks in advance :) .
void binary(int number) {
int remainder;
if(number <= 1) {
cout << number;
return;
}
remainder = number%2;
binary(number >> 1);
cout << remainder;
}
In most "C inspired languages*", the operator >> represents the right (bitwise) shift operator. So the code
binary(number >> 1);
passes a value to the recursive call to binary(), which is shifted by one bit to the right (i.e. the same as integer division by 2).
The recursion stops when the number is <= 1, i.e. there are no more powers of 2 to divide the remaining number through by.
In the interim, the modulo 2 (% 2) remainder for the call is held over and written after the inner recursive call, so that it will retain the correct position in the power of 2.
e.g.
12 Decimal
/ 2 = 6 remainder 0 // printed fourth
/ 2 = 3 remainder 0 // printed third
/ 2 = 1 remainder 1 // printed second
> <= 1 so Print 1 // printed first
So 1100 will be printed.
* Wikipedias terminology