Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Binääriluku heksaluvuksi

Sivun loppuun

timok16 [18.06.2006 07:39:17]

#

moikka,
Saisko hjelppiä tähän mun koodiin. koodin pitäis muuttaa binääriluku(32 bit) hexaluvuksi, mutta jokin mättää siinä.

#include <stdio.h>
#include <string.h>
#include <ctype.h>

/*********************************************************/
/**Global variables************************************/
char bitstring[8*sizeof(int)+1]; /* Sets the array to the size of int * 8 + 1 */
char hexstring[2*sizeof(int)+1]; /* Sets the array to the size of int * 2 + 1 */

/*********************************************************/

int main(void)
   {

  int count = 32;
  int n1, n2;
  unsigned char ch;
  int i;
  char bitstring[33] ={'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
  '0','0','0','0','0','0','0','0','0','0','0','0','1','0','1','0'};
    //näiden pitäisi olla varmaan int-tyyppisiä????
   printf("Bittijono = %s ",bitstring);

  for (n1 = 0, n2 = 0; n1 < count; n1+=8)
    {

       /* first nibble */
	  ch = ((((bitstring[n1] << 1) + bitstring[n1+1] << 1) + bitstring[n1+2] << 1) + bitstring[n1+3]);
      if (ch <= 0x09)
        hexstring[n2++] = ch + '0';
          else
         hexstring[n2++] = ch - 10 + 'a';


       /* second nibble */
		  ch = ((((bitstring[n1+4] << 1) + bitstring[n1+5] << 1) + bitstring[n1+6] << 1) + bitstring[n1+7]);
      if (ch <= 0x09)
         hexstring[n2++] = ch + '0';
          else
         hexstring[n2++] = ch - 10 + 'a';

    }
  hexstring[n2]='\0';
          printf("\t");
          printf(" Bitit hexana %s\n", hexstring);
		  printf("tasta bittijonosta pitais tulla hexana a-kirjain");

   printf("\n");

return 0;
   }

Metabolix [18.06.2006 16:55:48]

#

Unohdat vähentää taulukon alkioista aluksi sen ASCII-nollan arvon.
'0' != 0;
Koodi olisi vielä loogisempi, kun poistaisit tuon toiston (second nipple) ja sen sijaan silmukan nousemaan neljän hyppäyksin kahdeksan sijaan. Tuon taulukon alustusarvot voisit erotella väleillä tai laittaa hieman tiiviimpään tilaan ihan vain tekstinä tyyliin "0101".

timok16 [18.06.2006 18:13:38]

#

moi,

kysyy, että kuinka vähennän taulukon alkioista ton ASCII-arvon '0', joka on des. 48. teenkö jonkun silmukan joka käy läpi jokaisen tavun, ja kuinka se tapahtuu?

thanx kuitenkin

L2-K2 [18.06.2006 23:47:46]

#

'0' = 48 (110000); '1' = 49(110001)

vertaa sitä exlusiivisella tai:lla lukuun 48 (110000)
C:ssä (int)(48^asciiLuku)

tai vähennä siitä 48
C:ssä (int)(asciiLuku-48)

EDIT:
Pienen etsinnän jälkeen löysin koneeltani ratkaisun samaan ongelmaan:

#include <stdio.h>
int main(int argc, char** argv)
{
    unsigned long luku = 0;
    unsigned long i;
    int j;
    if(argc>0)
        for(i=2147483648,j=0;j<32;i/=2,j++) //2^31=2147483648
        {
            luku += i * (48^((int)argv[1][j]));
        }
    printf("%0x\n", luku);
    return 0;
}

PS: Tämä ei tarkista onko syöte kelvollinen vaan se jää käyttäjän vastuulle. Kääntyy (ainakin) Mingw:llä.

Metabolix [19.06.2006 10:14:50]

#

