How to convert very large binary to decimal in C - c

I'm using netBean to code C, and my assignment is convert a very large binary number to decimal ( the binary number maybe upto 100 digits), I'm very confuse because my program works when the binary number is about 50-60 digits but it will automatically crash on run-time when input is larger. I'm using long long int to store the decimal result but it seem doesn't work!
Here is my code :
long long int decimal = 0;
int position = 0;
for(int i = strlen(binaryInput)-1; i>=0; --i){
if(binaryInput[i]=='1'){
decimal += (long long int)(pow(2,position));
}
++position;
}
printf("\nDecimal number is: %lli ", decimal);
'binaryInput' is my string to store binaryNumber from keyboard.

Here is a hint:
The easiest solution is to actually take the long binary number, and split it in half (or quarters, or whatever.)
Keep track of which of these is the upper range of the binary number, and which of these is the lower end of the binary number.
Calculate what the true value of the lower range, and upper range is. After that add them together.

long long int has a range of -9,223,372,036,854,775,807 to 9,223,372,036,854,775,807, as mentioned here. There is no way that 100 bits can fit in there. However, this type is signed, you could try with an unsigned one, but I do not see any assumption on your numbers to be non-negative.
You could try with int128_t which fits 128-bit signed, but this is not Standard (Why isn't there int128_t?).
Consider using an array of size 100, where each cell will store a digit. With this approach it is suggested that you use Double dabble algorithm, which is used to convert binary numbers into binary-coded decimal (BCD) notation.
If you need a library, then The GNU Multiple Precision Arithmetic Library could do the trick.
PS: Use bit-shifts instead of pow(), since it will operate on floating-point values, and will decrease the performance of your code.

Not sure if this is the most optimized technique. This can calculate up to 1000 digit. You can increase the array allocation to calculate longer binary numbers
I used strings for input and high school mathematics technique for addition and calculate the power of 2
#include <bits/stdc++.h>
typedef long long int lli;
using namespace std;
int main() {
char bin_number[1010];
//variable for big integer operation
int int_number[1010], t_int_number[500];
/*
* int_number : converted decimal number will be stored here
* t_int_number : will be used to calculate the power of 2
*/
int bin_length, t_int_length, int_length, index;
/*
* bin_length : length(bin_number)
* t_int_length : length(t_int_length)
* int_length : length(int_length)
*/
bool carry;
while(scanf("%s", bin_number) != EOF) { //input binary number
for (int i = 0; i < 500; i++) { //intialize decimal number to 0 and t_int_number to 0
int_number[i] = 0;
t_int_number[i] = 0;
}
//set t_int_number to 1
t_int_number[0] = 1;
t_int_length = 1;
//set the int_number to 0
int_length = 1;
index = 0;
//calculate input length
bin_length = strlen(bin_number);
for (int i = bin_length - 1; i >= 0; i--) { //checks each digit of binary number
//if the digit in binary representation is 1
if (bin_number[i] == '1') {
//sum (int_number, t_int_number)
for (int index = 0; index < t_int_length; index++) {
int_number[index] +=
t_int_number[index]; //sum t_int_number digits
if (int_number[index] > 9) { //if carry
int_number[index + 1] ++;
int_number[index] -= 10;
}
}
int_length = index;
if (int_number[index] != 0) { //i f length increase for addition
int_length ++;
}
}
//Being ready for next iteration
//multiplying everytime with 2 and save it to t_int_number
carry = false;
for (index = 0; index < t_int_length; index++) {
t_int_number[index] += t_int_number[index]; //double the number
}
for (index = 0; index < t_int_length; index++) {
if (t_int_number[index] > 9) {
t_int_number[index] -= 10;
t_int_number[index + 1]++;
}
}
if (t_int_number[index] != 0) {
t_int_length++;
}
}
//printing the decimal number
for (int i = int_length - 1; i >=0; i--) {
printf("%d", int_number[i]);
}
printf("\n");
}
return 0;
}

Related

Decimal to binary - For loop prints the binary in reverse mode

Background on what the code is supposed to do, vs what I am achieving.
So the dec2bin function is supposed to get the values/numbers decimal from the array dec_nums[]={0, 1, 77, 159, 65530, 987654321};
the function is supposed to convert the value to binary numbers and print it out.
the conversion is done correctly however, it prints the binary backward.
Can someone help me on figuring out what the problem is, or if there is another way to achieve the correct results?
int main() {
int dec_nums[] = {0, 1, 77, 159, 65530, 987654321};
int i;
printf("=== dec2bin ===\n");
for (i = 0; i < sizeof(dec_nums) / sizeof(int); i++)
dec2bin(dec_nums[i]);
return 0;
}
void dec2bin(int num) {
int saveNum = num;
if (saveNum == 0) {
printf("\nBinary Number of %d", saveNum);
printf(" = 0");
} else {
int number;
int i;
printf("\nBinary Number of %i", saveNum);
printf(" = ");
for (i = 0; num > 0; i++) {
number = num % 2;
num = num / 2;
printf("%i", number);
}
printf("\n");
}
}
For bit fiddling unsigned types are preferrable, you avoid any kinds of problems with undefined behaviour due to under-/overflow.
Apart from, you can operate on bit masks:
for(unsigned mask = 1u << sizeof(mask) * CHAR_BIT - 1; mask; mask >>= 1)
{
unsigned bit = (value & mask) != 0;
// print it
}
CHAR_BIT is the value of bits within a char and comes from header limits.h, typically (but not necessarily) it is 8, with typically four bytes for ints you initialise the mask to 1 << 31 and further on shift it downwards until it reaches 1 << 0, i. e. 1, which is the last value yet considered. Yet another shift moves the single bit set out of the mask, so you get 0 and the loop aborts.
Above code will print leading zeros, you might prepend another loop that simply shifts down until the first 1-bit is met if you want to skip them.
This variant starts at most significant bit; by % 2 you always get the least significant bit instead – which is why you got the inverse order.
Side note: Getting length of an array is better done as sizeof(array)/sizeof(*array) – this avoids errors if you need to change the underlying type of the array...
A simple solution would be to write to bits into a char array, starting from the end of the array, the same way that we would do by hand.
Your dec2bin function would become (only minimal changes, with comments for added or changed lines):
void dec2bin(int num)
{
// declare a char array of size number_of_bits_in_an_int + 1 for the terminating null
char bin[sizeof(int) * CHAR_BIT + 1];
char* ix = bin + sizeof(bin) - 1; // make ix point to the last char
*ix-- = '\0'; // and write the terminating null
int saveNum = num;
if (saveNum == 0)
{
printf("\nBinary Number of %d", saveNum);
printf(" = 0");
}
else
{
int number;
int i;
printf("\nBinary Number of %i", saveNum);
printf(" = ");
for (i = 0; num > 0; i++)
{
number = num % 2;
num = num / 2;
*ix-- = '0' + number; // just write the bit representatin
}
printf("%s\n", ix+1); //print the binary representation
}
}
That is enough to get the expected result.

How to manipulate the decimals in an integer? CS50 Luhn's Algorithm

I want to add all the digits of an array and get the sum from them. The thing i'm struggling with is I have to multiply the numbers I get from my input by which makes an array have the possibility of two digits in one array.
An example number would be 8346761.
The challenge wants me to take every other digit (6,6,3), then multiply them (12,12,6) and add the first digits together like (1+2+1+2+6)=12. I only know how to do 12+12+6=30 and was looking for help on this specific part.
I'm new to programming and also stack overflow so if there is anything I did wrong asking the question please tell me so I can fix it. Thank you
#include <cs50.h>
#include <stdio.h>
int main(void)
{
long long cardNum = get_long_long("What is your credit card number?\n");
printf("Number: %lld\n", cardNum);
long long cardNumz = cardNum;
long long Multnumbers[20];
cardNum /= 10;
for (long long i=0; i < 20; i++)
{
Multnumbers[i] = cardNum % 10;
Multnumbers[i] *= 2;
cardNum /= 100;
}
int sum = 0;
int loop;
for(loop = 0; loop < 20; loop++)
{
printf("%lld ", Multnumbers[loop]);
}
printf("\n");
long long number=Multnumbers[0];
for (long long rz=1;rz<11;rz++)
{
number = number*10+Multnumbers[rz];
}
printf("Big multiple number is %lld\n ", number);
long long Nonmultnumbers[20];
for (long long i=0; i < 20; i++)
{
Nonmultnumbers[i] = cardNumz % 10;
cardNumz /= 100;
}
int loopn;
for(loopn = 0; loopn < 20; loopn++)
printf("Non multnumbers%lld ", Nonmultnumbers[loopn]);
printf("\n");
If I understood correctly, you want to take digits (1 and 2) in two digit number (12) to calculate sum. Easiest way might be dividing these numbers with 10 to calculate first digit. And using remainder operator to calculate second digits.
Calculation of first digit. (This division won't give 1.2 as long as numbers are integers).
int n = 12 / 10 // n will be 1 (1st digit).
Calculation of second digit. Using remainder operator, %.
int rem = 12 % 10 // rem will be 2 (2nd digit).

Finding numbers with unique digits in C

I have to write a program that finds every number (except 0) which can be factored by numbers from 2-9.
For example first such a number would be number 2520 as it can be divided by every single number from 2 to 9.
It also has to be a number that contains only 1 type of digit of its own (no multiple digits in a number). So for example 2520 will not meet this requirement since there are two same digits (2). The example of a number that meets both requirements is number 7560. That is the point I don't how to do it. I was thinking about converting value in an array to string, and then putting this string in another array so every digit would be represented by one array entry.
#include <stdio.h>
#include <math.h>
int main() {
int i, n, x, flag, y = 0;
scanf("%d", &n);
double z = pow(10, n) - 1;
int array[(int)z];
for (i = 0; i <= z; i++) {
flag = 0;
array[i] = i;
if (i > 0) {
for (x = 2; x <= 9; x++) {
if (array[i] % x != 0) {
flag = 1;
}
}
if (flag == 0) {
y = 1;
printf("%d\n", array[i]);
}
}
}
if (y == 0) {
printf("not exist");
}
return 0;
}
This should give you a base:
#include <stdio.h>
#include <string.h>
int main()
{
char snumber[20];
int number = 11235;
printf("Number = %d\n\n", number);
sprintf(snumber, "%d", number);
int histogram[10] = { 0 };
int len = strlen(snumber);
for (int i = 0; i < len; i++)
{
histogram[snumber[i] - '0']++;
}
for (int i = 0; i < 10; i++)
{
if (histogram[i] != 0)
printf("%d occurs %d times\n", i, histogram[i]);
}
}
Output:
Number = 11235
1 occurs 2 times
2 occurs 1 times
3 occurs 1 times
5 occurs 1 times
That code is a mess. Let's bin it.
Theorem: Any number that divides all numbers in the range 2 to 9 is a
multiple of 2520.
Therefore your algorithm takes the form
for (long i = 2520; i <= 9876543210 /*Beyond this there must be a duplicate*/; i += 2520){
// ToDo - reject if `i` contains one or more of the same digit.
}
For the ToDo part, see How to write a code to detect duplicate digits of any given number in C++?. Granted, it's C++, but the accepted answer ports verbatim.
If i understand correctly, your problem is that you need to identify whether a number is consisted of multiple digits.
Following your proposed approach, to convert the number into a string and use an array to represent digits, i can suggest the following solution for a function that implements it. The main function is used to test the has_repeated_digits function. It just shows a way to do it.
You can alter it and use it in your code.
#include <stdio.h>
#define MAX_DIGITS_IN_NUM 20
//returns 1 when there are repeated digits, 0 otherwise
int has_repeated_digits(int num){
// in array, array[0] represents how many times the '0' is found
// array[1], how many times '1' is found etc...
int array[10] = {0,0,0,0,0,0,0,0,0,0};
char num_string[MAX_DIGITS_IN_NUM];
//converts the number to string and stores it in num_string
sprintf(num_string, "%d", num);
int i = 0;
while (num_string[i] != '\0'){
//if a digit is found more than one time, return 1.
if (++array[num_string[i] - '0'] >= 2){
return 1; //found repeated digit
}
i++;
}
return 0; //no repeated digits found
}
// test tha function
int main()
{
int x=0;
while (scanf("%d", &x) != EOF){
if (has_repeated_digits(x))
printf("repeated digits found!\n");
else
printf("no repeated digits\n");
}
return 0;
}
You can simplify your problem from these remarks:
the least common multiple of 2, 3, 4, 5, 6, 7, 8 and 9 is 2520.
numbers larger than 9876543210 must have at least twice the same digit in their base 10 representation.
checking for duplicate digits can be done by counting the remainders of successive divisions by 10.
A simple approach is therefore to enumerate multiples of 2520 up to 9876543210 and select the numbers that have no duplicate digits.
Type unsigned long long is guaranteed to be large enough to represent all values to enumerate, but neither int nor long are.
Here is the code:
#include <stdio.h>
int main(void) {
unsigned long long i, n;
for (n = 2520; n <= 9876543210; n += 2520) {
int digits[10] = { 0 };
for (i = n; i != 0; i /= 10) {
if (digits[i % 10]++)
break;
}
if (i == 0)
printf("%llu\n", n);
}
return 0;
}
This program produces 13818 numbers in 0.076 seconds. The first one is 7560 and the last one is 9876351240.
The number 0 technically does match your constraints: it is evenly divisible by all non zero integers and it has no duplicate digits. But you excluded it explicitly.

Rounding off an integer to always end on 0

I'm making a program to calculate the number of perfect squares between 1 and another number, and I want the counter to take only the first number of the integer, and put 0 on the rest, e.g: Result of the calculation is 31, I want to display 30, if it's 190, then display 100, and so on.
int number;
int i = 1;
int perfectCounter = 0;
printf("Enter a number: ");
scanf("%d", &number);
while (i <= number) {
float tempSquare = sqrt(i);
int integerPart = tempSquare;
if (tempSquare == integerPart)
perfectCounter++;
i++;
}
printf("%d", perfectCounter);
That's the code that I have right now, if I insert 1000, it will display 31, and I want it to display 30, I can't think a solution for this.
Divide the number by the highest power of 10 below the number. Do this using integer arithmetic, so it gets the integer part of the division. Then multiply by the power of 10.
#include <math.h>
int powerOf10 = pow(10, (int)log10(perfectCounter));
int roundedCounter = (perfectCounter/powerOf10)*powerOf10;
printf("%d", roundedCounter);
You can use a function like this one to round your numbers. Basically what it does is it "chips away" one digit at a time until we are left with only one digit and then adds appropriate number of zeros to it:
int round(int _in){
int numDigits = 0;
while(_in > 9){
++numDigits;
_in /= 10;
}
int res = _in; // whatever is left would be the left-most digit
for(int i = 0; i < numDigits; ++i){
res *= 10;
}
return res;
}
Here's a simple solution with no math:
void print_rounded(int i) {
unsigned u = i;
if (i < 0) { putchar('-'); u = -i; }
char buf[2];
int n = snprintf(buf, 2, "%u", u);
for (putchar(buf[0]); --n; putchar('0')) {}
}
(In other words, print the first digit, and then print enough 0's to make up the length of the original number.)

High-precision program that calculates 2^n

I'm building a program in C that can get powers of 2. The user inputs the value of n, and the program calculates 2^n.
Here's the code.
The problem comes when I input 100
What I am getting:
1,267,650,600,228,229,400,000,000,000,000
What I should get
1,267,650,600,228,229,401,496,703,205,376
It has to be coded entirely in ANSI C. Any ideas on how to increase the precision? The maximum value of N has to be 256 (256 bits, I imagine, which means the maximum output should be 2^256).
What I'm lacking here is precision, and I don't know how to fix that. Any ideas?
I think it's easiest if you work in base 10 from the start. This is because while calculating powers of 2 in binary is trivial, the conversion back to base 10 is a lot harder.
If you have an array of base 10 digits1, you only need to implement base 10 addition with carry to be able to multiply by 2 (by adding the number to itself). Do that n times in a loop and you have your answer.
If you wish to support higher exponents, you can also look into implementing exponentiation by squaring, but that's harder, since you'll need general multiplication, not just by 2 for that.
1 Tip: It's more convenient if you store the digits in reverse order.
Here is my quick and dirty implementation of hammar's approach., storing the decimal number as a C string with the digits in reverse order.
Run the code on ideone
void doubleDecimal(char * decimal)
{
char buffer[256] = "";
char c;
unsigned char d, carry = 0;
int i = 0;
while (c = decimal[i])
{
d = 2 * (c - '0') + carry;
buffer[i] = (d % 10) + '0';
carry = d / 10;
i++;
}
if (carry > 0)
buffer[i++] = (carry % 10) + '0';
buffer[i] = '\0';
strncpy(decimal, buffer, 256);
}
void reverse(char * str)
{
int i = 0;
int j = strlen(str) - 1;
while (j > i)
{
char tmp = str[i];
str[i] = str[j];
str[j] = tmp;
i++;
j--;
}
}
int main(void)
{
char decimal[256] = "1";
int i;
for (i = 0; i < 100; i++)
doubleDecimal(decimal);
reverse(decimal);
printf("%s", decimal);
return 0;
}
Output:
1267650600228229401496703205376
double is a (probably) 64bit value. You can't store 256 bits of precision in 64 bits. The reason that you are getting a number that is sort of close is because floating point numbers are stored with varying precision -- not all sequential numbers can be represented, but you can represent very large numbers. Pretty useless in this case.
What you want is either to use an arbitrary precision library or, since this is probably homework, you are expected to write your own.
A typical double, using 64-bit IEEE 754, has about 51 bits precision, IIRC.
Most probably the point of supporting exponents up to 256 is to exceed that precision, and also the precision of a long double or long long, so that you have to do things yourself.
As a homework exercise, then,
Store decimal digit values in an array + a digit count
Implement doubling of the value in such array + count
Start with 1 and double value appropriate number of times.
A few things you'll want to think about to solve this:
You are only dealing with integers so you should use an integer
representation (you will need to roll your own because you can't use
long long which is "only" 64 bits long).
Powers of 2 you say -how convenient - computers store numbers using powers of 2 (you'll
only need to use shift operations and bit fiddling .... no
multiplications will be needed).
How can you convert a base 2 number to a base 10 number for display purposes (think of division and outputting one number at a time (think about what a hardware divisor does in order to get the bit manipulations correct).
You can't the store 256 bits of precision in 64 bits. Reason that you are getting a number to close is because floating point numbers are stored with varying precision. To all sequential numbers can be represented, but you can represent very large numbers. Pretty useless in this case.
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//constants
#define MAX_DIGITS 1000
//big integer number struct
struct bigint {
char Digits[MAX_DIGITS];
};
//assign a value
void assign(struct bigint* Number,int Value) {
if (Value!=1) {
printf("Can not assign value other than 1\n");
exit(0);
}
memset(Number,0,sizeof(bigint));
Number->Digits[0] = Value;
}
//multiply the big integer number with value
void multiply(struct bigint* Number,int Value) {
int Digit,New_Digit;
int Carry = 0;
for (int Index=0; Index<MAX_DIGITS; Index++) {
Digit = Number->Digits[Index];
New_Digit = Digit*Value%10;
if (New_Digit+Carry<10) {
New_Digit = New_Digit+Carry;
Carry = Digit*Value/10;
}
else {
New_Digit = (New_Digit+Carry)%10;
Carry = (Digit*Value/10)+1;
}
//set the new digit
Number->Digits[Index] = New_Digit;
}//for loop
}
//print out the value of big integer type
void print(struct bigint* Number) {
int Index = MAX_DIGITS-1;
while (Number->Digits[Index]==0 && Index>=0)
Index--;
//the big integer value is zero
if (Index==-1) {
printf("0");
return;
}
while (Index>=0) {
printf("%u",Number->Digits[Index]);
Index--;
}
}
//main programme entry point
int main(int Argc,char** Args) {
int Power = 100;
struct bigint Number;
//assign the initial value
assign(&Number,1);
//do the multiplication
for (int Index=0; Index<Power; Index++)
multiply(&Number,2);
//print result
print(&Number);
getch();
}
//END-OF-FILE

Resources