问题
I'm creating a program that adds and subtracts 2 numbers. Then I have to output this answer into different bases.
My answer is in decimal format, of type long double, such as:
long double answer;
answer = numberOne + numberTwo;
I want to convert this answer into binary. Now I have code used earlier in my program that does this, but with a char pointer:
char * decimalBinary (char * decimalNumber)
{
bool zeroFront = true;
int i;
int z;
int j = 0;
int n = atoi(decimalNumber);
char * binaryNum = malloc(32+1);
binaryNum[32] = '\0';
int current_index=1;
int end_index = strlen(decimalNumber)-1;
//Error check for valid decimal input, needed error check for beginning of code
while(current_index <= end_index)
{
if(decimalNumber[current_index] != '0' &&decimalNumber[current_index] != '1' &&decimalNumber[current_index] != '2' &&decimalNumber[current_index] != '3' &&decimalNumber[current_index] != '4' &&decimalNumber[current_index] != '5' &&dec[current_index] != '6' &&dec[current_index] != '7' &&decimalNumber[current_index] != '8' &&decimalNumber[current_index] != '9')
{
binaryNum[0] = -8;
return binaryNum;
}
current_index++;
}
for (i = 31; i >= 0; i--) {
z = n >> i;
if (z & 1)
{
binaryNum[j] = '1';
j++;
zeroFront = false;
}
else if (!zeroFront)
{
binaryNum[j] = '0';
j++;
}
}
binaryNum[j] = '\0';
return binaryNum;
}
My preferred solution is to use the code I already have in my program to convert my answer into a binary format, but as you can see the parameters are conflicting, and I'm not sure how to go about doing that.
Another possible solution that detracts from having reusable code in my program, is to create a different function all together that converts a decimal to a binary, but accepting a parameter of type long double, which is a bit unclear to me as well.
Edit:
Instead of long double
, my answer is of type int
.
回答1:
If you really want to reuse your function without modifications, you can transform answer
into a decimal string and pass the string to your function.
char stringAnswer[20];
sprintf(stringAnswer, "%d", answer);
printf("the binary answer is %s\n", decimalBinary(stringAnswer));
But a better solution should be to split the function decimalBinary
into two functions : the first one to check that all digits are ok, and the second one to convert a int
into a binary string.
Then you'll be able to call directly this second function with answer
as parameter.
回答2:
Rather than use a magic number 32, better to let the compiler deduce the needed size as an int
is not always 32 bits. Checking allocation results is a good habit.
#include <assert.h>
#include <stdlib.h>
#define INT_MAX_BIN_WIDTH (sizeof(int) * CHAR_BIT)
char * binaryNum = malloc(INT_MAX_BIN_WIDTH+1);
assert(binaryNum != NULL);
binaryNum[INT_MAX_BIN_WIDTH] = '\0'; // null character
Rather than checking against each digit, since '0'
to '9'
must be sequential:
// if(decimalNumber[current_index] != '0' &&decimalNumber[current_index] != '1' ...
if (decimalNumber[current_index] < '0' || decimalNumber[current_index] >= '9') ...
// or
if (!isdigit((unsigned char) decimalNumber[current_index])) ...
Problem does not address negative numbers. Better to state that they will not occur or better, make code handle them.
Code allocates memory, but does not free it. Consider letting the higher level code allocate/free and supply the needed buffer to decimalBinary(char *dest, size_t size, const char *src)
. Robust code would supply the size too.
char *binaryNum = malloc(INT_MAX_BIN_WIDTH+1);
assert(binaryNum != NULL);
decimalBinary(binaryNum, INT_MAX_BIN_WIDTH+1, "123");
do_something(binaryNum);
free(binaryNum);
Following is a solution that is not limited to 32 bits. It does not cope with negative numbers nor memory allocation - certainly it should provide some ideas for your eventual solution.
#include <stdio.h>
#include <string.h>
static void times10(char *binaryNumber, int carry) {
size_t length = strlen(binaryNumber);
size_t i = length;
while (i > 0) {
i--;
int sum = (binaryNumber[i] - '0') * 10 + carry;
binaryNumber[i] = sum % 2 + '0';
carry = sum / 2;
}
while (carry) {
memmove(&binaryNumber[1], &binaryNumber[0], ++length);
binaryNumber[0] = carry % 2 + '0';
carry /= 2;
}
}
char *decimalBinary(char *binaryNumber, const char *decimalNumber) {
strcpy(binaryNumber, "0");
int ch;
while ((ch = *decimalNumber++) >= '0' && (ch <= '9')) {
times10(binaryNumber, ch - '0');
}
return binaryNumber;
}
int main(void) {
char buf10[200];
puts(decimalBinary(buf10, "123"));
puts(decimalBinary(buf10, "123456"));
puts(decimalBinary(buf10, "123456789012345678901234567890"));
return 0;
}
来源:https://stackoverflow.com/questions/31231935/decimal-to-binary-in-c