Code archives/Algorithms/HexToDec

This code has been declared by its author to be Public Domain code.

Download source code

HexToDec by impixi2007
Evaluate a hex string to a decimal value.
See code below...

Comments

impixi2007
Damn, what a pain! A simple principle that should have taken me half an hour to implement took me about eight hours, partly because of data type precision issues and partly due to numerous fiddly bits and pieces.

Rem

	HexToDec: Evaluate a hex string into a decimal number.

	Untested but should work on non-Windows platforms.
	
	Currently only evaluates whole numbers (ie non-fractional numbers).

	Tested with BlitzMax V1.24

EndRem

SuperStrict

Graphics 800, 600

SeedRnd MilliSecs()

test

While Not KeyHit(KEY_ESCAPE)
	
	If MouseHit(1) Or MouseHit(2)
	
		test	
	
	EndIf

Wend

End


'********* TEST *************************************************


Function test()

	Cls
	
	DrawText "Click mouse button to generate some random values.", 10, 5
	DrawText "(If the evaluation is correct then the result should equal the source.)", 10, 30

	For Local n:Byte = 1 To 10

		Local source:Long = Rand(0, 10000)
		Local hexstr:String = Hex(source)
		Local result:Long = HexToDec(hexstr)
	
		DrawText "Source: " + source + ", Hex: " + hexstr + ", Result: " + result, 10, ((n + 2) * 30)

	Next

	Flip

EndFunction


'********** HexToDec FUNCTION *******************************************
'Simply cut and paste the hexToDec function into your program and use as required.

Function HexToDec:Long(s:String Var)

	's - string to evalute. Non-hex characters will be ignored.
	'returns a long integer
	
	Global hex_chars:String[] = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "a", "b", "c", "d", "e", "f"]

	Local val:Double 
	
	'Strip non-hex characters
	Local ts:String = ""
	For Local i:Int = 0 To (s.length - 1)
		Local ch:String = Chr(s[i])
		Local found:Int = False
		For Local i2:Int = 0 To hex_chars.length - 1
			If ch = hex_chars[i2] 
				found = True
				Exit
			EndIf
		Next	
		If found Then ts :+ ch 
	Next 
		
	'Remove leading zeros
	Local count:Int = 0
	For Local i:Int = 0 To (s.length - 1)
		If Chr(ts[i]) <> "0" Then Exit Else count :+ 1
	Next
	ts = ts[count..s.length]

	'Evaluate every character in the string
	For Local i:Int = 0 To ts.length - 1
	
		Local ch:String = Chr(ts[i])
		
		Local chval:Byte
	
		Select ch
			Case "A", "a"
				chval = 10
			Case "B", "b"
				chval = 11		
			Case "C", "c"
				chval = 12
			Case "D", "d"
				chval = 13	
			Case "E", "e"
				chval = 14		
			Case "F", "f"
				chval = 15
			Default 
				chval = ch.toInt()
		EndSelect
	
		val :+ (chval * (16 ^ (ts.length - 1.0 - i)))
	Next

	If (ts.length > 1) Then val :+ 1

	'Overcome precision issues
	Local remainder:Double = (val Mod 1)
	If remainder = 0.0
		If Long(val) > 15 Then Return Long(val - 1) Else Return Long(val)
	Else 
		Return Long(val)
	EndIf

EndFunction



klepto22007
Why not simply using this?

Print Int($ABCD)



impixi2007
LOL! If only I knew of it before... Ah well. It was a good programming exercise...

Print Int("$ABCD")



BlitzProg2007
Edit : oops i was wondering why it didn't work for me but i was trying on B+.


Code Archives Forum