Se on ihan itsestäsi kiinni, kunhan vain käytössä on (taulukko[i]-'0') joka kerta. Voit vähentää sen silmukalla kerran aluksi kaikista tai kirjoittaa tuon vähennyksen jokaiseen kohtaan erikseen.

timok16 [19.06.2006 17:33:16]

#

moi,

Jotain on vielä pahasti pielessä. Vähennän kaikista alkioista ton ASCII nollan '0' , mutta koodi tulostaa aina vain hexajonoksi 33333333, kun bittijonona on toi
"00000000000000000000000000001010". Jos toimis oikein, pitäis tulla tulostukseksi 0000000a täs vielä koodini.

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

char hexstring[2*sizeof(int)+1];

int main(void)
   {

  int count = 32;
  int n1, n2;
  unsigned char ch;
  char bitstring[33];
  int i;

 char string[33] ="00000000000000000000000000001010";

 for (i=0;i<=32;i++)
	{
 string[i]-'0';
 bitstring[i] = string[i];
 	}
 printf("Bits = %s ",bitstring);

  for (n1 = 0, n2 = 0; n1 < count; n1+=8)
    {

       /* first nibble */
	  //ch = ((((bitstring[n1] << 1) + bitstring[n1+1] << 1) + bitstring[n1+2] << 1) + bitstring[n1+3]);
      ch = bitstring[n1] >> 4;
	  if (ch <= 0x09)
        hexstring[n2++] = ch + '0';
          else
         hexstring[n2++] = ch - 10 + 'a';

       /* second nibble */
	    ch = ((((bitstring[n1+4] << 1) + bitstring[n1+5] << 1) + bitstring[n1+6] << 1) + bitstring[n1+7]);
        //ch = bitstring[n1] & 0xf0;
		if (ch <= 0x09)
         hexstring[n2++] = ch + '0';
          else
         hexstring[n2++] = ch - 10 + 'a';
    }
  hexstring[n2]='\0';
          printf("\t");
          printf(" Bitit hexana %s\n", hexstring);
		  printf("tasta bittijonosta pitais tulla hexana a-kirjain");

   printf("\n");

return 0;
   }

sainkin sen toimimaan, kun laitoin silmukan näin:

  char bitstring[33];
  int i;

 char string[33] ="00000000000000000000000000001010";

 for (i=0;i<=32;i++)
	{
 string[i] = string[i] -'0';
 bitstring[i] = string[i];
 	}

ja nyt tulee hexana 0000000a

Metabolix [19.06.2006 17:36:19]

#

Teepä vähän selvempää koodia, jotta sitä lukevat muutkin helpommalla.

Nyt ovat ihan alkeet hakusessa. Mitenkäs se vähennyslasku tapahtuukaan? Ei sentään aivan tuolla omalla koodillasi, joka näytti tältä:

string[i]-'0';
bitstring[i] = string[i];

Se vähennyslaskun tulos kannattaa jonnekin laittaa, tuossa nyt vain lasketaan se mutta jätetään tulos huomiotta, ja bitstring-muuttujaan päätyy alkuperäinen arvo.

timok16 [19.06.2006 18:02:23]

#

kun käyttää tätä c:tä ani harvoin, niin meinaa ruveta unohtumaan se mitä on joskus oppinut. Ihan kiva kun kommentoit noin isällisesti.

timok16 [20.06.2006 14:52:07]

#

moi,
tää koodi toimii, mutta pitää saada vielä tulostus muotoon 0x54, siis pitää liittää tohon hexalukuun toi etuliite 0x.

#include <stdio.h>
//#include <string.h>
//#include <ctype.h>
//#include <stdlib.h>

