Binary to decimal algorithm in c giving strange results - c

Hi i'm fairly new to c but for a program I'm writing I need to convert binary strings to decimal numbers. here is my current code:
int BinaryToInt(char *binaryString)
{
int decimal = 0;
int len = strlen(binaryString);
for(int i = 0; i < len; i++)
{
if(binaryString[i] == '1')
decimal += 2^((len - 1) - i);
printf("i is %i and dec is %i and the char is %c but the length is %i\n", i, decimal, binaryString[i], len);
}
return decimal;
}
int main(int argc, char **argv)
{
printf("%i", BinaryToInt("10000000"));
}
and here is the output:
i is 0 and dec is 5 and the char is 1 but the length is 8
i is 1 and dec is 5 and the char is 0 but the length is 8
i is 2 and dec is 5 and the char is 0 but the length is 8
i is 3 and dec is 5 and the char is 0 but the length is 8
i is 4 and dec is 5 and the char is 0 but the length is 8
i is 5 and dec is 5 and the char is 0 but the length is 8
i is 6 and dec is 5 and the char is 0 but the length is 8
i is 7 and dec is 5 and the char is 0 but the length is 8
5
I'm confused as to why this doesn't work, all help is greatly appreciated. Thanks in advance!
Ps: I'm used to java so at the moment C just makes me cry

The ^ operator is not for exponentiation, but is instead the bitwise XOR operator.
If you want to raise a number to a power of 2, use the left shift operator << to shift the value 1 by the exponent in question.
decimal += 1 << ((len - 1) - i);

The trick is the same as with any number base: for each incoming digit, multiply the accumulator by the number base and add the digit.
#include <stdio.h>
#include <string.h>
int BinaryToInt(char *binaryString)
{
int decimal = 0;
int len = strlen(binaryString);
for(int i = 0; i < len; i++) {
decimal = decimal * 2 + binaryString[i] - '0';
}
return decimal;
}
int main(void)
{
printf("%d", BinaryToInt("10000000"));
return 0;
}
Program output:
128

Related

Conversion hexadecimal to decimal

I've already written a program, but it's a bit incorrect.
I will be very grateful if you show me how to fix it.
So, here is the trouble:
You have to convert the number from hexadecimal to decimal form.
The main problem is that program must CALCULATE MANUALLY the number , instead of using a format specification ( as i did )
I apologize for possible inaccuracies and mistakes in English, I am just starting to familiarize myself with programming))
There is my variant:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define SIZE 20
int main(void) {
system("chcp 1251");
char str[SIZE][SIZE], (*pstr)[SIZE];
pstr = str;
char* pcode;
int kst;
printf("Specify the number of lines you want to enter: ");
scanf_s("%d", &kst);
getchar();
while (kst > SIZE)
{
printf("You have exceeded the allowed value (the number of lines must be less than 20): ");
scanf_s("%d", &kst);
getchar();
}
while (kst < 1)
{
printf("You entered a number that is too small, try entering a number between 1 and 20:");
scanf_s("%d", &kst);
getchar();
}
int isXDigit;
printf("\nEnter the lines:\n\n");
while (pstr < str + kst)
{
isXDigit = 1;
gets_s(*pstr);
for (pcode = *pstr; *pcode != '\0'; pcode++){
if (isxdigit(*pcode) == 0){
**pstr = 0;
break;
}
}
pstr++;
}
printf("\nThe result\n");
unsigned long long sixteen;
for (pstr = str; pstr < str + kst; pstr++)
{
if (**pstr == 0)
printf("16: The error!\n");
else {
sixteen = strtoull (*pstr, NULL, 16);
printf("16: %#020llx | 10: %llu\n", sixteen, sixteen);
}
}
return 0;
}
unsigned long long hexToNum(const char *hexSTR)
{
const char *digits = "0123456789ABCDEF";
const char *found = NULL;
unsigned long long result = 0;
while(*hexSTR)
{
result *= 0x10;
if(found = strchr(digits, toupper((unsigned char)*hexSTR)))
result += found - digits;
else { result = 0; break;}
hexSTR++;
}
return result;
}
Textual representation of a number
“Hexadecimal” and “decimal” (and “octal” and “binary” et cetera) are all textual representations of a number.
That is, we write numbers with a radix, but a number exists independently of any particular representation.
That is why 0xA equals 10 equals 012 equals 0b1010 (hexadecimal, decimal, octal, and binary representations).
Remember in grade school when you were taught digit places? That is because a number is a polynomial representation of a value.
→ 123 equals 100 + 20 + 3
Or, written as a polynomial:
 → 1×102 + 2×101 + 3×100
