binary string to decimal number in c - c

I can't figure out what's wrong with this code!
It returns 208 as a decimal
where it should be 0
typedef unsigned char uchar;
int CONVERTION_BinStrToDecimal(char* binstr) //transform a inary string to a decimal number
{
int cpts = 0;
unsigned char dec = 0;
uchar x = 0;
for (cpts = 0; cpts <= 7; cpts++) {
x = 7 - cpts;
dec += (binstr[cpts]*pow(2,x));
}
return dec;
}
int main()
{
uchar decimal = 0;
char bin[8] = "00000000"; //example
decimal = CONVERTION_BinStrToDecimal(bin);
printf("%d", decimal);
}

binstr[cpts] yields the ascii code of 0 or 1 (which is 0x30 or 0x31).
You need to use binstr[cpts] == '1' to convert a ascii '1' to the number 1 and everything else to 0 (assuming that no other characters may occur). Another option would be binstr[cpts] - '0'.
Btw, using the pow() function is disregarded for such cases, better substitute pow(2,x) by (1<<x).
for (cpts = 0; cpts <= 7; cpts++) {
x = 7 - cpts;
dec += ((binstr[cpts] == '1')*(1 << x));
}
There are many possibilities to make it look nicer, of course, the most obvious being (binstr[cpts] == '1') << x.
Furthermore, mind that your code expects exactly 8 binary digits to calculate the correct result.

Alternatively, if you zero-terminate your string you can use strtol function with base 2, e.g.:
char bin[9] = "00000000";
decimal = strtol(bin, NULL, 2);

Related

My decimal to hex conversion function only woks with positive nums

