We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Using the C51 tools, I am trying to convert a long Hex number, entered as an ASCII string, to its decimal equivalent. For example: the string could be: "ABCDEF1234565" And I would need to convert to the string: "188900967593046" The problem I have found is that since there does not seem to be a true 'double' variable type, I cannot do a direct conversion of the number. Which would consist of converting the ASCII hex to a variable, and then printing it out as decimal. I have tried several methods, but cannot get past needing variable storage larger than 32bits. Any suggestions on how to achieve this would be greatly appreciated... Thanks! David Marten
C51 does not have built-in features for dealing with very large numbers and all programming languages will have a limit at some point. You seem to need to be able to deal with 64-bit numbers - perhaps larger. Your best bet is probably to convert your ASCII string value to an internal binary representation and then convert that binary back to decimal. You may consider storing your binary representation as an array of 64 bytes - one for each bit. In answer to another question, I produced a binary to decimal conversion function for 38-bit values. The method is easily adaptable to larger numbers of bits. The method is not efficient, but it is easy to implement. See: http://www.keil.com/forum/msgpage.asp?MsgID=3389 Have fun.
In addition to Graham's 38-bit version, there is a 64-bit version posted at: http://www.keil.com/forum/msgpage.asp?MsgID=4052
On Nov. 11, 2001, I sent in a C51 V6.20 bug report via e-mail to support.us@keil.com. I never received a response, so assumed Keil's policy was to silently introduce the bug fix in a subsequent update. After downloading V6.21, I see that the bug is still present. Now I'm wondering whether my e-mailed bug report was ever acted upon, so I'm going to try the forum as the means to report the bug.<br> <br> I have a section of code with pointer incrementation that compiles and executes correctly when the pointer is defined as a generic pointer or as an xdata pointer, or when the optimization setting is reduced from the default OT(8,SPEED) to OT(7,SPEED). However, when the pointer is defined as a data or idata pointer, the compiler does not emit code to increment the pointer with default optimization.<br> <br> I have provided example code demonstrating the problem. The specific statement is line 50 below.<br> <br>
unsigned char idata u64[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; unsigned char idata s[21]; void U64ToStr( char idata *s, unsigned char idata *binP, unsigned char n ) { unsigned char bcd; unsigned char idata *bcdP; unsigned char bitMsk = 0x80; unsigned char carry; unsigned char i; /* Zero the target buffer (NUL-terminating the string). */ for (bcdP = s, i = n + 1; i != 0; *bcdP++ = 0, i--) ; /* Convert 64 bits of binary to unpacked BCD. For each bit, starting * with the MSBit, BCD = (BCD * 2) + bit. */ for (i = 64; i != 0; i--) { carry = (*binP & bitMsk) ? 1 : 0; for (bcdP = s + n; bcdP != s; /* Iter in body */) { bcd = *--bcdP * 2; bcd += carry; if (bcd < 10) carry = 0; else { carry = 1; bcd -= 10; } *bcdP = bcd; } if ((bitMsk >>= 1) == 0) { bitMsk = 0x80; binP++; } } /* ASCII'fy BCD. */ for (i = n; i != 0; i--) *bcdP++ += '0'; /* <-- C51 BUG: bcdP doesn't increment for (i)data */ } void main( void ) { for (;;) U64ToStr( s, u64, 6 ); }
Obviously, the forum messed up my last message. Here is what I ment. Seems like you can't avoid using 64-bit long numbers, as Graham said. To see some ways of converting binary into decimal, follow the link: http://www.public.asu.edu/~vidar/bcdchange.html Regards, Mike
Oh, and by the way, the bug I was referring to in that post has been fixed with C51 V6.22. --Dan Henry