That 10 is the radix. If we change the radix, the number gets written differently. The following, even though it has the same digits, is a totally different number:
 → 1×162 + 2×161 + 3×160
We can see this by doing the math.
3×160 is 3
2×161 is 32
1×162 is 256
256 + 32 + 3 is 291
Dissecting a number to a polynomial representation with radix
To get the least-significant digit of a number, you simply take the remainder of dividing it by the radix:
 → 123 ÷ 10 is 12 with a remainder of 3
You can repeat this process to get every digit in the given radix:
 → 12 ÷ 10 is 1 with a remainder of 2
 → 1  ÷ 10 is 0 with a remainder of 1
So the digits, radix 10, of 123 are, least-significant to most-significant, 3, 2, and 1. We write this as 123.
Suppose we take a radix of 16?
 → 123 ÷ 16 is 7 with a remainder of 11 (which we write as B)
 → 7   ÷ 16 is 0 with a remainder of 7
So the hexadecimal (radix == 16) value of 123 is 7B.
Suppose we take a radix of 8?
 → 123 ÷ 8 is 15 with remainder 3
 → 15  ÷ 8 is 1 with remainder 7
 → 1   ÷ 8 is 0 with remainder 1
So the octal (radix == 8) value of 123 is 173.
In C the operators for getting the quotient and remainder are / and %:
42 / 10 is 4 (quotient)
42 % 10 is 2 (remainder)
Building a number from a polynomial representation with radix
If you are given a textual number representation and wish to build that into an actual numeric value, you only need to know the radix and have access to multiplication and addition.
For example, given 2 7 B:
0 * 16 + 2 → 0 + 2 → 2
2 * 16 + 7 → 32 + 7 → 39
39 * 16 + 11 → 624 + 11 → 635
Indeed this is correct: The hexadecimal representation of 635 is 27B. Said another way, the decimal representation of 0x27B is 635.
Functions!
We can make ourselves functions both to build and dissect polynomial text representations.
int hex_to_int( const char * text );
void int_to_hex( int number, char result[] );
Digit symbols
One thing to be aware of is the number of digit symbols available to a given radix.
For decimal we use the digit symbols 0 through 9.
For octal we only use the digit symbols 0 through 7.
For binary we only need 0 and 1.
But we don’t have enough Arabic digit symbols for hexadecimal, which needs 16 digit symbols. So we just start using the alphabet:
 → 0 1 2 3 4 5 6 7 8 9 A B C D E F
Converting to hex is easy. Just use an array:
char digits[] = "0123456789ABCDEF";
To output the digit symbol for digit 13, just use the array:
printf( "%c", digits[13] ); // prints "D"
Going the other way is a little trickier. I recommend you make yourself a little function:
int hex_digit_to_value( int digit )
{
if ((digit >= '0') and (digit <= '9')) return (digit - '0');
if ((digit >= 'A') and (digit <= 'F')) return (digit - 'A') + 10;
if ((digit >= 'a') and (digit <= 'f')) return (digit - 'a') + 10;
return 0; // can't happen? maybe return -1?
}

What am I doing wrong in converting char to int?

