Here are a suite of hexadecimal to/from decimal conversion routines. These have been used in an application, so there should not be any errors, I trust.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | proc dec2hex {value} {
# Creates a 32 bit hex number from a signed decimal number
# Replace all non-decimal characters
regsub -all {[^0-9\.\-]} $value {} newtemp
set value [string trim $newtemp]
if {$value < 2147483647 && $value > -2147483648} {
set tempvalue [format "%#010X" [expr $value]]
return [string range $tempvalue 2 9]
} elseif {$value < -2147483647} {
return "80000000"
} else {
return "7FFFFFFF"
}
}
proc dec2hex16 {value} {
# Creates a 16 bit hex number from a signed decimal number
# Replace all non-decimal characters
regsub -all {[^0-9\.\-]} $value {} newtemp
set value [string trim $newtemp]
if {$value < 32767 && $value > -32768} {
set tempvalue [format "%#010X" [expr $value]]
return [string range $tempvalue 6 9]
} elseif {$value < -32767} {
return "8000"
} else {
return "7FFF"
}
}
proc hex2dec {hexvalue} {
# Creates an unsigned decimal number from a 63 bit hex value
set total "0000000000000000"
set mask "7FFFFFFF"
# replace from the end
set start 15
# Replace all non-hex characters
regsub -all {[^0-9A-F\.\-]} $hexvalue {} newtemp
set hexvalue [string trim $newtemp]
# Go from the end to the start
for {set i [expr [string length $hexvalue] -1]} {$i > -1} {incr i -1} {
# Get the next hex digit
set j [string toupper [string index $hexvalue $i]]
# Add it to the big string
set total [string replace $total $start $start $j]
incr start -1
}
set nlower [string range $total 8 15]
set nupper [string range $total 0 7]
# clear top bit to keep as positive. Also adds in "0x" at the start
set nupper "[format "%#010X" [expr "0x$nupper" & "0x$mask"]]"
# Now set to 64 bit - use a string to represent the number to avoid integer size limits
set total "[expr [format "%u" "0x$nlower"] + (4294967295 * [format "%u" "$nupper"])]"
return $total
}
proc uhex2dec32 {hexvalue} {
# Creates an unsigned decimal number from a 32 bit hex value
# Replace all non-hex characters
regsub -all {[^0-9A-F\.\-]} $hexvalue {} newtemp
set hexvalue [string trim $newtemp]
#trim to 8 characters
set hexvalue [string range $hexvalue [expr [string length $hexvalue]
- 8] [expr [string length $hexvalue] - 1]]
return [format "%#u" [expr "0x$hexvalue"]] } proc shex2dec32 {hexvalue} {
# Creates a signed decimal number from a 32 bit hex value
# Replace all non-hex characters
regsub -all {[^0-9A-F\.\-]} $hexvalue {} newtemp
set hexvalue [string trim $newtemp]
#trim to 8 characters
set hexvalue [string range $hexvalue [expr [string length $hexvalue]
- 8] [expr [string length $hexvalue] - 1]]
return [format "%#i" [expr "0x$hexvalue"]] }
proc uhex2dec16 {hexvalue} {
# Creates an unsigned decimal number from a 16 bit hex value
# Replace all non-hex characters
regsub -all {[^0-9A-F\.\-]} $hexvalue {} newtemp
set hexvalue [string trim $newtemp]
#trim to 4 characters
set hexvalue [string range $hexvalue [expr [string length $hexvalue]
- 4] [expr [string length $hexvalue] - 1]]
set value [format "%#u" [expr "0x$hexvalue"]]
return $value
}
proc shex2dec16 {hexvalue} {
# Creates an unsigned decimal number from a 16 bit hex value
# Replace all non-hex characters
regsub -all {[^0-9A-F\.\-]} $hexvalue {} newtemp
set hexvalue [string trim $newtemp]
#trim to 4 characters
set hexvalue [string range $hexvalue [expr [string length $hexvalue]
- 4] [expr [string length $hexvalue] - 1]]
# Convert to signed number
set value [format "%#u" [expr "0x$hexvalue"]]
if {$value > 32767} {
set value [expr ($value - 65536)]
}
return $value
}
|
These routines provide the following functions: Decimal to hex - 32 bit. Decimal to hex - 16 bit. Hex to decimal - unsigned 63 bit on 32bit Windows Tcl install. Hex to decimal - unsigned 32 bit. Hex to decimal - unsigned 16 bit. Hex to decimal - signed 16 bit.
dec2hex. proc dec2hex {dec_num} { return [format %04X $dec_num] }