2010-07-14 4 views
0

Я написал программу для преобразования десятичной дробной в двоичную для практических целей, но я получаю какой-то странный вывод. Когда вы выполняете modulo с десятичным числом, я получаю правильное значение, но что происходит в массиве - это косая черта? Я использую char array для того, чтобы иметь возможность использовать выходные данные с помощью cout < <.Decimal to Binary, странный вывод

// web binary converter: http://mistupid.com/computers/binaryconv.htm 

#include <iostream> 
#include <math.h> 
#include <malloc.h> // _msize 
#include <climits> 
#define WRITEL(x) cout << x << endl; 
#define WRITE(x) cout << x; 

using std::cout; 
using std::endl; 
using std::cin; 

char * decimalToBinary(int decimal); 
void decimal_to_binary_char_array(); 

static char * array_main; 

char * decimalToBinary(int decimal) // tied to array_main 
{ 
    WRITEL("Number to convert: " << decimal << "\n"); 
    char * binary_array; 
    int t = decimal,  // for number of digits 
     digits = 0,  // number of digits 
     bit_count = 0; // total digit number of binary number 
    static unsigned int array_size = 0; 
    if(decimal < 0) { t = decimal; t = -t; } // if number is negative, make it positive 
    while(t > 0) { t /= 10; digits++; }  // determine number of digits 
    array_size = (digits * sizeof(int) * 3); // number of bytes to allocate to array_main 
    WRITEL("array_size in bytes: " << array_size); 
    array_main = new char[array_size]; 
    int i = 0; // counter for number of binary digits 
    while(decimal > 0) 
    { 
     array_main[i] = (char) decimal % 2 + '0'; 
     WRITE("decimal % 2 = " << char (decimal % 2 + '0') << " "); 
     WRITE(array_main[i] << " "); 
     decimal = decimal/2; 
     WRITEL(decimal); 
     i++; 
    } 
    bit_count = i; 
    array_size = bit_count * sizeof(int) + 1; 
    binary_array = new char[bit_count * sizeof(int)]; 
    for(int i=0; i<bit_count+1; i++) 
     binary_array[i] = array_main[bit_count-1-i]; 
    //array_main[bit_count * sizeof(int)] = '\0'; 
    //WRITEL("\nwhole binary_array: "); for(int i=0; i<array_size; i++) WRITE(binary_array[i]); WRITEL("\n"); 
    delete [] array_main; 
    return binary_array; 
} 

int main(void) 
{ 

    int num1 = 3001; 
      // 3001 = 101110111001 
      // 300  = 100101100 
      // 1000 = 1111101000 
      // 1200 = 10010110000 
      // 1000000 = 11110100001001000000 
      // 200000 = 110000110101000000 
    array_main = decimalToBinary(num1); 
    WRITEL("\nMAIN: " << array_main); 

    cin.get(); 
    delete [] array_main; 
    return 0; 
} 

Выход:

Number to convert: 3001 

array_size in bytes: 48 
decimal % 2 = 1/1500 
decimal % 2 = 0 0 750 
decimal % 2 = 0 0 375 
decimal % 2 = 1 1 187 
decimal % 2 = 1/93 
decimal % 2 = 1 1 46 
decimal % 2 = 0 0 23 
decimal % 2 = 1 1 11 
decimal % 2 = 1 1 5 
decimal % 2 = 1 1 2 
decimal % 2 = 0 1 1 
decimal % 2 = 1 1 0 

MAIN: 1111101/100/ 

Каковы те слэша на выходе (1111101/100 /)?

+1

Одна вещь, о которой вы могли бы подумать, заключается в том, что значение в переменной 'decimal' уже находится в двоичном формате. Когда вы показываете его на экране, '' '' '' '' '' '' '' '' делает работу по преобразованию его в базу 10 для целей отображения, используя почти точно ту же самую процедуру, которую вы используете, чтобы отобразить ее в базе 2. Не так это будет влиять на ваше решение при использовании целых чисел, но когда вы работаете с значениями с плавающей запятой, это проявляется. – Eclipse

+0

Eclipse: Ну, я могу использовать cout << для отображения числа в двоичном формате, поскольку он уже двоичный, с некоторым модификатором формата? SETF (???)? Или cout << hex для шестнадцатеричного режима? –

ответ

2

Должно быть array_main[i] = (char) (decimal % 2 + '0'); (обратите внимание на круглые скобки). Но в любом случае код ужасен, напишите его снова с нуля.

+0

Phillip: да код ужасно, я провел несколько часов, пытаясь найти то, что я нашел в сети, чтобы сделать эту работу. Ну, это было весело. Кстати, спасибо за комментирование. –

0

Я не пробовал анализировать весь ваш код в деталях, но просто взглянул на него и увидел delete [] array_main; в двух местах, что вызывало у меня подозрение. Длина кода делает меня подозрительным. Преобразование числа в двоичный код должно занимать около двух или трех строк кода; когда я вижу код примерно как десять раз в течение долгого времени, я склонен думать, что анализ его подробно не стоит проблем - если бы мне пришлось это сделать, я бы только начал ...

Редактировать: о том, как сделать работу лучше, моя непосредственная реакция была бы начать с чего-то на этом общем порядке:

// warning: untested code. 
std::string dec2str(unsigned input) { 
    std::deque<char> buffer; 
    while (input) { 
     buffer.push_front((input & 1)+'0'); 
     input >>= 1; 
    } 
    return std::string(&buffer[0], &buffer[0]+buffer.size()); 
} 

в то время как я не проверял это, достаточно просто, что я был бы удивлен, если бы любые ошибки выше уровня простых опечаток (и это достаточно короткое, что, похоже, не хватает места, чтобы скрыть больше одного или двух из них, в самом большинстве).

+0

Эти два удаления удаляют разные вещи, но оба являются неправильным размером, и требуется только один. –

+0

@Mike: no, оба вопроса 'delete' в вопросе удаляют' array_main', который выделяется только один раз. Contrariwise, 'binary_array' не удаляется нигде. –

+0

@Jerry: нет, первый удаляет тот, который называется 'array_main' в' decimalToBinary() '; второй удаляет объект, называемый 'array_main' в' main() ', который называется' binary_array' в 'decimalToBinary()'. Это просто искривлено и запутанно, не так. В отличие от размеров массивов и арифметики символов, которые являются неправильными. –

7

Ваша проблема здесь:

array_main[i] = (char) decimal % 2 + '0'; 

Вы бросаете decimal к char и он ударяя от биты высокого порядка, так что в некоторых случаях она становится отрицательной. % отрицательное число отрицательно, поэтому вы получаете один символ до 0 в диаграмме ASCII, который равен /.

Я также хотел бы сказать, что я думаю, что ваши макросы WRITEL и WRITE относятся к категории препроцессоров. :-)

+1

Злоупотребление действительно. Я бы ожидал 'WRITE (1 << 4)' для печати 16, а не 14. –

+1

Ваша оценка прекрасна, но вы можете добавить, что для ее решения он может поместить 'decimal% 2 + '0'' в скобках, чтобы актерский состав произошел в результате его операции (что, вероятно, было намерением и дало соответствующие символы) – sleepynate

+0

Саймон: Так что я получил /. И я подумал, как можно поместить целое число в массив символов без потерь ... Еще один вопрос, почему злоупотребление препроцессором WRITE и WRITEL? Я думал, что такие обычаи все в порядке. Может случиться что-то плохое? –