I am basically trying to convert a char vector to int values: in file stage_03.txt I have something like 10011 10101 10011 11001 etc. and the stage_04.txt file should look like 19 21 19 etc. This code works perfectly fine in Code::Blocks. However, the stage_04.txt file is totally messed up when I run the code in Linux terminal: ^R ^S ^D etc.
#include <stdio.h>
#include <math.h>
int main(void) {
char x[256];
int aux[1000];
int numar = 0;
int z = 0;
int i = 0;
int l = 0;
int ch;
FILE *fin = fopen("stage_03.txt", "r");
FILE *fout = fopen("stage_04.txt", "w");
while ((ch = fgetc(fin)) != EOF) {
x[i++] = ch;
}
for (int i = 0; i < l; i = i + 6) {
numar = 0;
for (int j = 0; j <= 4; j++)
numar = numar + (x[i + j] - '0') * pow(2, (4 - j));
aux[z++] = numar;
}
for (i = 0; i < z - 1; i++) {
fputc(aux[i], fout);
fputc(' ', fout);
}
return 0;
}
What can I do to solve this?
Here is my solution. Please do not regard this as a "final" code. In final code one should divide the code into subprocedures and add error handling. I left this out for simplicity, here. The solution adds more flexibility concerning the separators and lengths of the numbers in the source file.
It can easily deal with source files such as:
0 1 00 01 10 11 000 001 010 011
100 101 110 111
0000 0001 0010 0011 0100 0101
0110 0111 1000 1001 1010 1011 1100 1101 1110
1111 10011 11001
You can see that fields do not need to have a fixed size of 6 character like in the original code.
#include <stdio.h>
#include <math.h>
#include <string.h>
int main(void) {
char sourceValues[256];
int targetValues[1000];
int number = 0;
int numLength = 0;
int i = 0;
int charsToProcess = 0;
int ch;
const char *srcPtr = &sourceValues[0];
int* targetPtr = &targetValues[0];
FILE *fin = fopen("stage_03.txt", "r");
FILE *fout = fopen("stage_04.txt", "w");
// read source file and determine number of chars to be processed
while ((ch = fgetc(fin)) != EOF) {
sourceValues[i++] = ch;
}
sourceValues[i] = '\0'; // terminate source data
charsToProcess = i;
srcPtr += strcspn(srcPtr, "01"); // eventually skip leading whitespace
do {
numLength = strcspn(srcPtr, " \t\n\r\v"); // determine runlength until next separator
// Convert ASCII into binary form
number = 0;
for (int i = 0; i < numLength; ++i)
{
number <<= 1; // Make room for next digit and propagate existing digits stepwise to their final place
number += (*srcPtr++ == '1'); // Insert new digit at starting pos
}
*targetPtr++ = number; // Store converted number in binary representation in target array
srcPtr += strcspn(srcPtr, "01"); // Skip whitespace. Set srcPtr to next numeric sequence
} while (srcPtr < sourceValues + charsToProcess);
for (const int *ptr = &targetValues[0]; ptr < targetPtr; ++ptr) {
fprintf(fout, "%d ", *ptr);
}
return 0;
}
Here is the output to the input given above:
0 1 0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 19 25

Count alphabets in C using log functions(without math.h) and arrays

I'm facing a slight problem with one of my projects. I am supposed to write a c program to calculate each character present in the input/file. (It's supposed to be a basic program.) The constraints - I cannot use the math.h library to produce log functions and obtain an output in the format:
1
5 1 2 0 2 2 5 8 4 3 6 6 2 5 5 7 2 1 1 2
7 9 8 1 7 2 4 1 0 0 4 5 0 2 2 5 2 6 3 6 6 3 7 0 2 2
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
The program is supposed to count the number of occurrences of each alphabetic letter (case insensitive) in the stdin input stream and display a histogram.
As you can see, the output is formatted vertically with each line printing the base 10 number of the position of the character.
Now, this might seem silly, but what I have so far is this:
#include <stdio.h>
#include <ctype.h>
/*
int logBase10 (int num) {
method to calculate the log base 10 of num
}
*/
int main (int argc, char * argv[]) {
char alpha;
int count = 0;
int ascii[128] = {0};
while ( (alpha = getchar()) != EOF) {
count++;
ascii[(int)alpha]++;
alpha = getchar();
}
printf("Char \t Count \n");
printf("------------------------\n");
for (int i = 0; i < 127; i++) {
if(ascii[i] > 0) {
printf("%c \t %d \n", i, ascii[i]);
}
}
}
Which produces an output like this:
Char Count
------------------------
5
93
, 6
- 2
. 3
; 2
C 2
I 6
N 1
T 1
W 2
a 26
b 5
c 8
d 13
e 55
f 11
g 7
h 28
i 32
k 3
l 26
m 17
n 31
o 27
p 12
q 1
r 26
s 22
t 42
u 11
v 8
w 8
y 13
z 1
First off, my program is printing unwanted ascii characters (, ; - etc) and I am working on changing the print function to be more vertical, but I cannot figure out the log method at all. I know log(10) is 1 because 10^1 is 1, but I am having trouble figuring out how to use this to create the method itself. Also, for the extra characters, I tried using:
if(ascii[i] > 65 || ascii[i] < 90 || ascii[i] >= 97 || ascii[i] <= 122 ) {
printf("%c \t %d \n", i, ascii[i]);
}
to no avail. Trying that produced more gibberish characters instead.
Any help/feedback is appreciated.
Soul
The commenters have already pointed out issues with your code. Here's a version that counts only letters and prints vertical labels. It doesn't need <ctype.h> or <math.h>.
Each character hets a letter index which is a number from 0 to 25 for upper and lower case letters and −1 if the character isn't a letter. That reduces the array size to 26.
You could find out each digit with elaborate calculations, but the easiest way is to print the number to a string. snprintf does this for you. You can right-align the number with a field width. The maximum value for a typical int is about 2 billion, which has 10 digits. You should account for that, even if you had to pass in the whole Moby-Dick plus the Bible to get that many counts.
You can test whether you should start printing by assuming a width of ten digits first and checking whether the maximum count has ten digits, that is whether it is 1,000,000,000 or higher. Then divide that limit by 10 in each iteration.
Here's the code:
#include <stdio.h>
// return letter index or -1 for non-letter
int letter(int c)
{
if ('a' <= c && c <= 'z') return c - 'a';
if ('A' <= c && c <= 'Z') return c - 'A';
return -1;
}
int main(int argc, char * argv[])
{
int count[26] = {0}; // letter counts
char label[26][12]; // buffer for printing numbers
int limit = 1000000000; // smallest 10-digit number
int max = 0;
int i, j;
// read and count letters
while (1) {
int c = getchar();
if (c == EOF) break;
c = letter(c);
if (c >= 0) count[c]++;
}
// write auxiliary labels
for (i = 0; i < 26; i++) {
snprintf(label[i], sizeof(label[i]), "%10d", count[i]);
if (count[i] > max) max = count[i];
}
// print vertical labels
for (j = 0; j < 10; j++) {
if (max >= limit) {
for (i = 0; i < 26; i++) {
putchar(' ');
putchar(label[i][j]);
}
putchar('\n');
}
limit /= 10;
}
// print horizontal rule
for (i = 0; i < 26; i++) {
putchar('-');
putchar('-');
}
putchar('-');
putchar('\n');
// print letters
for (i = 0; i < 26; i++) {
putchar(' ');
putchar('A' + i);
}
putchar('\n');
return 0;
}
On your example, it produces:
1
5 1 2 0 2 2 5 8 4 3 6 6 2 5 5 7 2 1 1 2
7 9 8 1 7 2 4 1 0 0 4 5 0 2 2 5 2 6 3 6 6 3 7 0 2 2
-----------------------------------------------------
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
One easy way to figure out how many digits that you'll need is to use sprintf to convert the integer count to a string, and then use strlen to find out how many digits you have. For example:
char str[20] = {0}; // 20 digits should be enough for your case
for (i = 0; i < 128; i++) {
sprintf(str, "%d", ascii[i]);
num_digits = strlen(str);
printf("%d has %d digits\n", ascii[i], num_digits);
}
I didn't test the code, but it should be close.
Some pseudo code
Find max count
Find width of that count when printed w=sprintf(buf, "%d", mxcnt)
Loop w times (wi = 0 to w - 1)
for each non-zero count
form string sprintf(buf, "%*d", w, count[i])
print buf[wi] character
print space
print \n

