How to convert decimal to binary in 64 bits? - c

so I have this code
int main()
{
int n, c, k;
printf("Enter an integer\n");
scanf("%d", &n);
printf("%d in binary is:\n", n);
for (c = 31; c >= 0; c--)
{
k = n >> c;
if (k & 1)
printf("1");
else
printf("0");
}
printf("\n");
return 0;
}
It converts decimal into binary but only in 32 bits. When I change it into 64 bits it doesn't work (it seems like it just doubles the result from 32 bits). At the same time it works fine with 8 or 4 bits etc.
What am I doing wrong?

It converts decimal into binary but only in 32 bits. When I change it into 64 bits it doesn't work (it seems like it just doubles the result from 32 bits).
The problem is here.
int n, c, k;
printf("Enter an integer\n");
scanf("%d", &n);
n is an int which can be as small as 16 bits. It could be 64 bits, but it's probably 32 bits. When you try to enter a 64 bit number you'll get garbage.
#include <stdio.h>
int main() {
int n;
printf("sizeof(int) == %zu\n", sizeof(int));
printf("Enter an integer\n");
scanf("%d", &n);
printf("n = %d\n", n);
}
$ ./test
sizeof(int) == 4
Enter an integer
12345678901
n = -539222987
Instead, you can use a long long int which has a minimum size of 64 bits or int64_t from stdint.h which is exactly 64 bits. I have a preference for using the explicit width types in code that requires a specific width to make it more obvious to the reader.
long long int uses %lld for scanf and printf while int64_t uses macros from inttypes.h. The code below takes advantage of C automatically concatenating constant strings; "foo" "bar" and "foobar" are equivalent.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main() {
int64_t n;
printf("Enter an integer\n");
scanf("%"SCNd64, &n);
printf("n = %"PRId64"\n", n);
}
$ ./test
Enter an integer
12345678901
n = 12345678901

The problem is your n & k variables' data type. They are integer. Check your platform's data type size using sizeof(int).
When you change to 64-bits, these variables can't hold 64-bit values.
HTH!

the following code is one way to handle the problem:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
long long unsigned int n;
long long int c;
long long unsigned int k;
printf("Enter an integer\n");
if( 1 != scanf("%llu", &n) )
{
perror( "scanf for 64 bit number failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
printf("%llu in binary is:\n", n);
for (c = 63; c >= 0; c--)
{
k = n >> c;
if (k & 1)
putc('1', stdout);
else
putc('0', stdout);
}
printf("\n");
return 0;
} // end function: main
and here is the output from a typical run of the program:
Enter an integer
6789097860397846
6789097860397846 in binary is:
0000000000011000000111101010011000000110010100000111101100010110

Related

Problem to return and printf unsigned long

I don't understand why my code is still printing int values (that are overflown) while I want unsigned long values!
There is my code :
#include <stdio.h>
unsigned long factorial(int num) {
if ((num == 0) || (num == 1 )) {
return 1;
} else if (num < 0) {
return 0;
} else {
return num * factorial(num - 1);
}
}
int main(void) {
int num;
char liste;
printf("Choisir un nombre pour trouver son factoriel : ");
//Translation : "Choose a number to find its factorial" 🥖
scanf("%d", &num);
printf("factoriel de %d : %lu\n", num, factorial(num));
}
It is a very basic code to return factorial value but I'm just a beginner.
The factorial function grows very fast. Just about no matter what type you use for your computations, it's going to overflow pretty soon.
On a machine where type unsigned long has 32 bits (which is all that's guaranteed), your program can correctly compute 12! = 479001600 (but nothing larger). I suspect that's what you're seeing.
On a machine where type unsigned long has 64 bits, your program can correctly compute 20! = 2432902008176640000. (My machine has 64-bit longs, and I used your program to compute this result, and it worked fine.)
So your program is actually fine; I can't see anything wrong with it. (Well, there's an unused variable liste, and a stray loaf of bread in a comment. :-) )
If your compiler and C library both support type long long, you can try this to increase the range on your machine:
#include <stdio.h>
unsigned long long factorial(int num) {
if (num < 0) {
return 0;
} else if (num <= 1 ) {
return num;
} else {
return num * factorial(num - 1);
}
}
int main(void) {
int num;
printf("Choisir un nombre pour trouver son factoriel : ");
scanf("%d", &num);
printf("factoriel de %d : %llu\n", num, factorial(num));
}
But, again, this'll only get you up to 20!. (In this version I have also cleaned up the logic of your factorial function slightly.)
If %llu doesn't work, you can try %Lu.
Some compilers support a 128-bit type (I think gcc calls it _uint128_t or something like that), and this could theoretically get you up to 34! = 295232799039604140847618609643520000000.
But beyond that you'd have to use a "multiple precision" or "arbitrary precision" library such as GMP. For example, 100! has 525 bits, and 1000! has 8530 bits.

