Author | Topic: Hex To Decimal Conversion | |
---|---|---|
Jonathan Leeming | Hex To Decimal Conversion on Wed, 18 Nov 2020 10:11:47 -0700 Hi, I'm sure I'm missing something as I am looking for a Hex to Decimal conversion function but I don't see one within Xbase++. I have written the following which works OK but a built in function would be faster... FUNCTION Hex2Decimal(cHex) LOCAL aHex := {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"},; cH := "0123456789ABCDEF",; nLen := LEN(cHex),; nPnt,; nDec := 0 cHex := UPPER(cHex) FOR nPnt := 1 TO nLen nDec += (AT(cHex[nPnt],cH)-1) * 16**(nLen-nPnt) *nDec += (ASCAN(aHex,cHex[nPnt])-1) * 16**(nLen-nPnt) NEXT nPnt RETURN INT(nDec) In the above I first used aHex with ASCAN() and then changed to cH with AT(). 1 Million calls with Hex2Decimal("000000022667aa02") took around 10 seconds using the aHex array and around 6 seconds if I use cH with AT(). The only thing I have found that looked promising was CtoN() in XbToolsIII which seems like a simple enough function to use but when I run CtoN("000000022667AA02",16) it returns 0. Further testing found that the CToN() function appears to have a limitation that the hex string to be converted can not be more than 8 characters. Thanks... Jonathan jonathan.leeming@familycentre.org Edmonton, Alberta, Canada | |
Edgar Borger | Re: Hex To Decimal Conversion on Wed, 18 Nov 2020 17:40:43 -0300 Hi Jonathan, similar to yours... FUNCTION Hex2Dec( cHexNum ) LOCAL n, nDec := 0, nHexPower := 1 cHexNum := IIF(Valtype(cHexNum)='C',cHexNum,'') cHexNum := ALLTRIM( cHexNum ) FOR n := Len( cHexNum ) TO 1 STEP -1 nDec += nHexPower * ( At( SubStr( Upper(cHexNum), n, 1 ), "0123456789ABCDEF" ) - 1 ) nHexPower *= 16 NEXT RETURN nDec Em 18/11/2020 14:11, Jonathan Leeming escreveu: > Hi, > > I'm sure I'm missing something as I am looking for a Hex to Decimal > conversion function but I don't see one within Xbase++. > > I have written the following which works OK but a built in function > would be faster... > > FUNCTION Hex2Decimal(cHex) > LOCAL aHex := > {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"},; > cH := "0123456789ABCDEF",; > nLen := LEN(cHex),; > nPnt,; > nDec := 0 > > cHex := UPPER(cHex) > > FOR nPnt := 1 TO nLen > nDec += (AT(cHex[nPnt],cH)-1) * 16**(nLen-nPnt) > *nDec += (ASCAN(aHex,cHex[nPnt])-1) * 16**(nLen-nPnt) > NEXT nPnt > > RETURN INT(nDec) > > In the above I first used aHex with ASCAN() and then changed to cH with > AT(). 1 Million calls with Hex2Decimal("000000022667aa02") took around > 10 seconds using the aHex array and around 6 seconds if I use cH with AT(). > > The only thing I have found that looked promising was CtoN() in > XbToolsIII which seems like a simple enough function to use but when I > run CtoN("000000022667AA02",16) it returns 0. Further testing found > that the CToN() function appears to have a limitation that the hex > string to be converted can not be more than 8 characters. > > Thanks... Jonathan > | |
Edgar Borger | Re: Hex To Decimal Conversion on Wed, 18 Nov 2020 18:11:52 -0300 this took 4.36 seconds: Function Dec2Hex( hex ) LOCAL i, dec := 0, msk := '123456789ABCDEF' for i = 1 to len(hex) dec := (dec * 16) + at( substr(hex,i,1), msk) next Return(dec) Em 18/11/2020 14:11, Jonathan Leeming escreveu: > Hi, > > I'm sure I'm missing something as I am looking for a Hex to Decimal > conversion function but I don't see one within Xbase++. > > I have written the following which works OK but a built in function > would be faster... > > FUNCTION Hex2Decimal(cHex) > LOCAL aHex := > {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"},; > cH := "0123456789ABCDEF",; > nLen := LEN(cHex),; > nPnt,; > nDec := 0 > > cHex := UPPER(cHex) > > FOR nPnt := 1 TO nLen > nDec += (AT(cHex[nPnt],cH)-1) * 16**(nLen-nPnt) > *nDec += (ASCAN(aHex,cHex[nPnt])-1) * 16**(nLen-nPnt) > NEXT nPnt > > RETURN INT(nDec) > > In the above I first used aHex with ASCAN() and then changed to cH with > AT(). 1 Million calls with Hex2Decimal("000000022667aa02") took around > 10 seconds using the aHex array and around 6 seconds if I use cH with AT(). > > The only thing I have found that looked promising was CtoN() in > XbToolsIII which seems like a simple enough function to use but when I > run CtoN("000000022667AA02",16) it returns 0. Further testing found > that the CToN() function appears to have a limitation that the hex > string to be converted can not be more than 8 characters. > > Thanks... Jonathan > | |
Jonathan Leeming | Re: Hex To Decimal Conversion on Fri, 20 Nov 2020 09:49:13 -0700 On 11/18/2020 2:11 PM, Edgar Borger wrote: > this took 4.36 seconds: > > Function Dec2Hex( hex ) > LOCAL i, dec := 0, msk := '123456789ABCDEF' > > for i = 1 to len(hex) > dec := (dec * 16) + at( substr(hex,i,1), msk) > next > > Return(dec) > > > Em 18/11/2020 14:11, Jonathan Leeming escreveu: >> Hi, >> >> I'm sure I'm missing something as I am looking for a Hex to Decimal >> conversion function but I don't see one within Xbase++. >> >> I have written the following which works OK but a built in function >> would be faster... >> >> FUNCTION Hex2Decimal(cHex) >> LOCAL aHex := >> {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"},; >> cH := "0123456789ABCDEF",; >> nLen := LEN(cHex),; >> nPnt,; >> nDec := 0 >> >> cHex := UPPER(cHex) >> >> FOR nPnt := 1 TO nLen >> nDec += (AT(cHex[nPnt],cH)-1) * 16**(nLen-nPnt) >> *nDec += (ASCAN(aHex,cHex[nPnt])-1) * 16**(nLen-nPnt) >> NEXT nPnt >> >> RETURN INT(nDec) >> >> In the above I first used aHex with ASCAN() and then changed to cH >> with AT(). 1 Million calls with Hex2Decimal("000000022667aa02") took >> around 10 seconds using the aHex array and around 6 seconds if I use >> cH with AT(). >> >> The only thing I have found that looked promising was CtoN() in >> XbToolsIII which seems like a simple enough function to use but when I >> run CtoN("000000022667AA02",16) it returns 0. Further testing found >> that the CToN() function appears to have a limitation that the hex >> string to be converted can not be more than 8 characters. >> >> Thanks... Jonathan >> Hi Edgar, I took your code and did some timings and after I took the cHex := UPPER(cHex) out of my code found that for 1 million cycles that our functions were about .1 seconds apart. I then "stole" and idea from yours so that instead of having my cH := "0123456789ABCDEF" and subtracting 1 from the AT() results each time I set cH := "123456789ABCDEF" which resulted in an additional .3 seconds off. I also played around with the changing the FOR / NEXT loop to a DO WHILE, using SUBSTR() instead of an index with cHex, and also using a new variable that was decremented on within the FOR/NEXT loop instead of doing nLen-nPnt... LOCAL nOff := nLen & then --nOff. OK... It's a cold winter day here in Edmonton and I had a bit of time on my hands... and I'm procrastinating about going out to shovel the snow! If anyone cares the fastest code I came up with is... FUNCTION Hex2Decimal(cHex) LOCAL cH := "123456789ABCDEF",; nLen := LEN(cHex),; nPnt,; nDec := 0 cHex := UPPER(cHex) in case cHex contains "abcdef" FOR nPnt := 1 TO nLen nDec += (AT(cHex[nPnt],cH)) * 16**(nLen-nPnt) NEXT nPnt RETURN INT(nDec) without int returns decimal_value.00 Thanks for everyone's ideas & input... stay safe... Jonathan jonathan.leeming@familycentre.org Edmonton, Alberta, Canada | |
Andreas Gehrs-Pahl | Re: Hex To Decimal Conversion on Fri, 20 Nov 2020 12:14:08 -0500 Jonathan, >If anyone cares the fastest code I came up with is... This code is about 25% faster than yours: Function Hex2Dec(cHexString) LOCAL cHex := alltrim(upper(cHexString)) LOCAL nLen := len(cHex) LOCAL nPos := 0 LOCAL nDec := 0 LOCAL nPwr := 1 for nPos := nLen to 1 Step -1 nDec += (At(cHex[nPos], "123456789ABCDEF")) * nPwr nPwr *= 16 next return (nDec) Hope that helps, Andreas Andreas Gehrs-Pahl Absolute Software, LLC phone: (989) 723-9927 email: Andreas@AbsoluteSoftwareLLC.com web: http://www.AbsoluteSoftwareLLC.com [L]: https://www.LinkedIn.com/in/AndreasGehrsPahl [F]: https://www.FaceBook.com/AbsoluteSoftwareLLC | |
Jonathan Leeming | Re: Hex To Decimal Conversion on Fri, 20 Nov 2020 11:55:52 -0700 On 11/20/2020 10:14 AM, Andreas Gehrs-Pahl wrote: > Jonathan, > >> If anyone cares the fastest code I came up with is... > > This code is about 25% faster than yours: > > Function Hex2Dec(cHexString) > LOCAL cHex := alltrim(upper(cHexString)) > LOCAL nLen := len(cHex) > LOCAL nPos := 0 > LOCAL nDec := 0 > LOCAL nPwr := 1 > for nPos := nLen to 1 Step -1 > nDec += (At(cHex[nPos], "123456789ABCDEF")) * nPwr > nPwr *= 16 > next > return (nDec) > > Hope that helps, > > Andreas > Hi Andreas... and thanks. It is faster however in taking your code and assigning the "123456789ABCDEF" to a local variable I found that it speeds up even a bit more. I created a FOR/NEXT loop that cycled through 20 iterations and within this compared the two versions at 1 million iterations each which resulted in an average time of 3.554 seconds for your version and 3.394 seconds using LOCAL cH := "123456789ABCDEF". As far as your solution helping... I still have not shoveled the walks!!! Thanks for the fun exercise... and education Cheers... Jonathan jonathan.leeming@familycentre.org Edmonton, Alberta, Canada | |
Andreas Gehrs-Pahl | Re: Hex To Decimal Conversion on Sat, 21 Nov 2020 15:15:51 -0500 Jonathan, >>This code is about 25% faster than yours: Actually, after some more testing, it seems to be actually about 30-35% faster than using the exponential "**" operator. >It is faster however in taking your code and assigning the >"123456789ABCDEF" to a local variable I found that it speeds up even a >bit more. I created a FOR/NEXT loop that cycled through 20 iterations >and within this compared the two versions at 1 million iterations each >which resulted in an average time of 3.554 seconds for your version and >3.394 seconds using LOCAL cH := "123456789ABCDEF". I don't see that here. But keep in mind that the order in which you run your code can have an affect on those kind of timings. Doing my tests, I have observed that whichever function you run/test first will be slightly faster on average, probably because of resource usage of the application. Also, I seem to have a slightly faster computer, as both functions run between 1.9 and 2.0 seconds for a million iterations, with the difference between two consecutive runs on average in the 0.025 second range, with the second one being the slower one (independent of which one is run first). >As far as your solution helping... I still have not shoveled the walks!!! So, how is your snow doing now? Its sunny (but cold) here, without any snow, so far. Andreas Andreas Gehrs-Pahl Absolute Software, LLC phone: (989) 723-9927 email: Andreas@AbsoluteSoftwareLLC.com web: http://www.AbsoluteSoftwareLLC.com [L]: https://www.LinkedIn.com/in/AndreasGehrsPahl [F]: https://www.FaceBook.com/AbsoluteSoftwareLLC | |
Jonathan Leeming | Re: Hex To Decimal Conversion on Sun, 22 Nov 2020 15:08:02 -0700 On 11/21/2020 1:15 PM, Andreas Gehrs-Pahl wrote: > Jonathan, > >>> This code is about 25% faster than yours: > > Actually, after some more testing, it seems to be actually about 30-35% > faster than using the exponential "**" operator. > >> It is faster however in taking your code and assigning the >> "123456789ABCDEF" to a local variable I found that it speeds up even a >> bit more. I created a FOR/NEXT loop that cycled through 20 iterations >> and within this compared the two versions at 1 million iterations each >> which resulted in an average time of 3.554 seconds for your version and >> 3.394 seconds using LOCAL cH := "123456789ABCDEF". > > I don't see that here. But keep in mind that the order in which you run your > code can have an affect on those kind of timings. Doing my tests, I have > observed that whichever function you run/test first will be slightly faster > on average, probably because of resource usage of the application. Also, I > seem to have a slightly faster computer, as both functions run between 1.9 > and 2.0 seconds for a million iterations, with the difference between two > consecutive runs on average in the 0.025 second range, with the second one > being the slower one (independent of which one is run first). > >> As far as your solution helping... I still have not shoveled the walks!!! > > So, how is your snow doing now? Its sunny (but cold) here, without any snow, > so far. > > Andreas > Faster computer... Quit bragging Actually quite a bit faster if you are sub 2 seconds but I still like my X1 Carbon... a couple of generations old but fast enough for me... light too (2.5 lbs)! Thanks for your concern about our snow, but don't worry as it is doing well. Walks got shoveled (actually snow blown) and we have a few days forecast below freezing and then day time highs just above freezing. Stays dark later in the morning and sooner in the evening (sunrise 8:15 and sunset 4:30)...Dec 21 sunrise will be 8:49am with sunset at 4:15pm... Think I'll just stay in bed! Stay safe... and warm!!! Jonathan jonathan.leeming@familycentre.org Edmonton, Alberta, Canada | |
Jim Lee | Re: Hex To Decimal Conversion on Thu, 19 Nov 2020 19:25:15 +0100 hi, here NanForum Function FUNCTION FT_HEX2DEC( cHexNum ) local n, nDec := 0, nHexPower := 1 for n := len( cHexNum ) to 1 step -1 nDec += ( at( subs( upper(cHexNum), n, 1 ), HEXTABLE ) - 1 ) * nHexPower nHexPower *= 16 next RETURN nDec | |
Andreas Gehrs-Pahl | Re: Hex To Decimal Conversion on Thu, 19 Nov 2020 17:06:34 -0500 Jim, >here NanForum Function This is pretty much exactly the same function as Jonathan and also Edgar have already posted, just that yours does the len() and upper() functions inside the loop, rather than before it, and that your "HEXTABLE" variable (or define constant) isn't defined anywhere. Also, the "subs()" function should actually be "substr()" in Xbase++, but using "cHexNum[nPos]" is actually quicker than using "substr(upper(cHexNum), nPos, 1)", at least in Xbase++. Jonathan, Your functions, as well as Edgar's (and if fixed) Jim's function, all work fine and are the only way that I know of that works with hex values larger than 64-bits or 8 hex digits in Xbase++. But if you have only 64-bits (or 8 bytes / DWORD) values (or smaller), you could use the OT4Xb function "nHex2Dw()", which is by far the fastest. I have attached a small demo program, which shows that the third method, using a separate variable for the nPower - using twice "*" rather than once "**" - and starting at the end of the hex string (rather than at the front), is the quickest option. Hope that helps, Andreas Andreas Gehrs-Pahl Absolute Software, LLC phone: (989) 723-9927 email: Andreas@AbsoluteSoftwareLLC.com web: http://www.AbsoluteSoftwareLLC.com [L]: https://www.LinkedIn.com/in/AndreasGehrsPahl [F]: https://www.FaceBook.com/AbsoluteSoftwareLLC Dec_to_Hex.prg | |
Andreas Gehrs-Pahl | Re: Hex To Decimal Conversion on Thu, 19 Nov 2020 17:19:38 -0500 Jonathan, I wrote: >Your functions, as well as Edgar's (and if fixed) Jim's function, all work >fine and are the only way that I know of that works with hex values larger >than 64-bits or 8 hex digits in Xbase++. But if you have only 64-bits (or 8 >bytes / DWORD) values (or smaller), you could use the OT4Xb function >"nHex2Dw()", which is by far the fastest. Actually, "nHex2Dw()" is for 32-bits (4 bytes) 8 hex digits DWORD values. If you need values larger than those, like 64-bits (8 bytes) 16 hex digits QWORD values, you need to use one of those other functions. And OT4Xb has also separate functions for 16-bits (2 bytes) 4 hex digits WORD values: "nHex2W()" and for 8-bits (1 byte) 2 hex digits BYTE values: "nHex2Byte()". Sorry for the confusions. Andreas Andreas Gehrs-Pahl Absolute Software, LLC phone: (989) 723-9927 email: Andreas@AbsoluteSoftwareLLC.com web: http://www.AbsoluteSoftwareLLC.com [L]: https://www.LinkedIn.com/in/AndreasGehrsPahl [F]: https://www.FaceBook.com/AbsoluteSoftwareLLC | |
Carlos A Beling | Re: Hex To Decimal Conversion on Fri, 20 Nov 2020 14:52:34 -0300 Hi: good day. How can the negative numbers being converted and reversed? Fraternally Beling On 18/11/2020 14:11, Jonathan Leeming wrote: > Hi, > > I'm sure I'm missing something as I am looking for a Hex to Decimal > conversion function but I don't see one within Xbase++. > > I have written the following which works OK but a built in function > would be faster... > > FUNCTION Hex2Decimal(cHex) > LOCAL aHex := > {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"},; > cH := "0123456789ABCDEF",; > nLen := LEN(cHex),; > nPnt,; > nDec := 0 > > cHex := UPPER(cHex) > > FOR nPnt := 1 TO nLen > nDec += (AT(cHex[nPnt],cH)-1) * 16**(nLen-nPnt) > *nDec += (ASCAN(aHex,cHex[nPnt])-1) * 16**(nLen-nPnt) > NEXT nPnt > > RETURN INT(nDec) > > In the above I first used aHex with ASCAN() and then changed to cH with > AT(). 1 Million calls with Hex2Decimal("000000022667aa02") took around > 10 seconds using the aHex array and around 6 seconds if I use cH with AT(). > > The only thing I have found that looked promising was CtoN() in > XbToolsIII which seems like a simple enough function to use but when I > run CtoN("000000022667AA02",16) it returns 0. Further testing found > that the CToN() function appears to have a limitation that the hex > string to be converted can not be more than 8 characters. > > Thanks... Jonathan > |