I have a character returned from something which returns character 20. I am trying to send this number 20 to another thing for it to display on an LCD, however when I put in 20, it shows 14. so I have tried multiple things like:
char x = 20;
char y = '0x' + x;
to literally try and combine them into "0x20" (20 in hexadecimal). I know when typing in "0x20" into my function it returns with the number 20, however trying the code I just showed you always returns "14" or some weird other form that is not number.
So what I am asking is:
If I have the char 20 that is supposed to show the number "20" since it gets sent somewhere in hex/binary, how do I make it "0x20"?
Small note: number 20 is 0x14 in hex when converted. I am trying to show 20 instead (well send 0x20). I have to use numbers that are higher than this so I have to make sure that i am always doing 0x20, 0x21.. 0x30... etc.
any char that is "1", "2" (under 10) is fine. it is just numbers 10 and above.
Get the tens digit of the value and multiply that by 16 to get the first digit of the corresponding hex value. Then add the ones digit of the number and add that.
char dec = 20;
char hex = 16 * (dec / 10) + dec % 10;
This assumes it's only up to 2 digits. The other answer shows how to do it for up to 3 digits.
unsigned convert(unsigned char x)
{
return (x % 10) + ((x / 10) % 10) * 16 + ((x / 100) % 10) * 16 * 16;
}
int main(void)
{
printf("Converted: 0x%x\n", convert(20));
printf("Converted: 0x%x\n", convert(120));
printf("Converted: 0x%x\n", convert(155));
printf("Converted: 0x%x\n", convert(255));
}
Related
If I have a number string (char array), one digit is one char, resulting in that the space for a four digit number is 5 bytes, including the null termination.
unsigned char num[] ="1024";
printf("%d", sizeof(num)); // 5
However, 1024 can be written as
unsigned char binaryNum[2];
binaryNum[0] = 0b00000100;
binaryNum[1] = 0b00000000;
How can the conversion from string to binary be made effectively?
In my program i would work with ≈30 digit numbers, so the space gain would be big.
My goal is to create datapackets to be sent over UDP/TCP.
I would prefer not to use libraries for this task, since the available space the code can take up is small.
EDIT:
Thanks for quick response.
char num = 0b0000 0100 // "4"
--------------------------
char num = 0b0001 1000 // "24"
-----------------------------
char num[2];
num[0] = 0b00000100;
num[1] = 0b00000000;
// num now contains 1024
I would need ≈ 10 bytes to contain my number in binary form. So, if I as suggested parse the digits one by one, starting from the back, how would that build up to the final big binary number?
In general, converting a number in string representation to decimal is easy because each character can be parsed separately. E.g. to convert "1024" to 1024 you can just look at the '4', convert it to 4, multiply by 10, then convert the 2 and add it, multiply by 10, and so on until you have parsed the whole string.
For binary it is not so easy, e.g. you can convert 4 to 100 and 2 to 010 but 42 is not 100 010 or 110 or something like that. So, your best bet is to convert the whole thing to a number and then convert that number to binary using mathematical operations (bit shifts and such). This will work fine for numbers that fit in one of the C++ number types, but if you want to handle arbitrarily large numbers you will need a BigInteger class which seems to be a problem for you since the code has to be small.
From your question I gather that you want to compress the string representation in order to transmit the number over a network, so I am offering a solution that does not strictly convert to binary but will still use fewer bytes than the string representation and is easy to use. It is based on the fact that you can store a number 0..9 in 4 bits, and so you can fit two of those numbers in a byte. Hence you can store an n-digit number in n/2 bytes. The algorithm could be as follows:
Take the last character, '4'
Subtract '0' to get 4 (i.e. an int with value 4).
Strip the last character.
Repeat to get 0
Concatenate into a single byte: digits[0] = (4 << 4) + 0.
Do the same for the next two numbers: digits[1] = (2 << 4) + 1.
Your representation in memory will now look like
4 0 2 1
0100 0000 0010 0001
digits[0] digits[1]
i.e.
digits = { 64, 33 }
This is not quite the binary representation of 1024, but it is shorter and it allows you to easily recover the original number by reversing the algorithm.
You even have 5 values left that you don't use for storing digits (i.e. everything larger than 1010) which you can use for other things like storing the sign, decimal point, byte order or end-of-number delimiter).
I trust that you will be able to implement this, should you choose to use it.
If I understand your question correctly, you would want to do this:
Convert your string representation into an integer.
Convert the integer into binary representation.
For step 1:
You could loop through the string
Subtract '0' from the char
Multiply by 10^n (depending on the position) and add to a sum.
For step 2 (for int x), in general:
x%2 gives you the least-significant-bit (LSB).
x /= 2 "removes" the LSB.
For example, take x = 6.
x%2 = 0 (LSB), x /= 2 -> x becomes 3
x%2 = 1, x /= 2 -> x becomes 1
x%2 = 1 (MSB), x /= 2 -> x becomes 0.
So we we see that (6)decimal == (110)bin.
On to the implementation (for N=2, where N is maximum number of bytes):
int x = 1024;
int n=-1, p=0, p_=0, i=0, ex=1; //you can use smaller types of int for this if you are strict on memory usage
unsigned char num[N] = {0};
for (p=0; p<(N*8); p++,p_++) {
if (p%8 == 0) { n++; p_=0; } //for every 8bits, 1) store the new result in the next element in the array. 2) reset the placing (start at 2^0 again).
for (i=0; i<p_; i++) ex *= 2; //ex = pow(2,p_); without using math.h library
num[n] += ex * (x%2); //add (2^p_ x LSB) to num[n]
x /= 2; // "remove" the last bit to check for the next.
ex = 1; // reset the exponent
}
We can check the result for x = 1024:
for (i=0; i<N; i++)
printf("num[%d] = %d\n", i, num[i]); //num[0] = 0 (0b00000000), num[1] = 4 (0b00000100)
To convert a up-to 30 digit decimal number, represented as a string, into a serious of bytes, effectively a base-256 representation, takes up to 13 bytes. (ceiling of 30/log10(256))
Simple algorithm
dest = 0
for each digit of the string (starting with most significant)
dest *= 10
dest += digit
As C code
#define STR_DEC_TO_BIN_N 13
unsigned char *str_dec_to_bin(unsigned char dest[STR_DEC_TO_BIN_N], const char *src) {
// dest[] = 0
memset(dest, 0, STR_DEC_TO_BIN_N);
// for each digit ...
while (isdigit((unsigned char) *src)) {
// dest[] = 10*dest[] + *src
// with dest[0] as the most significant digit
int sum = *src - '0';
for (int i = STR_DEC_TO_BIN_N - 1; i >= 0; i--) {
sum += dest[i]*10;
dest[i] = sum % 256;
sum /= 256;
}
// If sum is non-zero, it means dest[] overflowed
if (sum) {
return NULL;
}
}
// If stopped on something other than the null character ....
if (*src) {
return NULL;
}
return dest;
}
Let's supppose I have a variable with numeric value and I want to print it using 10 characters like the following: XXX XXXX XXX XXXX. So, for example, the number 10 would be printed as 000 0000 000 0010.
The closest I got in a straightforward way is using, for instance:
int value = 10;
printf("%010D", value);
However it produces, obviously:
0000000010
Does anyone know if there's any built-in function that could output
000 0000 000 0010
or it'd be necessary to implement one?
Thanks in advance
First note that a 32-bit int has a max value of 2,147,483,647. So a 14 digit number is impossible (except with at least 4 leading zeros). You'd need a 64-bit long long int to get 14 non-zero digits.
There is no simple library call that allows it, but making this happen is not hard. One way is to split the value with integer math. Another is by splitting a string:
int main(void) {
long long int value = 12345678901234;
// by string splitting...
char buf[32];
sprintf(buf, "%014lld", value);
printf("%.3s %.4s %.3s %.4s\n", buf, buf + 3, buf + 7, buf + 10);
// by integer modular arithmetic...
unsigned v0 = (unsigned)(value % 10000);
value /= 10000;
unsigned v1 = (unsigned)(value % 1000);
value /= 1000;
unsigned v2 = (unsigned)(value % 10000);
value /= 10000;
unsigned v3 = (unsigned)value;
printf("%03u %04u %03u %04u\n", v3, v2, v1, v0);
return 0;
}
I have a variable:
int a = 10;
I want to convert it to a hexadecimal value with 0x in front of 10 as: 0x10, and assign it to other variable, how to convert it?
Use snprintf():
char buf[128];
snprintf(buf, 128, "0x%d", a); // buf = "0x10"
Then read it back using sscanf():
unsigned int new_a;
if (1 == sscanf(buf, "0x%X", &new_a))
{
}
If your attempt is to reinterpret a decimal as hex, the problem means re-evaluating the polynomial A = a*10^n + b*10^(n-1) + ... + c to B=a*16^n + b*16^(n-1) + ... + c as in
1 1 2 3 = 1*1000 + 1 * 100 + 2 * 10 + 3
(0x) 1 1 2 3 = 1*4096 + 1 * 256 + 2 * 16 + 3 (=4387 dec)
Find the coefficients with repeated modulo and divide by 10, and add the results multiplied with the proper power of 16. (implements with shifting).
This is a question of representation. You can easily represent your decimal value as hex by
print("0x%x", a);
Which will print out 0xa in your particular case. For C it is insignificant if you have 0xa or 10 or 012.
Today I was just playing around for basic conversions from one base to another. I goggled some code for converting from hex to octal, and I noticed that it mostly uses intermediate conversion to either decimal or binary and then back to octal.Is it possible write my own function for converting hex string to octal string without using any intermediate conversion.Also I do not want to use inbuilt printf option like %x or %o. Thanks for your inputs.
Of course it is possible. A number is a number no matter what numeric system it is in. The only problem is that people are used to decimal and that is why they understand it better. You may convert from any base to any other.
EDIT: more info on how to perform the conversion.
First note that 3 hexadecimal digits map to exactly 4 octal digits. So having the number of hexadecimal digits you may find the number of octal digits easily:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int get_val(char hex_digit) {
if (hex_digit >= '0' && hex_digit <= '9') {
return hex_digit - '0';
} else {
return hex_digit - 'A' + 10;
}
}
void convert_to_oct(const char* hex, char** res) {
int hex_len = strlen(hex);
int oct_len = (hex_len/3) * 4;
int i;
// One hex digit left that is 4 bits or 2 oct digits.
if (hex_len%3 == 1) {
oct_len += 2;
} else if (hex_len%3 == 2) { // 2 hex digits map to 3 oct digits
oct_len += 3;
}
(*res) = malloc((oct_len+1) * sizeof(char));
(*res)[oct_len] = 0; // don't forget the terminating char.
int oct_index = oct_len - 1; // position we are changing in the oct representation.
for (i = hex_len - 1; i - 3 >= 0; i -= 3) {
(*res)[oct_index] = get_val(hex[i]) % 8 + '0';
(*res)[oct_index - 1] = (get_val(hex[i])/8+ (get_val(hex[i-1])%4) * 2) + '0';
(*res)[oct_index - 2] = get_val(hex[i-1])/4 + (get_val(hex[i-2])%2)*4 + '0';
(*res)[oct_index - 3] = get_val(hex[i-2])/2 + '0';
oct_index -= 4;
}
// if hex_len is not divisible by 4 we have to take care of the extra digits:
if (hex_len%3 == 1) {
(*res)[oct_index] = get_val(hex[0])%8 + '0';
(*res)[oct_index - 1] = get_val(hex[0])/8 + '0';
} else if (hex_len%3 == 2) {
(*res)[oct_index] = get_val(hex[1])%8 + '0';
(*res)[oct_index - 1] = get_val(hex[1])/8 + (get_val(hex[0])%4)*4 + '0';
(*res)[oct_index - 2] = get_val(hex[0])/4 + '0';
}
}
Also here is the example on ideone so that you can play with it: example.
It's a little tricky as you will be converting groups of 4 bits to groups of 3 bits - you'll probably want to work with 12 bits at a time, i.e. 3 hex digits to 4 octal digits and you'll then have to deal with any remaining bits separately.
E.g. to convert 5274 octal to hex:
5 2 7 4
101 010 111 100
|||/ \\// \|||
1010 1011 1100
A B C
All numbers in computer's memory are base 2. So whenever you want to actually DO something with the values (mathematical operations), you'll need them as ints, floats, etc. So it's handy or may come handy in the future to do the conversion via computable types.
I'd avoid direct string to string conversions, unless the values can be too big to fit into a numeric variable. It is surprisingly hard to write reliable converter from scratch.
(Using base 10 makes very little sense in a binary computer.)
Yes, you can do it relatively easily: four octal digits always convert to three hex digits, so you can split your string into groups of three hex digits, and process each group from the back. If you do not have enough hex digits to complete a group of three, add leading zeros.
Each hex digit gives you four bits; take the last three, and convert them to octal. Add the next four, and take three more bits to octal. Add the last group of four - now you have six bits in total, so convert them to two octal digits.
This avoids converting the entire number to a binary, although there will be a "sliding" binary window used in the process of converting the number.
Consider an example: converting 62ABC to octal. Divide into groups of three digits: 062 and ABC (note the added zero in front of 62 to make a group of three digits).
Start from the back:
C, or 1100, gets chopped into 1 and 100, making octal 4, and 1 extra bit for the next step
B, or 1011, gets chopped into 10 for the next step and 11 for this step. The 1 from the previous step is attached on the right of 11, making an octal 7
A, or 1010, gets chopped into 101 and 0. The 10 from the previous step is attached on the right, making 010, or octal 2. The 101 is octal 5, so we have 5274 so far.
2 becomes 2 and 0 for the next step;
6 becomes 4 and 01 for the next step;
0 becomes 0 and 1 (because 01 from the previous step is added).
The final result is 01425274.
Seems like a pretty straight forward task to me... You want a hex string and you want to convert it to an octal string. Let's take the ASCII hex and convert it to an int type to work with:
char hex_value[] = "0x123";
int value = strtol(hex_value,NULL,16);
It's still hex at this point, then if we want to convert from one base to another there's simple math that can be done:
123 / 8 = 24 R 3
24 / 8 = 4 R 4
4 / 8 = 0 R 4
This tells us that 12316 == 4438 so all we have to do is write that math into a basic function and put the final value back into a string:
char * convert_to_oct(int hex)
{
int ret = 0, quotient = 0, reminder = 0, dividend = hex, counter = 0, i;
char * ret_str; // returned string
while(dividend > 0){ // while we have something to divide
quotient = dividend / 0x8; // get the quotient
reminder = dividend - quotient * 0x8; // get the reminder
ret += reminder * pow(10, counter); // add the reminder (shifted)
// into our return value
counter++; // increment our shift
dividend = quotient; // get ready for the next divide operation
}
ret_str = malloc(counter); // allocate the right number of characters
sprintf(ret_str, "%d", ret); // store the result
return ret_str;
}
So this function will convert a hex (int) value into a oct string. You could call it like:
int main()
{
char hex_value[] = "0x123";
char * oct_value;
int value = strtol(hex_value,NULL,16);
// sanity check, see what the value should be before the convert
printf("value is %x, auto convert via printf gives %o\n", value, value);
oct_value = convert_to_oct(value);
printf("value is %s\n", oct_value);
All octal digits contain 3 bits of information. All Hex digits contain 12 bits of information. The least common multiple of 3 and 4 is 12.
This means you can build a simple lookup table
0000 = 0x000
0001 = 0x001
0002 = 0x002
...
0007 = 0x007
0010 = 0x008
0011 = 0x009
0012 = 0x00A
...
0017 = 0x00F
0020 = 0x010
...
5274 = 0xABC
...
Now that the idea is there, you have several choices:
Build a Map (lookup table)
The routine here would add leading zeros to the octal (string) number until it was 4 digits long, and then lookup the hexadecimal value from the table. Two variations are typing out the table statically, or populating it dynamically.
Use math to replace the lookup table
Instead of typing out each solution, you could calculate them
hexdigit1 = 01 & octaldigit8 + octaltdigit1;
hexdigit16 = 03 & octaldigit64 << 02 + 06 & octaldigit8 >> 01;
hexdigit256 = octaldigit512 << 01 + 01 & octaldigit64;
where the octaldigit1 / hexdigit16 / octaldigit8 means "octal 1's place", "hexadecimal 16's place", "octal 8's place" respectively.
Note that in either of these cases you don't "use binary" or "use decimal" but as these numbers can be represented in either of those two systems, it's not possible to avoid someone coming along behind and analyzing the correctness of the (or any) solution in decimal or binary terms.
Here is an easy function to convert your characters into javascript. valid for ALERT or for your pages up to 65536 32BITS. The concern you encounter is often for the text for codes beyond 127. The safest value is the OCTAL. ParseXX to avoid.
Thank you for your likes (^ _ ^). it's free to enjoy.
function enjoyOCTALJS (valuestr){
var arrstr = valuestr.split('');
arrstr = arrstr.map(f => (!isNaN(f.charCodeAt(0)))? (f.charCodeAt(0)>127)? '\\'+f.charCodeAt(0).toString(8):f:f);
return arrstr.join('');
}
If you just want to get the octal value of a character do this: Max = 65536 ou 0XFFFF.
var mchar = "à";
var result = mchar.charCodeAt(0).toString(8);
Or completely :
var mchar = 'à';
var result = mchar.codePointAt(0).toString(8);
If value > 65536 return UNDEFINED. You can use the function parameter to increase the value. charCodeAt(x) or codePointAt(x).
Your computer considers everything as 0 to 255.
We do not need to do big functions to convert characters, it's very easy.
CHAR TO UNICIDE
var mchar = 'à';
var result = mchar.codePointAt(0); or mchar.charCodeAt();
UNICODE TO OCTAL :
var mcode = 220;
var result = mcode.toString(8);
etc... :)
I'm trying to break down an integer with C on an 8-bit microcontroller (a PIC) into its ASCII equivalent characters.
For example:
convert 982 to '9','8','2'
Everything I've come up with so far seems pretty brute force. This is the main idea of what I'm basically doing right now:
if( (10 <= n) && (n < 100) ) {
// isolate and update the first order of magnitude
digit_0 = (n % 10);
// isolate and update the second order of magnitude
switch( n - (n % 10) ) {
case 0:
digit_1 = 0;
break;
case 10:
digit_1 = 1;
break;
...
And then I have another function to just add 0b00110000 (48decimal) to each of my digits.
I've been having trouble finding any C function to do this for me or doing it well myself.
Thanks in advance for any help!
If sprintf isn't suitable for some reason, something simple like this would work:
char digits[MAX_DIGITS];
int count = 0;
do {
digits[count++] = n % 10;
n /= 10;
} while (n > 0);
There'll be count digits, with digits[0] being the least significant.
To do it yourself you need to perform the operations which are demonstrated with the sample code below:
#include <stdio.h>
int main (void)
{
unsigned int x = 512;
int base_val = 10, digit, i = 0, n = 0;
char x_str[32], t;
printf ("\nEnter an unsigned number: ");
scanf ("%u", &x);
printf ("\nEnter base: ");
scanf ("%d", &base_val);
/* Chop the digits in reverse order and store in `x_arr`
* the interpretation of the digits are made in base value
* denoted by `base_val`
*/
while (x)
{
digit = x % base_val;
x /= base_val;
if (digit < 10)
x_str[n++] = digit + '0';
else
x_str[n++] = digit + 'A' - 10; /* handle base > 9 */
}
/* Terminate string */
x_str[n] = '\0';
/* Reverse string */
for (i=0; i<n/2; i++)
{
t = x_str[i];
x_str[i] = x_str[n-i-1];
x_str[n-i-1] = t;
}
printf ("\n%s\n", x_str);
return 0;
}
The while loop will chop out the digits from the integer in a given base and feed the digits in reverse order in an array. The inner if - else handles base more than 9, and places uppercase alphabets when a digit value is greater than 10. The for loop reverses the string and gets the chopped number into string in forward order.
You need to adjust the size of x_str array as per your max capability. Define a macro for it. Note the above code is only for unsigned integers. For signed integers you need to first check if it is below 0, then add a '-' sign in x_str and then print the magnitude ie. apply the above code with -x . This can also be done by checking the sign bit, by masking, but will make the process dependent on storage of integer.
The base_val is the base in which you want to interpret the numbers.
I answered a question like this a long time ago.
Implementing ftoa
I hope this helps. This applies to both integers and floating point numbers. The concept is simple.
Determine number of digits (for base 10, you use log base 10)
Grab the msb digit by taking the floor of (num/digit_weight)
Subtract digit * weight from number and decrease weight by 1
Do it again until number == 0 for integers or num > 0 + tolerance for fp numbers
Since the algorithm process a digit with every iteration, its O(logn) time so it's pretty reasonable.
If you are compatible with PIC16 RISC assembler than this is very simple, fast, short and efective. Here you have 16 bit unsigned 16 bit division by 10 rutine to see how to do it.
To get first lowest char of number in WREG put 16 bit unsigned number to Reg1 and Reg2 and call rutine. To get next char call rutine again and so on until Reg1 and Reg2 are 0.
RegAE res 1
RegA0 res 1
RegA1 res 1
RegA2 res 1
divR16by_c10
;{
;//Input: 16 bit unsigned number as RegA1,2 (RegA2 low byte, RegA1 High byte)
;//Division result: Reg1 and Reg2 and reminder as char in WREG
clrf RegA0
movlw 16 ;//init loop counter
movwf RegAE
lslf RegA2, f
divI16by_c10_
rlf RegA1, f
rlf RegA0, f
movlw 10
subwf RegA0, f
btfsc Carry
bra divI16by_c10_OK
addwfc RegA0, f
bcf Carry
divI16by_c10_OK
rlf RegA2, f
decfsz RegAE, f
bra divI16by_c10_
;//result= W from 0..9
addlw 0x30 ;//convert to char
return
;}
EDIT:
If you want to convert signed 16 bit value then check the 15th bit first, to determine sign number. If negative than write - sign and negate the number in RegA1,2. After that is the procedure the same a for positive number.
To negate number you can use the following asm rutine:
comf RegA2, f
comf RegA1, f
movlw 0
bsf STATUS, 0 ;//set carry flag
addwfc RegA2, f
addwfc RegA1, f