Soy estúpido ahora a resolver este problema…

Puedo obtener un número BCD (cada dígito es un 4Bit representación)

Por ejemplo, lo que yo quiero:

  • De entrada: 202 (hex) == 514 (dec)
  • De salida: BCD 0x415
  • De entrada: 0x202
  • De los bits de la representación: 0010 0000 0010 = 514

Lo he probado:

unsigned int uiValue = 0x202;
unsigned int uiResult = 0;
unsigned int uiMultiplier = 1;
unsigned int uiDigit = 0;


//get the dec bcd value
while ( uiValue > 0 )
{
    uiDigit= uiValue & 0x0F;
    uiValue >>= 4;
    uiResult += uiMultiplier * uiDigit;
    uiMultiplier *= 10;
}

Pero sé que está muy mal esto sería 202 en representación de Bit y luego se divide en 5 nibbles y, a continuación, representado como número decimal de nuevo

Puedo resolver el problema sobre el papel, pero yo no puedo conseguir en un simple Código C

Puedo sugerir que, cuando se trabaja con bytes y mordisquea, hex máscaras son más fáciles de poner en contexto? por ejemplo 0x0F es más que obvio que 15 (al menos para mí!)
He añadido algo más de información
eso es tan cierto, va a cambiar esto. thx
Pero él dijo que uiValue = 202, no 0x202.... Y si era 0x202, entonces el BCD valor decimal 202…
Por lo tanto, mi respuesta a continuación…

OriginalEl autor Sagi | 2012-11-06

