I'm writing C code that converts from an integer to its binary representation, reverses the binary and then converts back to an integer. It's working well, but I need it to work for input values up to 10^9. Right now, it seems to break for anything larger than 10^7. What I mean is I put in a number such as 10000000 and get out 17967657062982931584 as being the binary representation (despite being accurate for smaller integers). In addition, I am not sure where my int_to_binary is the only function experiencing this problem, or if the others need to be optimized for large inputs as well. Any ideas where I'm going wrong? Thank you.
#include <stdio.h>
#include <string.h>
unsigned long long int_to_binary(unsigned long long k) {
if (k == 0) return 0;
if (k == 1) return 1;
return (k % 2) + 10 * int_to_binary(k/2);
}
unsigned long long reverse_int(unsigned long long l) {
unsigned long long reversed;
reversed = 0;
while (l > 0) {
reversed = reversed * 10 + (l%10);
l = l / 10;
}
return reversed;
}
unsigned long long binary_to_int(unsigned long long k) {
char binaryString[80];
snprintf(binaryString, 4, "%llu", k);
unsigned long long decimal = 0;
int length = strlen(binaryString);
int i = 0;
while(i < length) {
decimal = (decimal << 1) + (binaryString[i] - 0x30);
i++;
}
return decimal;
}
int main() {
int number;
printf("Enter a number: ");
scanf("%d", &number);
printf("You entered %d\n", number);
unsigned long long b = int_to_binary(number);
printf("In Binary, this is %llu\n", b);
unsigned long long c = reverse_int(b);
printf("When we reverse it, it looks like this: %llu\n", c);
unsigned long long d = binary_to_int(c);
printf("And when we convert that back to an int, it looks like this: %llu\n", d);
return 0;
}
You're using long long to represent a binary number as a decimal. On many architectures this results in the maximum value being stored of 2**64-1 = 18446744073709551615.
If you put in a decimal number such as 10000000, it cannot be represented as a decimal-binary number in 64 bits.
The problem is attempting to manipulate a binary number as a sum of powers of ten. It's more efficient to manipulate binary directly. Just change 10 to 2 in the reverse_int function.
unsigned long long reverse_int(unsigned long long l) {
unsigned long long reversed;
reversed = 0;
while (l > 0) {
reversed = reversed * 2 + (l%2);
l = l / 2;
}
return reversed;
}
In order to print numbers in binary, write a loop, testing each bit in sequence, using modulo % or bitwise operators like & and >>.
Related
This is a Luhn algorithm code and it works fine in an online complier but when I use it in my local vscode it is only giving 63 as output.
I dont know if its a memory issue as it late long variable.
i.e credit card number as input.
#include <stdio.h>
// Finds its Luhn algorithm to see if its a valid credit card number.
void checksum(long num)
{
int sum = 0;
for (int i = 0; num != 0; num /= 10, i++)
{
if (i % 2 == 0)
{
sum = sum + num % 10;
}
else
{
int digit = 2 * (num % 10);
sum = sum + (digit / 10) + (digit % 10);
}
}
printf("%d", sum);
}
int main()
{
long int num;
// Takes credit Card number as input.
do
{
printf("Number: ");
scanf("%li", &num);
} while (num < 0);
checksum(num);
return 0;
}
My inputs are like 374245455400126,378282246310005.
And output is always 63.
The result depends on the size of the type long int that can be equal either to the size of the type int or to the size of the type long long int.
So use the type long long int instead of the type long int.
Also as the program expects an unsigned value then instead of the signed type long long int it is even better to use the type unsigned long long int.
Sorry for this weird question but I'm only a beginner. I created a program with two while loops next to each other. The first while loop takes user input and repeats until input=0. When the second while loop begins, it takes the input = 0 from the first while loop. How to run the second while loop with original user input? Thank you.
unsigned long long int inp,inp1,rem,rem1,ans=0,ans1=0,place_value=1,place_value1=1;
printf("Please input binary for conversion:\n");
scanf("%llu", &input);
inp=input;
while (input>0){
rem=input%10;
ans=ans+rem*place_value;
input=input/10;
place_value=place_value*2;
}
while (input!=0){
rem1 = inp1 % 10;
ans1 = ans1 + rem * place_value1;
place_value1 = place_value1* 2;
inp1 = inp1 / 10;
}
printf("%d in Binary is %llu in Decimal Form.\n\n", inp,ans);
printf("%d in Binary is %d in Octal Form.\n", inp1,ans1);
printf("");
I finally found a fix without functions. Thank you to everyone for helping me. Declaring another variable was indeed the fix, I just needed to refine it a bit more.
else if(op=='B' || op=='b'){
unsigned long long int inp,rem=0,ans=0,place_value=1;
printf("You have chosen Binary to Decimal and Octal\n");
printf("Please input binary for conversion:\n");
scanf("%llu", &input);
inp=input;
while (input>0){
rem=input%10;
ans=ans+rem*place_value;
input=input/10;
place_value=place_value*2;
}
unsigned long long int rem1=0,ans1=0,place_value1=1;
input1=inp;
while (input1!=0){
rem1 = input1 % 10;
ans1 = ans1 + rem1 * place_value1;
place_value1 = place_value1 * 2;
input1 = input1 / 10;
}
printf("%llu in Binary is %llu in Decimal Form.\n\n", inp,ans);
printf("%llu in Binary is %o in Octal Form.\n", inp,ans1);
main();
}
You have way too many variables in your code. And similar names which only differ by some appended number is a mess. And you are mixing it all up. For instance you never assign a value to inp1 and you use input where it should have been inp1. You use rem where it should be rem1. It's too complicated... It's time to use functions...
unsigned long long int foo(unsigned long long int input)
{
unsigned long long int rem;
unsigned long long int ans=0;
unsigned long long int place_value=1;
while (input>0){
rem = input % 10;
ans = ans + rem * place_value;
input = input / 10;
place_value = place_value * 2;
}
return ans;
}
unsigned long long int bar(unsigned long long int input)
{
unsigned long long int rem;
unsigned long long int ans=0;
unsigned long long int place_value=1;
while (input!=0){
rem = input % 10;
ans = ans + rem * place_value;
place_value = place_value * 2;
input = input / 10;
}
return ans;
}
and then use the functions like
unsigned long long int input, ans_foo, ans_bar;
printf("Please input binary for conversion:\n");
scanf("%llu", &input);
ans_foo = foo(input);
ans_bar = bar(input);
printf("%d in Binary is %llu in Decimal Form.\n\n", input, ans_foo);
printf("%d in Binary is %d in Octal Form.\n", input, ans_bar);
printf("");
Note To me it seems that your two while loops are doing the same... but that's an unrelated mistake.
The easiest solution would be to define a new variable to store the input value.
unsigned long long int value = input
But I think this problem would be easier to resolve/read with recursion.
Here you have a working example.
unsigned long long int power(int base, unsigned int exponent)
{
if (exponent == 0)
return 1;
else
return base * power(base, exponent - 1);
}
I am working on a program where I need to take in a string of 8 characters (e.g. "I want t") then convert this into a long long int in the pack function. I have the pack function working fine.
unsigned long long int pack(char unpack[])
{
/*converting string to long long int here
didn't post code because its large*/
}
After I enter "I want t" I get "Value in Decimal = 5269342824372117620" and then I send the decimal to the unpack function. So I need to convert 5269342824372117620 back into "I want t". I tried bit manipulation which was unsuccessful any help would be greatly appreciated.
void unpack(long long int pack)
{
long long int bin;
char convert[100];
for(int i = 63, j = 0, k = 0; i >= 0; i--,j++)
{
if((pack & (1 << i)) != 0)
bin += power(2,j);
if(j % 8 == 0)
{
convert[k] = (char)bin;
bin = 0;
k++;
j = -1;
}
}
printf("String: %s\n", convert);
}
A simple solution for your problem is to consider the characters in the string to be digits in a large base that encompasses all possible values. For example base64 encoding can convert strings of 8 characters to 48-bit numbers, but you can only use a subset of at most 64 different characters in the source string.
To convert any 8 byte string into a number, you must use a base of at least 256.
Given your extra input, After I enter "I want t" I get "Value in Decimal = 5269342824372117620", and since 5269342824372117620 == 0x492077616e742074, you do indeed use base 256, big-endian order and ASCII encoding for the characters.
Here is a simple portable pack function for this method:
unsigned long long pack(const char *s) {
unsigned long long x = 0;
int i;
for (i = 0; i < 8; i++) {
x = x * 256 + (unsigned char)s[i];
}
return x;
}
The unpack function is easy to derive: compute the remainders of divisions in the reverse order:
char *unpack(char *dest, unsigned long long x) {
/* dest is assumed to have a length of at least 9 */
int i;
for (i = 8; i-- > 0; ) {
s[i] = x % 256;
x = x / 256;
}
s[8] = '\0'; /* set the null terminator */
return s;
}
For a potentially faster but less portable solution, you could use this, but you would get a different conversion on little-endian systems such as current Macs and PCs:
#include <string.h>
unsigned long long pack(const char *s) {
unsigned long long x;
memcpy(&x, s, 8);
return x;
}
char *unpack(char *s, unsigned long long x) {
memcpy(s, &x, 8);
s[8] = '\0';
return s;
}
I've been trying to print out the Binary representation of a long long integer using C Programming
My code is
#include<stdio.h>
#include <stdlib.h>
#include<limits.h>
int main()
{
long long number, binaryRepresentation = 0, baseOfOne = 1, remainder;
scanf("%lld", &number);
while(number > 0) {
remainder = number % 2;
binaryRepresentation = binaryRepresentation + remainder * baseOfOne;
baseOfOne *= 10;
number = number / 2;
}
printf("%lld\n", binaryRepresentation);
}
The above code works fine when I provide an input of 5 and fails when the number is 9223372036854775807 (0x7FFFFFFFFFFFFFFF).
1.Test Case
5
101
2.Test Case
9223372036854775807
-1024819115206086201
Using a denary number to represent binary digits never ends particularly well: you'll be vulnerable to overflow for a surprisingly small input, and all subsequent arithmetic operations will be meaningless.
Another approach is to print the numbers out as you go, but using a recursive technique so you print the numbers in the reverse order to which they are processed:
#include <stdio.h>
unsigned long long output(unsigned long long n)
{
unsigned long long m = n ? output(n / 2) : 0;
printf("%d", (int)(n % 2));
return m;
}
int main()
{
unsigned long long number = 9223372036854775807;
output(number);
printf("\n");
}
Output:
0111111111111111111111111111111111111111111111111111111111111111
I've also changed the type to unsigned long long which has a better defined bit pattern, and % does strange things for negative numbers anyway.
Really though, all I'm doing here is abusing the stack as a way of storing what is really an array of zeros and ones.
As Bathsheba's answer states, you need more space than is
available if you use a decimal number to represent a bit sequence like that.
Since you intend to print the result, it's best to do that one bit at a time. We can do this by creating a mask with only the highest bit set. The magic to create this for any type is to complement a zero of that type to get an "all ones" number; we then subtract half of that (i.e. 1111.... - 0111....) to get only a single bit. We can then shift it rightwards along the number to determine the state of each bit in turn.
Here's a re-worked version using that logic, with the following other changes:
I use a separate function, returning (like printf) the number of characters printed.
I accept an unsigned value, as we were ignoring negative values anyway.
I process arguments from the command line - I tend to find that more convenient that having to type stuff on stdin.
#include <stdio.h>
#include <stdlib.h>
int print_binary(unsigned long long n)
{
int printed = 0;
/* ~ZERO - ~ZERO/2 is the value 1000... of ZERO's type */
for (unsigned long long mask = ~0ull - ~0ull/2; mask; mask /= 2) {
if (putc(n & mask ? '1' : '0', stdout) < 0)
return EOF;
else
++printed;
}
return printed;
}
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
print_binary(strtoull(argv[i], 0, 10));
puts("");
}
}
Exercises for the reader:
Avoid printing leading zeros (hint: either keep a boolean flag that indicates you've seen the first 1, or have a separate loop to shift the mask before printing). Don't forget to check that print_binary(0) still produces output!
Check for errors when using strtoull to convert the input values from decimal strings.
Adapt the function to write to a character array instead of stdout.
Just to spell out some of the comments, the simplest thing to do is use a char array to hold the binary digits. Also, when dealing with bits, the bit-wise operators are a little more clear. Otherwise, I've kept your basic code structure.
int main()
{
char bits[64];
int i = 0;
unsigned long long number; // note the "unsigned" type here which makes more sense
scanf("%lld", &number);
while (number > 0) {
bits[i++] = number & 1; // get the current bit
number >>= 1; // shift number right by 1 bit (divide by 2)
}
if ( i == 0 ) // The original number was 0!
printf("0");
for ( ; i > 0; i-- )
printf("%d", bits[i]); // or... putchar('0' + bits[i])
printf("\n");
}
I am not sure what you really want to achieve, but here is some code that prints the binary representation of a number (change the typedef to the integral type you want):
typedef int shift_t;
#define NBITS (sizeof(shift_t)*8)
void printnum(shift_t num, int nbits)
{
int k= (num&(1LL<<nbits))?1:0;
printf("%d",k);
if (nbits) printnum(num,nbits-1);
}
void test(void)
{
shift_t l;
l= -1;
printnum(l,NBITS-1);
printf("\n");
l= (1<<(NBITS-2));
printnum(l,NBITS-1);
printf("\n");
l= 5;
printnum(l,NBITS-1);
printf("\n");
}
If you don't mind to print the digits separately, you could use the following approach:
#include<stdio.h>
#include <stdlib.h>
#include<limits.h>
void bindigit(long long num);
int main()
{
long long number, binaryRepresentation = 0, baseOfOne = 1, remainder;
scanf("%lld", &number);
bindigit(number);
printf("\n");
}
void bindigit(long long num) {
int remainder;
if (num < 2LL) {
printf("%d",(int)num);
} else {
remainder = num % 2;
bindigit(num/2);
printf("%d",remainder);
}
}
Finally I tried a code myself with idea from your codes which worked,
#include<stdio.h>
#include<stdlib.h>
int main() {
unsigned long long number;
int binaryRepresentation[70], remainder, counter, count = 0;
scanf("%llu", &number);
while(number > 0) {
remainder = number % 2;
binaryRepresentation[count++] = remainder;
number = number / 2;
}
for(counter = count-1; counter >= 0; counter--) {
printf("%d", binaryRepresentation[counter]);
}
}
I am writing a very basic program to print the range of an unsigned long long variable in C language (0 to ((2 ^ n) - 1) where n is the number of bits for the data type in any system (with C installed in it and according to the compiler). In my system, the size of a long long variable is 8 bytes.
I am using the following code:
#include<stdio.h>
#include<math.h>
int main()
{
unsigned long long n;
//n = pow(2, 63);
//n = (n * 2) - 1;
n = pow(2, 64) - 1;
printf("\nn: %llu\n", n);
return 0;
}
upon compiling, gcc gives me the following error:
Print_long_long_int.c:10:2: warning: overflow in implicit constant conversion [-Woverflow].
On executing it, I get the correct output of
n: 18446744073709551615
But, if I remove the single comments from the lines, and use them:
n = pow(2, 63);
n = (n * 2) - 1;
Instead of:
n = pow(2, 64) - 1;
It doesn't give me any such warning. And executes normally.
Why is this discrepancy happening?
Thanks!
When you are giving
pow(2,64) -1 ;
It exceeds the limit of unsigned long long. This is the reason you are getting that warning.
Range of unsigned long is 0 to 18,446,744,073,709,551,615
Result of pow(2,64) is 18446744073709551616.
Power should return an integer, and you're getting an unsigned long long. I just made a simple power function to handle unsigned long longs.
#include<stdio.h>
unsigned long long power(int base, int exponent)
{
unsigned long long n = 1;
int i;
for (i = 0; i < exponent ; i++)
n *= base;
return n;
}
int main()
{
unsigned long long n = power(2, 64) - 1;
printf("n: %llu\n", n);
return 0;
}