C : 0 & 1 combinations using recursion

I want to list combinations of o & 1 recursively using c depending on variables number (number)
the output I want is
000
001
010
011
100
101
110
111
I've tried many algorithms the last one is :
void permute(unsigned number) {
if(number == 0) {
printf("\n");
return;
}
permute(number - 1);
printf("0");
permute(number - 1);
printf("1");
} //permute ends here
void permuteN(unsigned number) {
unsigned i;
for(i = 0; i < number + 1; i++){
permute(i);
}
} //permuteN ends here
I think it gives me the answer but not ordered because I don't know where to put \n;
need your help!
If you are indeed just looking for combinations of 1's and 0's I'd suggest you just count up the numbers and list them in binary.
Take the numerals 0...7 in binary and taking only the last 3 bits (apply mask maybe), and you end up with the same set you specified:
000
001
...
...
111
For n-digit combinations, you need to do 0..2^n - 1
Based off this answer, for one specific case of 3-bits
(Credit to #ChrisLutz and #dirkgently)
#include <stdio.h>
int main(){
int numdigits = 3, j;
for(j=1; j<8; j++)
printbits(j);
}
void printbits(unsigned char v) {
int i;
for(i = 2; i >= 0; i--) putchar('0' + ((v >> i) & 1));
printf("\n");
}
Output:
000
001
010
011
100
101
110
111
All you are actually doing is converting a number to binary.... A simple loop does this without any library calls (aside from printf)...
const unsigned int numbits = 3;
unsigned int bit;
for( bit = 1U << (numbits-1); bit != 0; bit >>= 1 ) {
printf( number&bit ? "1" : "0" );
}
printf( "\n" );
Edited, since you seem to want recursion. You need to have some way to specify how many bits you require. You need to pass this into your recursive routine:
#include <stdio.h>
void permute(unsigned number, unsigned bits)
{
if( bits == 0 ) return;
permute(number / 2, bits-1);
printf( "%d", number % 2 );
} //permute ends here
void permuteN(unsigned number, unsigned bits ) {
unsigned i;
for(i = 0; i < number + 1; i++){
permute(i, bits);
printf("\n");
}
} //permuteN ends here
int main(void)
{
permuteN(7, 3);
return 0;
}
To get the output in the order you require, you can't know when to write the newline. So in this case, you write it afterwards.
#paddy has a nice answer; only adding a bit (as of my toughs by your reply on my comment - was a bit late to the game). This rely on pow() , (and log10 for some nicety in print), tho so; if using gcc compile with -lm:
basemight be a bit confusing here - but guess you get the meaning.
gcc -Wall -Wextra -pedantic -o combo combo.c -lm
/* gcc - Wall -Wextra -pedantic -o combo combo.c -lm */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static void prnt_combo(unsigned number, unsigned bits, int base)
{
if (!bits)
return;
prnt_combo(number / base, --bits, base);
printf("%d", number % base);
}
void prnt_combos(int bits, int base)
{
int i;
int n = pow(base, bits);
int wp = log10(n) + 1;
fprintf(stderr,
"Printing all combinations of 0 to %d by width of %d numbers. "
"Total %d.\n",
base - 1, bits, n
);
for (i = 0; i < n; i++) {
fprintf(stderr, "%*d : ", wp, i);
prnt_combo(i, bits, base);
printf("\n");
}
}
/* Usage: ./combo [<bits> [<base>]]
* Defaults to ./combo 3 2
* */
int main(int argc, char *argv[])
{
int bits = argc > 1 ? strtol(argv[1], NULL, 10) : 3;
int base = argc > 2 ? strtol(argv[2], NULL, 10) : 2;
prnt_combos(bits, base);
return 0;
}
Sample:
$ ./combo 4 2
Printing all combinations of 0 to 1 by width of 4 numbers. Total 16.
0 : 0000
1 : 0001
2 : 0010
3 : 0011
4 : 0100
5 : 0101
6 : 0110
7 : 0111
8 : 1000
9 : 1001
10 : 1010
11 : 1011
12 : 1100
13 : 1101
14 : 1110
15 : 1111
Or clean output:
$ ./combo 3 2 >&2-
000
001
010
011
100
101
110
111
You might like to add something like:
if (base > 10)
printf("%x", number % base);
else
printf("%d", number % base);
in prnt_combo(). This way you get i.e. by 2 16:
0 : 00
1 : 01
2 : 02
3 : 03
4 : 04
...
250 : fa
251 : fb
252 : fc
253 : fd
254 : fe
255 : ff

Count total number of digits from a given positive number without looping in C

How to count total number of digits from a given positive number without looping in C?
For integers, take the log10 of the number, round down, and add one.
TEST:
#include <math.h>
#include <stdio.h>
int
num_digits(unsigned long number)
{
return (int)(floor(log10((double)number)) + 1.0);
}
int
main(int argc, char **argv)
{
unsigned long test_numbers[] = {
1, 9, 10, 99, 100, 999, 1000, 9999, 10000, 99999, 100000, 999999,
123456789ul,
999999999ul,
0
};
unsigned long *ptr;
for(ptr = test_numbers; *ptr; ptr++)
{
printf("Number of digits in %lu: %d\n", *ptr, num_digits(*ptr));
}
return 0;
}
Output:
Number of digits in 1: 1
Number of digits in 9: 1
Number of digits in 10: 2
Number of digits in 99: 2
Number of digits in 100: 3
Number of digits in 999: 3
Number of digits in 1000: 4
Number of digits in 9999: 4
Number of digits in 10000: 5
Number of digits in 99999: 5
Number of digits in 100000: 6
Number of digits in 999999: 6
Number of digits in 123456789: 9
Number of digits in 999999999: 9
One possible solutions, assuming 16-bit integer values and logical expressions evaluating to 0 or 1. You could replace the conditions with (u > 99) ? 1 : 0 if you're worried about portability.
int digits( unsigned u)
{
return 1 + (u > 9) + (u > 99) + (u > 999) + (u > 9999);
}
Two solutions for you!
int digit_count(unsigned int n)
{
if (n < 10)
return 1;
else
return (1 + digit_count(n / 10));
}
and
unsigned int n = 50;
int i = 0;
HACK:
i++;
if (n < 10)
{
printf("Digits: %d\n", i);
}
else
{
n /= 10;
goto HACK;
}
Don't hate me for the last one :(
return snprintf(0, 0, "%d", num);

Resources