5 Comentarios

  1. 8

    Tienes al revés. Su código es la conversión de BCD a binario, así como su pregunta (original) título dice. Pero la entrada y la salida de los valores proporcionados son correctos sólo si se convierte binario a BCD. En ese caso, trate de:

    #include <stdio.h>
    
    int main(void) {
    
       int binaryInput = 0x202; 
       int bcdResult = 0;
       int shift = 0;
    
       printf("Binary: 0x%x (dec: %d)\n", binaryInput , binaryInput );
    
       while (binaryInput > 0) {
          bcdResult |= (binaryInput % 10) << (shift++ << 2);
          binaryInput /= 10;
       }
    
       printf("BCD: 0x%x (dec: %d)\n", bcdResult , bcdResult );
       return 0;
    }

    Prueba: http://ideone.com/R0reQh

    Gracias, eso es lo que yo necesitaba 🙂 es casi el mismo código como el que yo tenía, pero me fui a la dirección equivocada… Gracias
    Lo siento, mi comentario anterior es un error pero no puedo quitarlo.
    Muchas gracias, esto me ha ayudado. Una pequeña nota: no estoy seguro si este era su objetivo, pero la salida BCD nibbles salir ordenó «menos importante». En mi caso, yo quería que la nibbles «más importante», por lo que tuve que cambiar cada mordisco a la izquierda por un incremento múltiplo de 4 (cambio justo después de tomar el modulo) y sólo entonces O la pre-desplazado a mordisquear el resultado. Nota cómo el algoritmo (%10, /=10) se inicia desde el de menor orden dígitos decimales y se procede a órdenes superiores.
    usted, por supuesto, correcto. Fue un simple error, y me fijo el código. Gracias por informar!

    OriginalEl autor Daniel Gehriger

  2. 1

    Un ingenuo, pero simple solución:

    char buffer[16];
    sprintf(buffer, "%d", var);
    sscanf(buffer, "%x", &var);
    No es que esto va a producir un hex, donde como el OP pidió BCD? Que no son equivalentes. Yo no voto, aunque. Es un cuerpo de otra persona
    A partir de la primera revisión de su pregunta era evidente que él quería convertir 202 a 514, hace justamente eso.
    Pero él quiere 514 BCD no 514 Hex
    él empezó a querer que después de mi respuesta, me contestó a la primera revisión, en la que declaró que sólo entrada fue en BCD
    No sé, tengo que responder a la pregunta del título, en la cuestión del cuerpo o en el código de ejemplo. Son tres distintos.

    OriginalEl autor panda-34

  3. 1

    El verdadero problema aquí es la confusión de las bases y unidades

    El 202 debería ser HEXAGONAL, lo que equivale a 514 decimal… y por lo tanto el BCD calcs son correctos

    Código binario decimal va a convertir el número decimal (514) en tres picar tamaño de los campos:
    – 5 = 0101
    – 1 = 0001
    – 4 = 0100

    El problema más grande era que tiene el título al revés, y que va a convertir Uint a BCD, mientras que el título pidió BCD a Unint

    Andrés, no es tan complicado como eso. No hay necesidad de convertir de hexadecimal a decimal para encontrar el valor BCD.
    NO, pero creo que explica la confusión… 0x202 == 514(bcd), mientras que 202(dec) == 202(bcd)
    El otro camino, 0x202 == 202 (bcd).
    Eh? Deja ir lo más simple… 10d = 0Ah = (0001 0000)BCD == «10»bcd no «0A»bcd… así que, ¿cómo puede 0x202 == 202 BCD?
    10d = 0Ah tiene una representación binaria de 0000 1010 , así que supongo que depende de si su 202 significa bcd, decimal o hexadecimal. Sin duda uiValue = 202 está mal, aunque el texto dice que debe ser hex: Input: 202 (hex) Si la entrada es 0x202 como dice el texto, la representación binaria de la entrada es 0000 0010 0000 0010, que se puede convertir fácilmente en bcd.

    OriginalEl autor Andrew

  4. 1

    Tratar el siguiente.

    unsigned long toPackedBcd (unsigned int val)
    {
      unsigned long bcdresult = 0; char i;
    
    
      for (i = 0; val; i++)
      {
        ((char*)&bcdresult)[i / 2] |= i & 1 ? (val % 10) << 4 : (val % 10) & 0xf;
        val /= 10;
      }
      return bcdresult;
    }

    También se puede intentar la siguiente variante (aunque tal vez poco ineficaz)

    /*
    Copyright (c) 2016 enthusiasticgeek<[email protected]> Binary to Packed BCD
    This code may be used (including commercial products) without warranties of any kind (use at your own risk)
    as long as this copyright notice is retained.
    Author, under no circumstances, shall not be responsible for any code crashes or bugs.
    Exception to copyright code: 'reverse string function' which is taken from http://stackoverflow.com/questions/19853014/reversing-a-string-in-place-in-c-pointers#19853059
    Double Dabble Algorithm for unsigned int explanation
    255(binary) - base 10 -> 597(packed BCD) - base 16
    H|    T|    U|        (Keep shifting left)
    11111111
    1 1111111
    11 111111  
    111 11111
    1010 11111    <-----added 3 in unit's place (7+3 = 10) 
    1 0101 1111  
    1 1000 1111     <-----added 3 in unit's place (5+3 = 8)
    11 0001 111
    110 0011 11       
    1001 0011 11       <-----added 3 in ten's place (6+3 = 9)
    1 0010 0111 1  
    1 0010 1010 1        <-----added 3 in unit's place (7+3 = 10)
    10 0101 0101  -> binary 597 but bcd 255
    ^    ^    ^  
    |    |    |
    2    5    5   
    */
    #include <stdio.h>   
    #include <string.h>
    //Function Prototypes
    unsigned int binaryToPackedBCD (unsigned int binary); 
    char * printPackedBCD(unsigned int bcd, char * bcd_string);
    //For the following function see http://stackoverflow.com/questions/19853014/reversing-a-string-in-place-in-c-pointers#19853059
    void reverse(char *str);
    //Function Definitions
    unsigned int binaryToPackedBCD (unsigned int binary) {
    const unsigned int TOTAL_BITS = 32;
    /*Place holder for bcd*/
    unsigned int bcd = 0;
    /*counters*/
    unsigned int i,j = 0;
    for (i=0; i<TOTAL_BITS; i++) {
    /*
    Identify the bit to append  to LSB of 8 byte or 32 bit word -
    First bitwise AND mask with 1. 
    Then shift to appropriate (nth shift) place. 
    Then shift the result back to the lsb position. 
    */
    unsigned int binary_bit_to_lsb = (1<<(TOTAL_BITS-1-i)&binary)>>(TOTAL_BITS-1-i);
    /*shift by 1 place and append bit to lsb*/
    bcd = ( bcd<<1 ) | binary_bit_to_lsb;       
    /*printf("=> %u\n",bcd);*/
    /*Don't add 3 for last bit shift i.e. in this case 32nd bit*/
    if( i >= TOTAL_BITS-1) { 
    break;
    }
    /*else continue*/
    /* Now, check every nibble from LSB to MSB and if greater than or equal 5 - add 3 if so */
    for (j=0; j<TOTAL_BITS; j+=4) {
    unsigned int temp = (bcd & (0xf<<j))>>j;
    if(temp >= 0x5) {
    /*printf("[%u,%u], %u, bcd = %u\n",i,j, temp, bcd);*/
    /*Now, add 3 at the appropriate nibble*/
    bcd = bcd  + (3<<j);
    //printf("Now bcd = %u\n", bcd);
    }
    }
    }
    /*printf("The number is %u\n",bcd);*/
    return bcd;
    }   
    char * printPackedBCD(unsigned int bcd, char * bcd_string) {
    const unsigned int TOTAL_BITS = 32;
    printf("[LSB] =>\n");
    /* Now, check every nibble from LSB to MSB and convert to char* */
    for (unsigned int j=0; j<TOTAL_BITS; j+=4) {
    //for (unsigned int j=TOTAL_BITS-1; j>=4; j-=4) {
    unsigned int temp = (bcd & (0xf<<j))>>j;
    if(temp==0){
    bcd_string[j/4] = '0';      
    } else if(temp==1){
    bcd_string[j/4] = '1';
    } else if(temp==2){
    bcd_string[j/4] = '2';
    } else if(temp==3){
    bcd_string[j/4] = '3';
    } else if(temp==4){
    bcd_string[j/4] = '4';
    } else if(temp==5){
    bcd_string[j/4] = '5';
    } else if(temp==6){
    bcd_string[j/4] = '6';
    } else if(temp==7){
    bcd_string[j/4] = '7';
    } else if(temp==8){
    bcd_string[j/4] = '8';
    } else if(temp==9){
    bcd_string[j/4] = '9';
    } else {
    bcd_string[j/4] = 'X';
    }
    printf ("[%u - nibble] => %c\n", j/4, bcd_string[j/4]);
    }      
    printf("<= [MSB]\n");
    reverse(bcd_string);
    return bcd_string;
    }
    //For the following function see http://stackoverflow.com/questions/19853014/reversing-a-string-in-place-in-c-pointers#19853059
    void reverse(char *str)
    { 
    if (str != 0 && *str != '\0') //Non-null pointer; non-empty string
    {
    char *end = str + strlen(str) - 1; 
    while (str < end)
    {
    char tmp = *str; 
    *str++ = *end; 
    *end-- = tmp;
    } 
    }
    }
    int main(int argc, char * argv[])
    {
    unsigned int number = 255;
    unsigned int bcd = binaryToPackedBCD(number);
    char bcd_string[8];
    printPackedBCD(bcd, bcd_string);
    printf("Binary (Base 10) = %u => Packed BCD (Base 16) = %u\n OR \nPacked BCD String = %s\n", number, bcd, bcd_string);
    return 0;
    }
    Puedo probar esta función, y que parece funcionar al principio, pero yo no lo he probado para números muy grandes o la comparación de su eficiencia con la outlier candidato algoritmo para hacer la conversión, por ejemplo, de 11 a 17 o de la misma manera. (Mi proyecto es de código C para el 7-segmentos Led de la Altera DE2 FPGA.)

    OriginalEl autor enthusiasticgeek

  5. 0

    Esta es la solución que he desarrollado y funciona muy bien para sistemas embebidos, como la de los microcontroladores PIC de Microchip:

    #include <stdio.h>
    void main(){
    unsigned int output = 0;
    unsigned int input;
    signed char a;
    //enter any number from 0 to 9999 here:
    input = 1265;
    for(a = 13; a >= 0; a--){
    if((output & 0xF) >= 5)
    output += 3;
    if(((output & 0xF0) >> 4) >= 5)
    output += (3 << 4);
    if(((output & 0xF00) >> 8) >= 5)
    output += (3 << 8);
    output = (output << 1) | ((input >> a) & 1);
    }
    printf("Input decimal or binary: %d\nOutput BCD: %X\nOutput decimal: %u\n", input, output, output);
    }

    OriginalEl autor Ernesto Flôres Barreira

Dejar respuesta

Please enter your comment!
Please enter your name here