This program is supposed to determine how many units are stored in the value of the variable c_val, if each unit is stored as a set bit.
My question is: why did the author write if (c % 2 == 1) count++; then shift c to the right with this statement c = c >> 1;?
#include <stdio.h>
#include <cstdlib>
int main(){
unsigned char c_val;
printf("char value = ");
scanf("%c", &c_val);
int count = 0;
unsigned char c = c_val;
while(c){
if (c % 2 == 1) count++;
c = c >> 1;
}
printf("%d bits are set", count);
system("pause");
}
The data size of type char is always one byte - no exceptions. This code, however, calculates the popcount - that is, the number of 1 bits - in c_val.
We can translate the relevant code from
while (c) {
if (c % 2 == 1) count++;
c = c >> 1;
}
to
while (c != 0) {
if (c & 0x1 == 1) count++; /* if the rightmost bit of c is 1, then count++ */
c = c / 2;
}
The last change I made works because right-shifting an unsigned integral data type (in this case, unsigned char) is equivalent to dividing by 2, with round-toward-zero semantics.
We can think of c as a conveyor belt of bits - zero bits come in from the left, and one bit falls off the right on each loop iteration. If the rightmost bit is a 1, we increase the count by 1, and otherwise the count remains unchanged. So, once c is filled with zero bits, we know that we have counted all the one bits, and exactly the one bits, so count contains the number of one bits in c_val.
This isn't a function to determine the "size" of instances of the type char at all, but rather to determine the number of bits in a character that are set to 1.
The expression
c % 2 == 1
determines whether or not the least significant bit is a 1.
The shifting brings the second to last bit into the last position so it can be tested.
The condition while (c) means to keep counting 1s and shifting until the whole byte is all zeros.
Your code is just coding how many 1 bits in char c. "c % 2 === 1" checks if the last bit in "c" is 1. So we must use "c = c >> 1" to shift the other bits in "c" to the last position.
Other way to do the same:
#include <stdio.h>
#include <conio.h>
unsigned int f (unsigned int a , unsigned int b);
unsigned int f (unsigned int a , unsigned int b)
{
return a ? f ( (a&b) << 1, a ^b) : b;
}
int bitcount(int n) {
int tot = 0;
int i;
for (i = 1; i <= n; i = i<<1)
if (n & i)
++tot;
return tot;
}
int bitcount_sparse_ones(int n) {
int tot = 0;
while (n) {
++tot;
n &= n - 1;
}
return tot;
}
int main()
{
int a = 12;
int b = 18;
int c = f(a,b);
printf("Sum = %d\n", c);
int CountA = bitcount(a);
int CountB = bitcount(b);
int CntA = bitcount_sparse_ones(a);
int CntB = bitcount_sparse_ones(b);
printf("CountA = %d and CountB = %d\n", CountA, CountB);
printf("CntA = %d and CntB = %d\n", CntA, CntB);
getch();
return 0;
}
Related
I have written a C++ program to find all the automorphic numbers (numbers which are repeated in the final digits of their squares such as 5x5=25, 76x76=5776) from 1 to 111,111. The program runs fine except that it fails to give 90625 and 109376. The code is as follows:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
long int square;
int a, sum = 0, result, b;
for (int i = 1; i < 111111; i++) {
result = 1;
b = i;
while (b > 0){
b = b / 10;
result = result * 10;
}
square = i * i;
a = square % result;
if(i == a){
sum = sum + i;
cout << i << endl;
}
}
cout << sum << endl;
return 0;
}
Long int has only 4 bytes
long 4 bytes -2,147,483,648 to 2,147,483,647
unsigned long 4 bytes 0 to 4,294,967,295
The square of 90625 and 109376 are 8,212,890,625 and 11,963,109,376 respectively. So as the values overflow, you won't be able to produce those two values in long int limit. You can use integer type long long.
long long 8 bytes –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
unsigned long long 8 bytes 0 to 18,446,744,073,709,551,615
And if you want to use bigger numbers you can handle them using Arrays or let libraries like GMP to handle larger numbers.
I write this code for show fibonacci series using recursion.But It not show correctly for n>43 (ex: for n=100 show:-980107325).
#include<stdio.h>
#include<conio.h>
void fibonacciSeries(int);
void fibonacciSeries(int n)
{
static long d = 0, e = 1;
long c;
if (n>1)
{
c = d + e;
d = e;
e = c;
printf("%d \n", c);
fibonacciSeries(n - 1);
}
}
int main()
{
long a, n;
long long i = 0, j = 1, f;
printf("How many number you want to print in the fibonnaci series :\n");
scanf("%d", &n);
printf("\nFibonacci Series: ");
printf("%d", 0);
fibonacciSeries(n);
_getch();
return 0;
}
The value of fib(100) is so large that it will overflow even a 64 bit number. To operate on such large values, you need to do arbitrary-precision arithmetic. Arbitrary-precision arithmetic is not provided by C nor C++ standard libraries, so you'll need to either implement it yourself or use a library written by someone else.
For smaller values that do fit your long long, your problem is that you use the wrong printf format specifier. To print a long long, you need to use %lld.
Code overflows the range of the integer used long.
Could use long long, but even that may not handle Fib(100) which needs at least 69 bits.
Code could use long double if 1.0/LDBL_EPSILON > 3.6e20
Various libraries exist to handle very large integers.
For this task, all that is needed is a way to add two large integers. Consider using a string. An inefficient but simply string addition follows. No contingencies for buffer overflow.
#include <stdio.h>
#include <string.h>
#include <assert.h>
char *str_revese_inplace(char *s) {
char *left = s;
char *right = s + strlen(s);
while (right > left) {
right--;
char t = *right;
*right = *left;
*left = t;
left++;
}
return s;
}
char *str_add(char *ssum, const char *sa, const char *sb) {
const char *pa = sa + strlen(sa);
const char *pb = sb + strlen(sb);
char *psum = ssum;
int carry = 0;
while (pa > sa || pb > sb || carry) {
int sum = carry;
if (pa > sa) sum += *(--pa) - '0';
if (pb > sb) sum += *(--pb) - '0';
*psum++ = sum % 10 + '0';
carry = sum / 10;
}
*psum = '\0';
return str_revese_inplace(ssum);
}
int main(void) {
char fib[3][300];
strcpy(fib[0], "0");
strcpy(fib[1], "1");
int i;
for (i = 2; i <= 1000; i++) {
printf("Fib(%3d) %s.\n", i, str_add(fib[2], fib[1], fib[0]));
strcpy(fib[0], fib[1]);
strcpy(fib[1], fib[2]);
}
return 0;
}
Output
Fib( 2) 1.
Fib( 3) 2.
Fib( 4) 3.
Fib( 5) 5.
Fib( 6) 8.
...
Fib(100) 3542248xxxxxxxxxx5075. // Some xx left in for a bit of mystery.
Fib(1000) --> 43466...about 200 more digits...8875
You can print some large Fibonacci numbers using only char, int and <stdio.h> in C.
There is some headers :
#include <stdio.h>
#define B_SIZE 10000 // max number of digits
typedef int positive_number;
struct buffer {
size_t index;
char data[B_SIZE];
};
Also some functions :
void init_buffer(struct buffer *buffer, positive_number n) {
for (buffer->index = B_SIZE; n; buffer->data[--buffer->index] = (char) (n % 10), n /= 10);
}
void print_buffer(const struct buffer *buffer) {
for (size_t i = buffer->index; i < B_SIZE; ++i) putchar('0' + buffer->data[i]);
}
void fly_add_buffer(struct buffer *buffer, const struct buffer *client) {
positive_number a = 0;
size_t i = (B_SIZE - 1);
for (; i >= client->index; --i) {
buffer->data[i] = (char) (buffer->data[i] + client->data[i] + a);
buffer->data[i] = (char) (buffer->data[i] - (a = buffer->data[i] > 9) * 10);
}
for (; a; buffer->data[i] = (char) (buffer->data[i] + a), a = buffer->data[i] > 9, buffer->data[i] = (char) (buffer->data[i] - a * 10), --i);
if (++i < buffer->index) buffer->index = i;
}
Example usage :
int main() {
struct buffer number_1, number_2, number_3;
init_buffer(&number_1, 0);
init_buffer(&number_2, 1);
for (int i = 0; i < 2500; ++i) {
number_3 = number_1;
fly_add_buffer(&number_1, &number_2);
number_2 = number_3;
}
print_buffer(&number_1);
}
// print 131709051675194962952276308712 ... 935714056959634778700594751875
Best C type is still char ? The given code is printing f(2500), a 523 digits number.
Info : f(2e5) has 41,798 digits, see also Factorial(10000) and Fibonacci(1000000).
Well, you could want to try implementing BigInt in C++ or C.
Useful Material:
How to implement big int in C++
For this purporse you need implement BigInteger. There is no such build-in support in current c++. You can view few advises on stack overflow
Or you also can use some libs like GMP
Also here is some implementation:
E-maxx - on Russian language description.
Or find some open implementation on GitHub
Try to use a different format and printf, use unsigned to get wider range of digits.
If you use unsigned long long you should get until 18 446 744 073 709 551 615 so until the 93th number for fibonacci serie 12200160415121876738 but after this one you will get incorrect result because the 94th number 19740274219868223167 is too big for unsigned long long.
Keep in mind that the n-th fibonacci number is (approximately) ((1 + sqrt(5))/2)^n.
This allows you to get the value for n that allows the result to fit in 32 /64 unsigned integers. For signed remember that you lose one bit.
I'm trying to find a way to find the length of an integer (number of digits) and then place it in an integer array. The assignment also calls for doing this without the use of classes from the STL, although the program spec does say we can use "common C libraries" (gonna ask my professor if I can use cmath, because I'm assuming log10(num) + 1 is the easiest way, but I was wondering if there was another way).
Ah, and this doesn't have to handle negative numbers. Solely non-negative numbers.
I'm attempting to create a variant "MyInt" class that can handle a wider range of values using a dynamic array. Any tips would be appreciated! Thanks!
Not necessarily the most efficient, but one of the shortest and most readable using C++:
std::to_string(num).length()
The number of digits of an integer n in any base is trivially obtained by dividing until you're done:
unsigned int number_of_digits = 0;
do {
++number_of_digits;
n /= base;
} while (n);
There is a much better way to do it
#include<cmath>
...
int size = trunc(log10(num)) + 1
....
works for int and decimal
If you can use C libraries then one method would be to use sprintf, e.g.
#include <cstdio>
char s[32];
int len = sprintf(s, "%d", i);
"I mean the number of digits in an integer, i.e. "123" has a length of 3"
int i = 123;
// the "length" of 0 is 1:
int len = 1;
// and for numbers greater than 0:
if (i > 0) {
// we count how many times it can be divided by 10:
// (how many times we can cut off the last digit until we end up with 0)
for (len = 0; i > 0; len++) {
i = i / 10;
}
}
// and that's our "length":
std::cout << len;
outputs 3
Closed formula for the longest int (I used int here, but works for any signed integral type):
1 + (int) ceil((8*sizeof(int)-1) * log10(2))
Explanation:
sizeof(int) // number bytes in int
8*sizeof(int) // number of binary digits (bits)
8*sizeof(int)-1 // discount one bit for the negatives
(8*sizeof(int)-1) * log10(2) // convert to decimal, because:
// 1 bit == log10(2) decimal digits
(int) ceil((8*sizeof(int)-1) * log10(2)) // round up to whole digits
1 + (int) ceil((8*sizeof(int)-1) * log10(2)) // make room for the minus sign
For an int type of 4 bytes, the result is 11. An example of 4 bytes int with 11 decimal digits is: "-2147483648".
If you want the number of decimal digits of some int value, you can use the following function:
unsigned base10_size(int value)
{
if(value == 0) {
return 1u;
}
unsigned ret;
double dval;
if(value > 0) {
ret = 0;
dval = value;
} else {
// Make room for the minus sign, and proceed as if positive.
ret = 1;
dval = -double(value);
}
ret += ceil(log10(dval+1.0));
return ret;
}
I tested this function for the whole range of int in g++ 9.3.0 for x86-64.
int intLength(int i) {
int l=0;
for(;i;i/=10) l++;
return l==0 ? 1 : l;
}
Here's a tiny efficient one
Being a computer nerd and not a maths nerd I'd do:
char buffer[64];
int len = sprintf(buffer, "%d", theNum);
Would this be an efficient approach? Converting to a string and finding the length property?
int num = 123
string strNum = to_string(num); // 123 becomes "123"
int length = strNum.length(); // length = 3
char array[3]; // or whatever you want to do with the length
How about (works also for 0 and negatives):
int digits( int x ) {
return ( (bool) x * (int) log10( abs( x ) ) + 1 );
}
Best way is to find using log, it works always
int len = ceil(log10(num))+1;
Code for finding Length of int and decimal number:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int len,num;
cin >> num;
len = log10(num) + 1;
cout << len << endl;
return 0;
}
//sample input output
/*45566
5
Process returned 0 (0x0) execution time : 3.292 s
Press any key to continue.
*/
There are no inbuilt functions in C/C++ nor in STL for finding length of integer but there are few ways by which it can found
Here is a sample C++ code to find the length of an integer, it can be written in a function for reuse.
#include<iostream>
using namespace std;
int main()
{
long long int n;
cin>>n;
unsigned long int integer_length = 0;
while(n>0)
{
integer_length++;
n = n/10;
}
cout<<integer_length<<endl;
return 0;
}
Here is another way, convert the integer to string and find the length, it accomplishes same with a single line:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
long long int n;
cin>>n;
unsigned long int integer_length = 0;
// convert to string
integer_length = to_string(n).length();
cout<<integer_length<<endl;
return 0;
}
Note: Do include the cstring header file
The easiest way to use without any libraries in c++ is
#include <iostream>
using namespace std;
int main()
{
int num, length = 0;
cin >> num;
while(num){
num /= 10;
length++;
}
cout << length;
}
You can also use this function:
int countlength(int number)
{
static int count = 0;
if (number > 0)
{
count++;
number /= 10;
countlength(number);
}
return count;
}
#include <math.h>
int intLen(int num)
{
if (num == 0 || num == 1)
return 1;
else if(num < 0)
return ceil(log10(num * -1))+1;
else
return ceil(log10(num));
}
Most efficient code to find length of a number.. counts zeros as well, note "n" is the number to be given.
#include <iostream>
using namespace std;
int main()
{
int n,len= 0;
cin>>n;
while(n!=0)
{
len++;
n=n/10;
}
cout<<len<<endl;
return 0;
}
I want to convert an integer to binary string and then store each bit of the integer string to an element of a integer array of a given size. I am sure that the input integer's binary expression won't exceed the size of the array specified. How to do this in c++?
Pseudo code:
int value = ???? // assuming a 32 bit int
int i;
for (i = 0; i < 32; ++i) {
array[i] = (value >> i) & 1;
}
template<class output_iterator>
void convert_number_to_array_of_digits(const unsigned number,
output_iterator first, output_iterator last)
{
const unsigned number_bits = CHAR_BIT*sizeof(int);
//extract bits one at a time
for(unsigned i=0; i<number_bits && first!=last; ++i) {
const unsigned shift_amount = number_bits-i-1;
const unsigned this_bit = (number>>shift_amount)&1;
*first = this_bit;
++first;
}
//pad the rest with zeros
while(first != last) {
*first = 0;
++first;
}
}
int main() {
int number = 413523152;
int array[32];
convert_number_to_array_of_digits(number, std::begin(array), std::end(array));
for(int i=0; i<32; ++i)
std::cout << array[i] << ' ';
}
Proof of compilation here
You could use C++'s bitset library, as follows.
#include<iostream>
#include<bitset>
int main()
{
int N;//input number in base 10
cin>>N;
int O[32];//The output array
bitset<32> A=N;//A will hold the binary representation of N
for(int i=0,j=31;i<32;i++,j--)
{
//Assigning the bits one by one.
O[i]=A[j];
}
return 0;
}
A couple of points to note here:
First, 32 in the bitset declaration statement tells the compiler that you want 32 bits to represent your number, so even if your number takes fewer bits to represent, the bitset variable will have 32 bits, possibly with many leading zeroes.
Second, bitset is a really flexible way of handling binary, you can give a string as its input or a number, and again you can use the bitset as an array or as a string.It's a really handy library.
You can print out the bitset variable A as
cout<<A;
and see how it works.
You can do like this:
while (input != 0) {
if (input & 1)
result[index] = 1;
else
result[index] =0;
input >>= 1;// dividing by two
index++;
}
As Mat mentioned above, an int is already a bit-vector (using bitwise operations, you can check each bit). So, you can simply try something like this:
// Note: This depends on the endianess of your machine
int x = 0xdeadbeef; // Your integer?
int arr[sizeof(int)*CHAR_BIT];
for(int i = 0 ; i < sizeof(int)*CHAR_BIT ; ++i) {
arr[i] = (x & (0x01 << i)) ? 1 : 0; // Take the i-th bit
}
Decimal to Binary: Size independent
Two ways: both stores binary represent into a dynamic allocated array bits (in msh to lsh).
First Method:
#include<limits.h> // include for CHAR_BIT
int* binary(int dec){
int* bits = calloc(sizeof(int) * CHAR_BIT, sizeof(int));
if(bits == NULL) return NULL;
int i = 0;
// conversion
int left = sizeof(int) * CHAR_BIT - 1;
for(i = 0; left >= 0; left--, i++){
bits[i] = !!(dec & ( 1u << left ));
}
return bits;
}
Second Method:
#include<limits.h> // include for CHAR_BIT
int* binary(unsigned int num)
{
unsigned int mask = 1u << ((sizeof(int) * CHAR_BIT) - 1);
//mask = 1000 0000 0000 0000
int* bits = calloc(sizeof(int) * CHAR_BIT, sizeof(int));
if(bits == NULL) return NULL;
int i = 0;
//conversion
while(mask > 0){
if((num & mask) == 0 )
bits[i] = 0;
else
bits[i] = 1;
mask = mask >> 1 ; // Right Shift
i++;
}
return bits;
}
I know it doesn't add as many Zero's as you wish for positive numbers. But for negative binary numbers, it works pretty well.. I just wanted to post a solution for once :)
int BinToDec(int Value, int Padding = 8)
{
int Bin = 0;
for (int I = 1, Pos = 1; I < (Padding + 1); ++I, Pos *= 10)
{
Bin += ((Value >> I - 1) & 1) * Pos;
}
return Bin;
}
This is what I use, it also lets you give the number of bits that will be in the final vector, fills any unused bits with leading 0s.
std::vector<int> to_binary(int num_to_convert_to_binary, int num_bits_in_out_vec)
{
std::vector<int> r;
// make binary vec of minimum size backwards (LSB at .end() and MSB at .begin())
while (num_to_convert_to_binary > 0)
{
//cout << " top of loop" << endl;
if (num_to_convert_to_binary % 2 == 0)
r.push_back(0);
else
r.push_back(1);
num_to_convert_to_binary = num_to_convert_to_binary / 2;
}
while(r.size() < num_bits_in_out_vec)
r.push_back(0);
return r;
}
I made a function that converts numbers to binary. For some reason it's not working. It gives the wrong output. The output is in binary format, but it always gives the wrong result for binary numbers that end with a zero(at least that's what I noticed..)
unsigned long long to_binary(unsigned long long x)
{
int rem;
unsigned long long converted = 0;
while (x > 1)
{
rem = x % 2;
x /= 2;
converted += rem;
converted *= 10;
}
converted += x;
return converted;
}
Please help me fix it, this is really frustrating..
Thanks!
Use std::bitset to do the translation:
#include <iostream>
#include <bitset>
#include <limits.h>
int main()
{
int val;
std::cin >> val;
std::bitset<sizeof(int) * CHAR_BIT> bits(val);
std::cout << bits << "\n";
}
You're reversing the bits.
You cannot use the remains of x as an indicator when to terminate the loop.
Consider e.g. 4.
After first loop iteration:
rem == 0
converted == 0
x == 2
After second loop iteration:
rem == 0
converted == 0
x == 1
And then you set converted to 1.
Try:
int i = sizeof(x) * 8; // i is now number of bits in x
while (i>0) {
--i;
converted *= 10;
converted |= (x >> i) & 1;
// Shift x right to get bit number i in the rightmost position,
// then and with 1 to remove any bits left of bit number i,
// and finally or it into the rightmost position in converted
}
Running the above code with x as an unsigned char (8 bits) with value 129 (binary 10000001)
Starting with i = 8, size of unsigned char * 8. In the first loop iteration i will be 7. We then take x (129) and shift it right 7 bits, that gives the value 1. This is OR'ed into converted which becomes 1. Next iteration, we start by multiplying converted with 10 (so now it's 10), we then shift x 6 bits right (value becomes 2) and ANDs it with 1 (value becomes 0). We OR 0 with converted, which is then still 10. 3rd-7th iteration do the same thing, converted is multiplied with 10 and one specific bit is extracted from x and OR'ed into converted. After these iterations, converted is 1000000.
In the last iteration, first converted is multiplied with 10 and becomes 10000000, we shift x right 0 bits, yielding the original value 129. We AND x with 1, this gives the value 1. 1 is then OR'ed into converted, which becomes 10000001.
You're doing it wrong ;)
http://www.bellaonline.com/articles/art31011.asp
The remain of the first division is the rightmost bit in the binary form, with your function it becomes the leftmost bit.
You can do something like this :
unsigned long long to_binary(unsigned long long x)
{
int rem;
unsigned long long converted = 0;
unsigned long long multiplicator = 1;
while (x > 0)
{
rem = x % 2;
x /= 2;
converted += rem * multiplicator;
multiplicator *= 10;
}
return converted;
}
edit: the code proposed by CygnusX1 is a little bit more efficient, but less comprehensive I think, I'll advise taking his version.
improvement : I changed the stop condition of the while loop, so we can remove the line adding x at the end.
You are actually reversing the binary number!
to_binary(2) will return 01, instead of 10. When initial 0es are truncated, it will look the same as 1.
how about doing it this way:
unsigned long long digit = 1;
while (x>0) {
if (x%2)
converted+=digit;
x/=2;
digit*=10;
}
What about std::bitset?
http://www.cplusplus.com/reference/stl/bitset/to_string/
If you want to display you number as binary, you need to format it as a string. The easiest way to do this that I know of is to use the STL bitset.
#include <bitset>
#include <iostream>
#include <sstream>
typedef std::bitset<64> bitset64;
std::string to_binary(const unsigned long long int& n)
{
const static int mask = 0xffffffff;
int upper = (n >> 32) & mask;
int lower = n & mask;
bitset64 upper_bs(upper);
bitset64 lower_bs(lower);
bitset64 result = (upper_bs << 32) | lower_bs;
std::stringstream ss;
ss << result;
return ss.str();
};
int main()
{
for(int i = 0; i < 10; ++i)
{
std::cout << i << ": " << to_binary(i) << "\n";
};
return 1;
};
The output from this program is:
0: 0000000000000000000000000000000000000000000000000000000000000000
1: 0000000000000000000000000000000000000000000000000000000000000001
2: 0000000000000000000000000000000000000000000000000000000000000010
3: 0000000000000000000000000000000000000000000000000000000000000011
4: 0000000000000000000000000000000000000000000000000000000000000100
5: 0000000000000000000000000000000000000000000000000000000000000101
6: 0000000000000000000000000000000000000000000000000000000000000110
7: 0000000000000000000000000000000000000000000000000000000000000111
8: 0000000000000000000000000000000000000000000000000000000000001000
9: 0000000000000000000000000000000000000000000000000000000000001001
If your purpose is only display them as their binary representation, then you may try itoa or std::bitset
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
unsigned long long x = 1234567890;
// c way
char buffer[sizeof(x) * 8];
itoa (x, buffer, 2);
printf ("binary: %s\n",buffer);
// c++ way
cout << bitset<numeric_limits<unsigned long long>::digits>(x) << endl;
return EXIT_SUCCESS;
}
void To(long long num,char *buff,int base)
{
if(buff==NULL) return;
long long m=0,no=num,i=1;
while((no/=base)>0) i++;
buff[i]='\0';
no=num;
while(no>0)
{
m=no%base;
no=no/base;
buff[--i]=(m>9)?((base==16)?('A' + m - 10):m):m+48;
}
}
Here is a simple solution.
#include <iostream>
using namespace std;
int main()
{
int num=241; //Assuming 16 bit integer
for(int i=15; i>=0; i--) cout<<((num >> i) & 1);
cout<<endl;
for(int i=0; i<16; i++) cout<<((num >> i) & 1);
cout<<endl;
return 0;
}