I'm having problems converting negative numbers, from decimal base to hexadecimal base, with the following function:
#include <stdio.h>
int main()
{
int quotient, remainder;
int i, j = 0;
char hexadecimalnum[100];
quotient = -50;
while (quotient != 0)
{
remainder = quotient % 16;
if (remainder < 10)
hexadecimalnum[j++] = 48 + remainder;
else
hexadecimalnum[j++] = 55 + remainder;
quotient = quotient / 16;
}
strrev(hexadecimalnum);
printf("%s", hexadecimalnum);
return 0;
}
For quotient = -50; the correct output should be:
ffffffce
But this function's output is:
.
With positive numbers the output is always correct but with negative numbers not.
I'm having a hard time understanding to why it doesn't work with negative numbers.
Some fixes:
unsigned int quotient - you need to convert -50 to a large hex number in two's complement or you'll get the wrong number of iterations (2) in the loop, instead of 8 as required.
Removal of "magic numbers": '0' + remainder and 'A' + remainder - 10.
Zero initialize hexadecimalnum becaues it needs to be null terminated before printing a string from there. Better yet, add the null termination explicitly.
Use for loops when possible.
Might as well store the characters from the back to front and save the extra call of reversing the string.
Result:
#include <stdio.h>
// 4 bytes*2 = 8 nibbles
#define HEX_STRLEN (sizeof(int)*2)
int main()
{
unsigned int remainder;
int i = 0;
char hex[100];
for(unsigned int q = -50; q!=0; q/=16)
{
remainder = q % 16;
if (remainder < 10)
hex[HEX_STRLEN-i-1] = '0' + remainder;
else
hex[HEX_STRLEN-i-1] = 'A' + remainder - 10;
i++;
}
hex[HEX_STRLEN] = '\0'; // explict null termination
printf("%s\n", hex);
}
(There's lots of improvements than can be made still, this is just to be considered as the first draft.)
You can use printf's format specifier "%08x", then you can print any number in their respective hexadecimal representation.
#include <stdio.h>
void num_to_hex(int a, char *ptr) { snprintf(ptr, 9, "%08x", a); }
int main() {
char hex[10] = {};
num_to_hex(-50, hex);
printf("%s\n", hex);
return 0;
}
Output:
ffffffce

Concatenating binary numbers

I am trying to code a program that will take a floating point number in base 10 and convert its fractional part in base 2. In the following code, I am intending to call my converting function into a printf, and format the output; the issue I have lies in my fra_binary() where I can't figure out the best way to return an integer made of the result of the conversion at each turn respectively (concatenation). Here is what I have done now (the code is not optimized because I am still working on it) :
#include <stdio.h>
#include <math.h>
int fra_binary(double fract) ;
int main()
{
long double n ;
double fract, deci ;
printf("base 10 :\n") ;
scanf("%Lf", &n) ;
fract = modf(n, &deci) ;
int d = deci ;
printf("base 2: %d.%d\n", d, fra_binary(fract)) ;
return(0) ;
}
int fra_binary(double F)
{
double fl ;
double decimal ;
int array[30] ;
for (int i = 0 ; i < 30 ; i++) {
fl = F * 2 ;
F = modf(fl, &decimal) ;
array[i] = decimal ;
if (F == 0) break ;
}
return array[0] ;
}
Obviously this returns partly the desired output, because I would need the whole array concatenated as one int or char to display the series of 1 and 0s I need. So at each turn, I want to use the decimal part of the number I work on as the binary number to concatenate (1 + 0 = 10 and not 1). How would I go about it?
Hope this makes sense!
return array[0] ; is only the first value of int array[30] set in fra_binary(). Code discards all but the first calculation of the loop for (int i = 0 ; i < 30 ; i++).
convert its fractional part in base 2
OP's loop idea is a good starting point. Yet int array[30] is insufficient to encode the fractional portion of all double into a "binary".
can't figure out the best way to return an integer
Returning an int will be insufficient. Instead consider using a string - or manage an integer array in a likewise fashion.
Use defines from <float.h> to drive the buffer requirements.
#include <stdio.h>
#include <math.h>
#include <float.h>
char *fra_binary(char *dest, double x) {
_Static_assert(FLT_RADIX == 2, "Unexpected FP base");
double deci;
double fract = modf(x, &deci);
fract = fabs(fract);
char *s = dest;
do {
double d;
fract = modf(fract * 2.0, &d);
*s++ = "01"[(int) d];
} while (fract);
*s = '\0';
// For debug
printf("%*.*g --> %.0f and .", DBL_DECIMAL_DIG + 8, DBL_DECIMAL_DIG, x,
deci);
return dest;
}
int main(void) {
// Perhaps 53 - -1021 + 1
char fraction_string[DBL_MANT_DIG - DBL_MIN_EXP + 1];
puts(fra_binary(fraction_string, -0.0));
puts(fra_binary(fraction_string, 1.0));
puts(fra_binary(fraction_string, asin(-1))); // machine pi
puts(fra_binary(fraction_string, -0.1));
puts(fra_binary(fraction_string, DBL_MAX));
puts(fra_binary(fraction_string, DBL_MIN));
puts(fra_binary(fraction_string, DBL_TRUE_MIN));
}
Output
-0 --> -0 and .0
1 --> 1 and .0
3.1415926535897931 --> 3 and .001001000011111101101010100010001000010110100011
-0.10000000000000001 --> -0 and .0001100110011001100110011001100110011001100110011001101
1.7976931348623157e+308 --> 179769313486231570814527423731704356798070600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 and .0
2.2250738585072014e-308 --> 0 and .00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
4.9406564584124654e-324 --> 0 and .000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
Also unclear why input is long double, yet processing is with double. Recommend using just one FP type.
Note that your algorithm finds out the binary representation of the fraction most significant bit first.
One way to convert the fractional part to a binary string, would be to supply the function with a string and a string length, and have the function fill it with up to that many binary digits:
/* This function returns the number of chars needed in dst
to describe the fractional part of value in binary,
not including the trailing NUL ('\0').
Returns zero in case of an error (non-finite value).
*/
size_t fractional_bits(char *dst, size_t len, double value)
{
double fraction, integral;
size_t i = 0;
if (!isfinite(value))
return 0;
if (value > 0.0)
fraction = modf(value, &integral);
else
if (value < 0.0)
fraction = modf(-value, &integral);
else {
/* Zero fraction. */
if (len > 1) {
dst[0] = '0';
dst[1] = '\0';
} else
if (len > 0)
dst[0] = '\0';
/* One binary digit was needed for exact representation. */
return 1;
}
while (fraction > 0.0) {
fraction = fraction * 2.0;
if (fraction >= 1.0) {
fraction = fraction - 1.0;
if (i < len)
dst[i] = '1';
} else
if (i < len)
dst[i] = '0';
i++;
}
if (i < len)
dst[i] = '\0';
else
if (len > 0)
dst[len - 1] = '\0';
return i;
}
The above function works very much like snprintf(), except it takes only the double whose fractional bits are to be stored as a string of binary digits (0 or 1). and returns 0 in case of an error (non-finite double value).
Another option is to use an unsigned integer type to hold the bits. For example, if your code is intended to work on architectures where double is an IEEE-754 Binary64 type or similar, the mantissa has up to 53 bits of precision, and an uint64_t would suffice.
Here is an example of that:
uint64_t fractional_bits(const double val, size_t bits)
{
double fraction, integral;
uint64_t result = 0;
if (bits < 1 || bits > 64) {
errno = EINVAL;
return 0;
}
if (!isfinite(val)) {
errno = EDOM;
return 0;
}
if (val > 0.0)
fraction = modf(val, &integral);
else
if (val < 0.0)
fraction = modf(-val, &integral);
else {
errno = 0;
return 0;
}
while (bits-->0) {
result = result << 1;
fraction = fraction * 2.0;
if (fraction >= 1.0) {
fraction = fraction - 1.0;
result = result + 1;
}
}
errno = 0;
return result;
}
The return value is the binary representation of the fractional part: [i]fractional_part[/i] ≈ [i]result[/i] / 2[sup][i]bits[/i][/sup], where [i]bits[/i] is between 1 and 64, inclusive.
In order for the caller to detect an error, the function clears errno to zero if no error occurred. If an error does occur, the function returns zero with errno set to EDOM if the value is not finite, or to EINVAL if bits is less than 1 or greater than 64.
You can combine the two approaches, if you implement an arbitrary-size unsigned integer type, or a bitmap type.

C: Use scanf() function instead of gets

/* hexadecimal to decimal conversion */
#include <stdio.h>
#include <math.h>
#include <string.h>
int main()
{
char hex[17];
long long decimal;
int i , val, len;
decimal = 0;
// Input hexadecimal number from user
printf("Enter any hexadecimal number: ");
gets(hex);
//Find the length of total number of hex digit
len = strlen(hex);
len--;
for(i=0; hex[i]!='\0'; i++)
{
// Find the decimal representation of hex[i]
if(hex[i]>='0' && hex[i]<='9')
{
val = hex[i] - 48;
}
else if(hex[i]>='a' && hex[i]<='f')
{
val = hex[i] - 97 + 10;
}
else if(hex[i]>='A' && hex[i]<='F')
{
val = hex[i] - 65 + 10;
}
decimal += val * pow(16, len);
len--;
}
printf("Hexadecimal number = %s\n", hex);
printf("Decimal number = %lld", decimal);
return 0;
}
In the above program when i have used scanf instead of gets,it doesn't give the result.why? i used scanf("%x",hex); . please explain me decimal += val * pow(16, len); too.thank you so much in advance.
Because if you use scanf(), it does the conversion from string for you, that's sort of its entire point.
unsigned int x;
if(scanf("%x", &x) == 1)
printf("you entered %d (hex 0x%x)\n", x, x);
You can't combine %x a pointer to a character array, it requires a pointer to an unsigned integer. This is of course well documented in the manual page.
Also, using pow() here seems excessive, just multiply what you have by 16 before adding in each new digit:
unsigned int parsehex(const char *s)
{
unsigned int x = 0;
const char *digits = "0123456789abcdef";
const char *p;
while(*s && (p = strchr(digits, tolower(*s++))) != NULL)
{
x *= 16;
x += (unsigned int) (p - digits);
}
return x;
}
This is a bit "heavier" (uses strchr()) than your code, but shorter and perhaps therefore easier to validate. If it's overly performance-critical, I'd consider looking into it.
scanf("%x",hex);
should be
scanf("%s",hex);
you cannot do hex[i] when you read as integer.
decimal += val * pow(16, len); represents decimal = decimal + (val * pow(16, len));
Hopes this answers your question
scanf("%x"...) performs the conversion to integer for you. Therefore, you want to deposit the result in decimal:
scanf("%x", &decimal);
Each iteration of the for loop is generating a nibble (4 bits) of the number into val. The val * pow(16, len); is (in)effectively shifting the nibble into the correct position. However, this code is using floating point math to accomplish this (pow returns a double) instead of simply left shifting by 4*len. A better approach is to simply shift decimal left by 4 bits on each iteration and add (or OR) the nibble into the least significant bits. In this way, the first nibble will ultimately end up where it is supposed to be.
Also, character literals work as numbers, so instead of subtracting 48, 97, 65 it would read better if you subtracted '0', 'f', 'F' respectively.

C: Decimal Value

Can any one help me sort out one problem, i have to reverse a number without using array(int/char) for storing them.
input1 = 123
output1 = 321
input2 = 2300
output2 = 0032
I am trying to find the solution but 0 got erased while printing so i thought of octal conversion but still no solution, so i went with the decimal places and i made the 23 to 0.0032. Now my problem is how can i extract the 0032 from that part.
Is there any possible way to achieve this without using array(int/char), with that it will be easy.
#include<stdio.h>
#include<math.h>
int main()
{
int number =3200;
int temp;
while (number >0)
{
temp= number%10;
printf("%d",temp);
number = number/10;
}
return 0;
}
you could use recursion to solve this problem, without using any array in fact u could also reverse a string without using any array using recursion. This code works for both numbers and strings and it has no arrays:
char reverse(int a)
{
char c,d;
if(a=='\n')
return 0;
c=getchar();
d=reverse(c);
putchar(a);
return (c);
}
int main()
{
char c;
scanf("%c",&c);
reverse(c);
}
for a start try this.
int n, l;
char nBuf[126];
n = 1230010;
l = sprintf(nBuf, "%d", n );
while( l >= 0 )
printf("%c", nBuf[l--] );
Though if you are taking input from stdin take it as string rathar than as int or long.
Edit - for not using array
int n = 123;
while(n) {
printf("%d", n%10);
n/=10;
}
I am assuming to get a value of this sort "output2 = 0032" it is better of being a string, else formatting complications turns up with input value length and format left space with zeros etc etc.
This becomes fairly easy if you know that you can represent numbers like so:
x = a_0 + a_1 * b^1 + a_2 * b^2 + ...
a_i are the digits
b is the base
To extract the lowest digit, you can use the remainder: x % b
Dividing by the base "removes" the last digit. That way you can get the digits in order lowest to highest.
If you reverse the digits then the lowest becomes the highest. Looking at below transformation it's easy to see how to incrementally build up a number when the digits come in order highest to lowest:
x = a_0 + b * (a_1 + b * (a_2 + ...
You start of with 0, and for each digit you multiply with the base and then add the digit.
In pseudo code:
output = 0
while input != 0
digit = input % base
input = input / base ;; integer division
output = output * base + digit
end
If you want to store leading zeros, then you need to either store the digits in an array, or remember for how many steps of above loop the output remained zero:
output = 0
zeros = 0
while input != 0
digit = input % base
input = input / base ;; integer division
output = output * base + digit
if output == 0
zeros = zeros + 1
end
end
To print that you obviously need to print zeros zeros and then the number.
Live example here, relevant code:
unsigned reverse(
unsigned input,
unsigned const base,
unsigned * const zeros) {
unsigned output = 0;
unsigned still_zero = 0;
for (; input != 0; input/=base) {
output *= base;
output += input % base;
if (output == 0) {
++still_zero;
}
}
if (zeros != NULL) {
*zeros = still_zero;
}
return output;
}
void print_zeros(unsigned zeros) {
for (; zeros != 0; --zeros) {
printf("0");
}
}
Recursion allows for a simple solution. A small variation on #vishu rathore
void rev_dec(void) {
int ch = getchar();
if (isdigit(ch)) {
rev_dec();
}
if (ch >= 0) putchar(ch);
}
int main(void) {
rev_dec();
return 0;
}
input
0123456789012345678901234567890123456789
output
9876543210987654321098765432109876543210

Display the binary representation of a number in C? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a printf converter to print in binary format?
Still learning C and I was wondering:
Given a number, is it possible to do something like the following?
char a = 5;
printf("binary representation of a = %b",a);
> 101
Or would i have to write my own method to do the transformation to binary?
There is no direct way (i.e. using printf or another standard library function) to print it. You will have to write your own function.
/* This code has an obvious bug and another non-obvious one :) */
void printbits(unsigned char v) {
for (; v; v >>= 1) putchar('0' + (v & 1));
}
If you're using terminal, you can use control codes to print out bytes in natural order:
void printbits(unsigned char v) {
printf("%*s", (int)ceil(log2(v)) + 1, "");
for (; v; v >>= 1) printf("\x1b[2D%c",'0' + (v & 1));
}
Based on dirkgently's answer, but fixing his two bugs, and always printing a fixed number of digits:
void printbits(unsigned char v) {
int i; // for C89 compatability
for(i = 7; i >= 0; i--) putchar('0' + ((v >> i) & 1));
}
Yes (write your own), something like the following complete function.
#include <stdio.h> /* only needed for the printf() in main(). */
#include <string.h>
/* Create a string of binary digits based on the input value.
Input:
val: value to convert.
buff: buffer to write to must be >= sz+1 chars.
sz: size of buffer.
Returns address of string or NULL if not enough space provided.
*/
static char *binrep (unsigned int val, char *buff, int sz) {
char *pbuff = buff;
/* Must be able to store one character at least. */
if (sz < 1) return NULL;
/* Special case for zero to ensure some output. */
if (val == 0) {
*pbuff++ = '0';
*pbuff = '\0';
return buff;
}
/* Work from the end of the buffer back. */
pbuff += sz;
*pbuff-- = '\0';
/* For each bit (going backwards) store character. */
while (val != 0) {
if (sz-- == 0) return NULL;
*pbuff-- = ((val & 1) == 1) ? '1' : '0';
/* Get next bit. */
val >>= 1;
}
return pbuff+1;
}
Add this main to the end of it to see it in operation:
#define SZ 32
int main(int argc, char *argv[]) {
int i;
int n;
char buff[SZ+1];
/* Process all arguments, outputting their binary. */
for (i = 1; i < argc; i++) {
n = atoi (argv[i]);
printf("[%3d] %9d -> %s (from '%s')\n", i, n,
binrep(n,buff,SZ), argv[i]);
}
return 0;
}
Run it with "progname 0 7 12 52 123" to get:
[ 1] 0 -> 0 (from '0')
[ 2] 7 -> 111 (from '7')
[ 3] 12 -> 1100 (from '12')
[ 4] 52 -> 110100 (from '52')
[ 5] 123 -> 1111011 (from '123')
#include<iostream>
#include<conio.h>
#include<stdlib.h>
using namespace std;
void displayBinary(int n)
{
char bistr[1000];
itoa(n,bistr,2); //2 means binary u can convert n upto base 36
printf("%s",bistr);
}
int main()
{
int n;
cin>>n;
displayBinary(n);
getch();
return 0;
}
Use a lookup table, like:
char *table[16] = {"0000", "0001", .... "1111"};
then print each nibble like this
printf("%s%s", table[a / 0x10], table[a % 0x10]);
Surely you can use just one table, but it will be marginally faster and too big.
There is no direct format specifier for this in the C language. Although I wrote this quick python snippet to help you understand the process step by step to roll your own.
#!/usr/bin/python
dec = input("Enter a decimal number to convert: ")
base = 2
solution = ""
while dec >= base:
solution = str(dec%base) + solution
dec = dec/base
if dec > 0:
solution = str(dec) + solution
print solution
Explained:
dec = input("Enter a decimal number to convert: ") - prompt the user for numerical input (there are multiple ways to do this in C via scanf for example)
base = 2 - specify our base is 2 (binary)
solution = "" - create an empty string in which we will concatenate our solution
while dec >= base: - while our number is bigger than the base entered
solution = str(dec%base) + solution - get the modulus of the number to the base, and add it to the beginning of our string (we must add numbers right to left using division and remainder method). the str() function converts the result of the operation to a string. You cannot concatenate integers with strings in python without a type conversion.
dec = dec/base - divide the decimal number by the base in preperation to take the next modulo
if dec > 0:
solution = str(dec) + solution - if anything is left over, add it to the beginning (this will be 1, if anything)
print solution - print the final number
This code should handle your needs up to 64 bits.
char* pBinFill(long int x,char *so, char fillChar); // version with fill
char* pBin(long int x, char *so); // version without fill
#define width 64
char* pBin(long int x,char *so)
{
char s[width+1];
int i=width;
s[i--]=0x00; // terminate string
do
{ // fill in array from right to left
s[i--]=(x & 1) ? '1':'0'; // determine bit
x>>=1; // shift right 1 bit
} while( x &gt 0);
i++; // point to last valid character
sprintf(so,"%s",s+i); // stick it in the temp string string
return so;
}
char* pBinFill(long int x,char *so, char fillChar)
{ // fill in array from right to left
char s[width+1];
int i=width;
s[i--]=0x00; // terminate string
do
{
s[i--]=(x & 1) ? '1':'0';
x>>=1; // shift right 1 bit
} while( x > 0);
while(i>=0) s[i--]=fillChar; // fill with fillChar
sprintf(so,"%s",s);
return so;
}
void test()
{
char so[width+1]; // working buffer for pBin
long int val=1;
do
{
printf("%ld =\t\t%#lx =\t\t0b%s\n",val,val,pBinFill(val,so,0));
val*=11; // generate test data
} while (val < 100000000);
}
Output:
00000001 = 0x000001 = 0b00000000000000000000000000000001
00000011 = 0x00000b = 0b00000000000000000000000000001011
00000121 = 0x000079 = 0b00000000000000000000000001111001
00001331 = 0x000533 = 0b00000000000000000000010100110011
00014641 = 0x003931 = 0b00000000000000000011100100110001
00161051 = 0x02751b = 0b00000000000000100111010100011011
01771561 = 0x1b0829 = 0b00000000000110110000100000101001
19487171 = 0x12959c3 = 0b00000001001010010101100111000011
You have to write your own transformation. Only decimal, hex and octal numbers are supported with format specifiers.

Resources