int main(void)
   {

  int count = 32;
  int n1, n2;
  unsigned char ch;
  char bitstring[33];
  char hexstring[9];
  int i;

 char string[] ="00000000000000000000000001010100";


 for (i=0;i<=count;i++)
	{
   bitstring[i] = string[i]-'0';//vähennetään taulukon alkioista ASCII-arvo '0' = des. 48
								//, muutetaan numeroksi ja laitetaan talteen bitstring-taulukkoon
	}
 	printf("Bits = %s ",string);

  for (n1 = 0, n2 = 0; n1 < count; n1+=8)
    {

       /* first nibble */
	  ch = ((((bitstring[n1] << 1) + bitstring[n1+1] << 1) + bitstring[n1+2] << 1) + bitstring[n1+3]);
	  if (ch <= 0x09)
        hexstring[n2++] = ch + '0';
          else
         hexstring[n2++] = ch - 10 + 'a';


       /* second nibble */
	    ch = ((((bitstring[n1+4] << 1) + bitstring[n1+5] << 1) + bitstring[n1+6] << 1) + bitstring[n1+7]);
		if (ch <= 0x09)
         hexstring[n2++] = ch + '0';
          else
         hexstring[n2++] = ch - 10 + 'a';

    }
  hexstring[n2]='\0';
          printf("\t");
          printf(" Bitit hexana %s\n", hexstring);

   printf("\n");

return 0;
   }

Nyt tulee tulokseksi 00000054. ja pitäis saada 0x54

Metabolix [20.06.2006 23:33:36]

#

Ensinnäkin tarvitset tauluun tietenkin kaksi merkkiä enemmän tilaa. Aseta alkuun 0 ja x ja muuta silmukkasi alkuun n2 = 2. Laita tuo merkinlisäyksen sisältävä if-lause sellaisen iffin sisään, jossa tarkistat, onko n2 yhä 2 ja lisättävä merkki 0, jolloin merkkien lisääminen alkaa vasta ensimmäisestä muusta numerosta.

if (n2 != 2 || ch != 0) {
  hexstring[n2++] = ch + (ch < 10 ? '0' : 'a' - 10);
}

koo [21.06.2006 09:46:43]

#

Jotenkin tuntuu, että hommaa yritetään hoitaa turhan vaikeasti. Olisiko tämmöisestä pätkäleestä mitään apua?

#include <stdio.h>
#include <stdlib.h>

int main()
{
        const char *str = "00000000000000000000000001010100";
        char *end; /* esim. virheentarkistusta varten */
        long val;
        val = strtol(str, &end, 2);
        printf("%s = %#lx\n", str, val);
}

Voi homman itsekin väkästää, yleensä tulos on standardikirjastoja huonompi ja virheentarkastusten kanssa on vähän niin ja näin. Tässä nyt aika yksinkertainen yritelmä:

#include <stdio.h>

long bitstr_to_long(const char *s)
{
        long li;
        for (li = 0; *s != '\0'; ++s)
        {
                li <<= 1;
                if ((*s - '0') != '\0')
                        ++li;
        }
        return li;
}

char *long_to_hexstr(char *s, long li)
{
        const char *x = "0123456789abcdf";
        char *ret;
        unsigned long ul;
        int i;
        char tmp[sizeof(long)*2];
        ret = s;
        *s++ = '0';
        *s++ = 'x';
        if (li != 0) {
                for (ul = li, i = 0; ul != 0; ul /= 16)
                        tmp[i++] = x[ul % 16];
                while (i > 0)
                        *s++ = tmp[--i];
        } else {
                *s++ = '0';
        }
        *s = '\0';
        return ret;
}

int main()
{
        const char *str = "00000000000000000000000001010100";
        long val;
        char xstr[2+sizeof(long)*2+1];
        val = binstr_to_long(str);
        long_to_hexstr(xstr, val);
        printf("%s = %s\n", str, xstr);
}

Metabolix [21.06.2006 10:26:24]

#

Niin, olisi varmaan pitänyt katsoa, ketkä näitä kyselevät, huomata, että kyseessä oli eri henkilö ja linkittää tännekin:
https://www.ohjelmointiputka.net/keskustelu/12585-kymmen-ja-binäärijärjestelmä

Sinne laitoin jo maanantaina muunokset ties mihin.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta