2010-07-14 5 views
0

J'ai écrit un programme pour convertir décimal en binaire à des fins de pratique, mais j'ai une sortie étrange. Lorsque je fais un modulo avec un nombre décimal, j'obtiens une valeur correcte mais qu'est-ce qui va dans le tableau est une barre oblique? J'utilise char array pour pouvoir utiliser simplement la sortie avec cout < <.Decimal to Binary, sortie étrange

// 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; 
} 

La sortie:

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/ 

Quels sont les barres obliques en sortie (1111101/100 /)?

+1

Une chose que vous pourriez penser, c'est que la valeur de la variable 'decimal' est déjà en binaire. Lorsque vous l'affichez à l'écran, l'opérateur '' de '' 'de' de 'de' est en train de le convertir en base 10 à des fins d'affichage, en utilisant presque exactement la même routine que vous utilisez pour l'afficher en base 2. Non cela affectera votre solution, lors de l'utilisation de nombres entiers, mais lorsque vous travaillez avec des valeurs à virgule flottante, cela s'affiche. – Eclipse

+0

Eclipse: Puis-je utiliser cout << pour afficher le nombre en binaire car il est déjà binaire, avec un modificateur de format? setf (???)? Ou cout << hex pour le mode hexadécimal? –

Répondre

2

Il doit être array_main[i] = (char) (decimal % 2 + '0'); (notez les parenthèses). Mais de toute façon, le code est horrible, s'il vous plaît écrivez-le à partir de zéro.

+0

Phillip: oui le code est horrible, j'ai passé plusieurs heures à essayer tout ce que j'ai trouvé sur le net pour faire ce travail. Eh bien, c'était amusant. Btw, merci de commenter. –

0

Je n'ai pas essayé d'analyser tout votre code en détail, mais juste le regarder et voir delete [] array_main; dans deux endroits me rend suspect. La longueur du code me rend également suspect. Convertir un nombre en binaire devrait prendre environ deux ou trois lignes de code; quand je vois du code quelque chose comme dix fois plus long, j'ai tendance à penser que l'analyser en détail n'en vaut pas la peine - si je devais le faire, je recommencerais ...

Editer: quant à la façon de faire le travail mieux, ma réaction immédiate serait de commencer par quelque chose de cet ordre général:

// 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()); 
} 

Bien que je ne l'ai pas testé, il est assez simple que je serais surpris s'il y avait toutes les erreurs au-dessus du niveau de fautes de frappe simples (et c'est assez court qu'il ne semble pas y avoir de place pour cacher plus d'un ou deux d'entre eux, tout au plus).

+0

Les deux suppressions suppriment des choses différentes, mais les deux ont la mauvaise taille et une seule est nécessaire. –

+0

@Mike: non, les deux 'delete's en question suppriment' array_main', qui est seulement alloué une fois. Par contre, 'binary_array' n'est pas supprimé n'importe où. –

+0

@Jerry: non, le premier supprime celui appelé 'array_main' dans' decimalToBinary() '; la seconde supprime celle appelée 'array_main' dans' main() ', appelée' binary_array' dans 'decimalToBinary()'. C'est juste tordu et confus, pas faux. Contrairement aux tailles de tableau et à l'arithmétique des caractères, qui sont fausses. –

7

Votre problème est ici:

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

Vous jettes decimal à char et il est hors glisser les bits de poids fort, de sorte que dans certains cas, il devient négatif. % appliqué à un nombre négatif est négatif, d'où vous obtenez un caractère avant 0 dans le tableau ASCII, qui est /.

Je voudrais aussi dire que je pense que vos macros WRITEL et WRITE sont qualifiées d'abus de préprocesseur. :-)

+1

Abus en effet. Je m'attendrais 'WRITE (1 << 4)' à imprimer 16, pas 14. –

+1

Votre évaluation est parfaite, mais vous pouvez ajouter que pour le résoudre, il peut placer le 'décimal% 2 + '0'' entre parenthèses de sorte que la distribution ait lieu sur le résultat de son opération (ce qui était probablement l'intention, et donne les caractères appropriés) – sleepynate

+0

Simon: Donc, ce que j'ai eu /. Et je pensais comment est-il possible de mettre des nombres entiers dans le tableau char sans perdre ... Une autre question, pourquoi est-WRITE et WRITEL préprocesseur abus? Je pensais que de tels usages allaient bien. Quelque chose de mauvais peut-il arriver? –