How to find the number of digits int digits in c upto 100 or 1000 digits?

This is my code:`
#include <stdio.h>
void main() {
int n;
int count = 0;
printf("Enter an integer: ");
scanf("%d", &n);
// iterate until n becomes 0
// remove last digit from n in each iteration
// increase count by 1 in each iteration
while (n != 0) {
n /= 10; // n = n/10
++count;
}
printf("Number of digits: %lld", count);
}
I am able to run the code finely but when I enter 15 or 16 digits of number as input then it always shows me that the number of digits is 10. And another problem with this code is that suppose if I input 000 then I want the output to be 3 digits but this code is not able to do that as the condition in the while loop becomes instantly false. So how write a code that enables me to take upto 100 or 1000 digits as input and also enables me to input 0s as well.
Note: This program should be solved using a loop and in C language
I found a answer to the question here in stackoverflow written in c++ that I couldn't even understand as I am a beginner and I am learning C.
Link to the answer:
How can I count the number of digits in a number up to 1000 digits in C/C++
Instead of reading a number, read a string and count the digits:
#include <stdio.h>
int main() {
char buffer[10000];
int n;
printf("Enter an integer: ");
if (scanf("%9999s", buffer) == 1) {
for (n = 0; buffer[n] >= '0' && buffer[n] <= '9'; n++)
continue;
printf("Number of digits: %d\n", n);
}
return 0;
}
You can also use the scanf() scanset feature to perform the test in one step:
#include <stdio.h>
int main() {
char buffer[10000];
int n;
printf("Enter an integer: ");
if (scanf("%9999[0-9]%n", buffer, &n) == 1) {
printf("Number of digits: %d\n", n);
}
return 0;
}
32 bits signed integer has the max value equals 2,147,483,647 so, if you input a bigger one, it will not be stored. I'd make it receiving a string and get its length, like so:
#include <stdio.h>
#include <string.h>
int len = strlen("123123123123132");
You are taking int variable and you are trying to count a number like whose digit is 100 or 1000. it will not fit with int. so take input as a string and count the length of string.

Can't get right answer

PROBLEM: Create a loop that, for a positive integer n, finds the biggest integer k for which n ≥ 2k. (We are essentially finding the integer log base-2 of n.) Do not use pow, log2, or any functions from math.h to implement this!
Last printf statement doesn't work.
My solution:
#include <stdio.h>
int main(void){
int k=1, n, j=2;
printf("Enter positive number: ");
scanf("%d", &n);
while(n>=j*k){
k++;
}
printf("k: %d", k);
return 0;
}
It works,
beside the result is incorrect, you may want to print the k-1 value.
Reason you are not seeing it may depend on missing "\n" at the end of printf() which do not refresh the output buffer
In addition to #Jack's (correct) answer, you might consider a different solution to the problem: use bit shifting operations. Given the problem asks for log base 2, one can count the number of "shift right" operations that are required to make n zero.
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
int k = -1;
unsigned long int n;
if (argc != 2) {
fprintf(stderr, "usage: %s n\n", argv[0]);
return 1;
}
n = strtoul(argv[1], NULL, 0);
while (n) {
k++;
// Shift the bits in n to the right by one place. Equivalent to n /= 2.
n >>= 1;
}
printf("%d\n", k);
return 0;
}

Why does C outputs gibberish results when operation on an integer greater than 10 digits?

The code given below works fine up-to 10 digits with (int data-type) , but for numbers exceeding 10 digits it failed , so i tried unsigned long long int. But now my output is fixed to 15 , idk why? Consider me very new to C , i have mediocre python background though!
I am using gcc (Ubuntu 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609
#include <stdio.h> //Get number of digits in a int
unsigned long long int get_len();
void main() {
unsigned long long int num;
printf("Enter the number:");
scanf("%d",&num);
printf("\nThe length of number is is: %d \n",get_len(num));
}
unsigned long long int get_len(unsigned long long int z) {
unsigned long long int i = 1;
while (1) {
if ((z/10) > 1) {
//printf("Still greater than 1");
i++;
z = z/10;
continue;}
else {
return(i+1);
break;}}}
You have used wrong format specifier. it would be scanf("%llu",&num);
Using the wrong format specifer in scanf is undefined behavior.
Apart from what is being mentioned, your length finding logic is wrong in that it will fail for single digit numbers and also for multidigit one.
For 1 it will return number of digits 2 and similarly for other numbers. (like for 12 it will return 3).
For larger numbers you will have options of opting an library (big number processing) or write one of as you need.
I would scan the numbers like this
if( scanf("%llu",&num) != 1) { /* error */}. More clearly check the return value of scanf.
Here's another implementation. This fixes a few issues:
Main return type must be int.
unsigned int is more than sufficient as get_len() return type.
unsigned int and unsigned are the same. Also unsigned long long int can be stripped of int.
#include <stdio.h>
unsigned get_len();
int main()
{
unsigned long long num;
printf("Enter the number: ");
scanf("%llu", &num);
printf("\nThe length of number is: %u\n", get_len(num));
}
unsigned get_len(unsigned long long z)
{
return (z / 10 > 0) ? get_len(z / 10) + 1 : 1;
}

Issue with a program in C to check if a number is divisible by 100

I wrote a program in C to check if the entered number is divisible by 100, but I've run into a problem. If I enter a number with 11 digits or more (with the last two digits being zeroes, of course), it says the number is not divisible by 100, even though it is. Help?
#include <stdio.h>
#include <conio.h>
int main()
{
long int a;
printf("Enter the number: ");
scanf("%d" , &a);
if(a%100==0)
{printf("This number is divisible by 100");}
else
{printf("This number is not divisible by 100");}
getch();
}
Your number just doesn't fit into long int type, so the actual number you get is not what you expect. Try using unsigned long long, but be aware that numbers greater than 2^64 - 1 won't fit anyway. Also, you should use scanf("%llu", &a) in this case
One of the many reasons why scanf should never be used is that numeric overflow provokes undefined behavior. Your C library seems to produce a garbage value on overflow.
If you write the program using getline and strtol, then you can safely check for overflow and print a proper error message:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int
main(void)
{
char *linebuf = 0;
size_t linebufsz = 0;
ssize_t len;
char *endp;
long int val;
for (;;) {
fputs("Enter a number (blank line to quit): ", stdout);
len = getline(&linebuf, &linebufsz, stdin);
if (len < 0) {
perror("getline");
return 1;
}
if (len < 2)
return 0; /* empty line or EOF */
/* chomp */
if (linebuf[len-1]) == '\n')
linebuf[len--] = '\0';
/* convert and check for overflow */
errno = 0;
val = strtol(linebuf, &endp, 10);
if ((ssize_t)(endp - linebuf) != len) {
fprintf(stderr, "Syntactically invalid number: %s\n", linebuf);
continue;
}
if (errno) {
fprintf(stderr, "%s: %s\n", strerror(errno), linebuf);
continue;
}
if (val % 100 == 0)
printf("%ld is divisible by 100\n", val);
else
printf("%ld is not divisible by 100\n", val);
}
}
I tested this on a machine where long is 64 bits wide, so it can do most but not all 19-digit numbers:
Enter a number (blank line to quit): 1234567890123456789
1234567890123456789 is not divisible by 100
Enter a number (blank line to quit): 12345678901234567890
Numerical result out of range: 12345678901234567890
Enter a number (blank line to quit): 9223372036854775807
9223372036854775807 is not divisible by 100
Enter a number (blank line to quit): 9223372036854775808
Numerical result out of range: 9223372036854775808
I suspect that on your computer long is only 32 bits wide, so the limit will instead be 2147483647 for you.

Resources