Alaska Software Inc. - Hex To Decimal Conversion
Username: Password:
AuthorTopic: Hex To Decimal Conversion
Jonathan LeemingHex 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 LeemingRe: 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 LeemingRe: 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 LeemingRe: 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 LeeRe: 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
>