## Please explain ASCII to Binary

7 posts / 0 new
Author
Message

hi   freaks, I'm newbie here , can any one explain

unsigned char ascii_to_bin( char data )
{
if( data < 'A' )
{
return( data - '0' );
}
else
{
return( data - 55 );
}
}

How it will work

Last Edited: Mon. Jan 4, 2016 - 04:22 AM

Refer to your handy ASCII Table.  Note that the hex value for ASCII 0 is 0x30.  Subtract 0x30 from the hex value for ASCII 9.  What do you get?  Yes, 0x09.  Similarly for ASCII 8, ASCII 7, etc.  For ASCII F, you subtract 0d55 to get 0x0F.  Similarly for ASCII E, ASCII D, etc.

Study the table a bit and you will get it.

In consideration of others, please RTFM!

To be honest that is not very good code. I think it would have been more readable if written as:

unsigned char ascii_to_bin( char data )
{
if( data < 'A' )
{
return( data - '0' );
}
else
{
return( data - 'A' + 10 );
}
}

because that mysterious "55" value in there is exactly the same as "- 'A' + 10".

Think about what they are trying to achieve here. They want to convert '0'..'9', 'A'..'F' into 0x00, 0x01, 0x02 ... 0x0E, 0x0F. The values '0'..'9' are adjacent so if it had simply been '0'..'9' into 0x00 . .0x09 the code would simply have been:

unsigned char ascii_to_bin( char data )
{
return( data - '0' );
}

Hopefully that is fairly obvious? The character '0' has an ASCII value of 0x30 not the 0x00 that you want here so to get from 0x30 to 0x00 (or say from 0x37 to 0x07 etc.) you need to subtract 0x30 (that is '0') from the value.

But once you introduce "hex" and need to handle 'A' .. 'F' as well as '0' .. '9' you are faced with two different conversions. The character 'A' has ASCII value 0x41 (65) so if you wanted to convert 'A'..'F' to simply 0x00..0x05 you would subtract 65 (which is 0x41 or 'A') from it. So the routine:

unsigned char AF_to_05( char data )
{
return( data - 'A' );
}

would achieve this. But the 'A' .. 'F' values are actually 10..15 not 0..5 so you then need to bump this up by 10. You could do this with:

unsigned char AF_to_1015( char data )
{
return( data - 'A' + 10);
}

or because 'A' is 65 then "- 65 + 10" is the same as simply "- 55" and that's what you see in the code you showed.

However, as I say, it makes much more sense ( I think!) to the maintainer if you write that mysterious 55 as this "- 'A' + 10" instead. You are saying first take the 'A' .. 'F' and throw away the "ASCIIness" of it by subtracting 'A' then bump the 0..5 up to the 10..15 position by adding 10 back to the result.

BTW if you don't know ASCII I think it helps to study a table such as:

http://www.asciitable.com/

in which you can see that '0' .. '9' are 0x30..0x39 (that is 48 .. 57 in decimal) and that that 'A' to 'F' are 0x41 .. 0x46 (that is 65 to 70).

As an exercise you might want to consider how this routine could be extended to cope with 'a' .. 'f' (0x61.. 0x66) as well as 'A' .. 'F' ;-)

PS forgot to say that it's all very well writing this kind of ascii_to_bin() routine yourself but C already comes with a function called strtol()/strtoul() ((ASCII) string to long) that handles all this (and more) anyway. So I would be tempted to use that rather than rewriting things from scratch.

Last Edited: Mon. Jan 4, 2016 - 09:57 AM

YAAT - To find 'Yet Another ASCII Table' you might want to look at one derived from a chart that used to be included with many Heathkits.

Follow the Decimal - Binary - Octal - Hex ASCII Conversion Chart link at http://web.alfredstate.edu/weimandn/ ,  make sure you scroll down to see the information below the chart.

Don

Well, you're not understanding ASCII.

Remember when you were 7 and you and your friends would make up codes: 1 is A, 2 is B, 3 is C and so on?

A computer doesn't understand letters, only numbers. Well, actually it doesn't understand anything, but we pretend. So we assign numbers to the letters and it's up to us to know this number actually represents a letter. In this code, 32 is a space, 48 is a zero, 49 is a one, 65 is a capital A, 66 is a capital B, and 97 is a small A. You can find the whole code at http://www.ascii-code.com/

In most languages, the compiler will do the coding for us. We can put text in quotes like "ABC" and the compiler will generate 4 numbers, 65, 66, 67, 0 for us. Many displays, printers and the like use the same code, so you can output 123 and get a "{." If you're using a graphic display where your program has to draw the characters itself, you can, of course, use any code you like, but the standard ASCII is convenient since the compiler will code text for you. Sometimes you want to change the code, like if you have to store a font in limited program memory, you might put 0 is space and not take up space with the bottom 32. If you keep the same order as ASCII, then your draw character function can translate from ascii to your code by just subtracting:

uint16_t BitPointer = * (font + (c-31)*2);

See, I got a pointer to my character in the "font" by subtracting 31 from the code, multiplying by 2, since there are 2 bytes per character, and adding the address of the data in memory. This lets me write

LCDWriteString(10, 100,Tahoma24, "Hello World") ;

Even though my "font" in flash isn't really ascii.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut.

Last Edited: Mon. Jan 4, 2016 - 02:41 PM

Noone has mentioned 'a'-'f'?  Or error handling, if NAN?

But in context, OP just asked to explain the code snippet.

https://github.com/qca/open-plc-...

The C standard mentions isdigit() and isxdigit().  Once vetted with those functions, then what would be the C-standard way of doing the conversion?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.