Thank you for the link. Using transform(65535, "@0") will give 0x0000FFFF. ?0xFFFF will give 65535 with width = 5. What are those 0s between x and F for? It seems that they are some sort of placeholder because ?0x00FFFF will give 65535 with width = 8.
you guessed it pretty much...8 is just the default width.
when you see hex with a default width of 6 it is usually being used as a color. Include the leading 0's (after the 0x of course) or exclude them, they won't effect (or is that affect?) the value of the hex expression.
Using TRANFORM is cryptic. Better to use functions that are more mathematically friendly. "True Basic" has the answer, and I translated it to a VFP module than can be included in your program with a simple "set procedure to hexlib"
Here it is (copyrighted by 'True Basic'):
* HEXLIB
*
* Version 1.0
* Copyright (c) 1987 by .T. BASIC, Inc.
* All rights reserved.
*
* Bit-manipulation routines
*
* All these routines work properly only for integers.
*
* Conversion functions from numbers to strings:
*
* CONVERT(n,b) converts the integer n to any base b from 2 to 16
* BIN converts n to base 2
* OCT converts n to base 8
* HEX converts n to base 16
* HEXW converts n to 4 base 16 digits, with negative numbers
* treated as two's complement (0 -> "0000", -1 -> "FFFF")
*
* Conversion function from string to number:
*
* CONVERT(s) converts the string s to a number, where s contains
* one of the standard radix marks to indicate the base
* (Unix, Pascal, MS-BASIC, 8086 or 68000 assembler formats
* -- preferred format is a trailing letter H for hex, Q
* for octal, or B for binary)
*
* The conversion functions aren't quite inverses of each other. To
* convert to hexadecimal, you would use HEX. To convert a hex string
* back to a number, if it didn't already have a radix mark (which it
* wouldn't, if it was created by HEX), you'd have to add "H", then
* use CONVERT -- e.g. n = CONVERT(h + "H").
*
*EXTERNAL
*
function convertToHex
parameters number, base
local convert,sign,digit,c,q
sign = ""
digit = 0
c = ""
number = round(number,0)
IF number < 0 then
number = -number
sign = "-"
endif
DO while .T.
do divide with number, base, q, digit
number = q
digit = digit + 1
c = substr("0123456789ABCDEF",digit,1) + c
if number = 0 then
exit && do
endif
enddo
convert = sign + c
return convert
*--------------*
function hex
parameters n
local hex
hex = convertToHex(n,16)
return hex
*--------------*
function oct
parameters n
local oct
oct = convertToHex(n,8)
return oct
*--------------*
function bin
parameters n
local bin
bin = convertToHex(n,2)
return bin
*--------------*
function hexw
parameters n
local hexw,digit,c
digit = 0
c = ""
n = round(n,0)
FOR i = 1 to 4
do divide with n, 16, n, digit
digit = digit + 1
c = substr("0123456789ABCDEF",digit,1) + c
NEXT i
hexw = c
return hexw
*--------------*
* Convert returns the value of the string as a number. The string
* representation may be in binary, octal, decimal, or hexadecimal.
* Hexadecimal is represented by a leading "&H" or "0X", or by a
* leading or trailing "H", "X", or "$". Octal is represented by a
* leading "0" or "&", or by a leading or trailing "O" or "Q". Binary
* is represented by a leading or trailing "B". Any of these may be
* in upper or lower case. If none of these is present, the string is
* assumed to be decimal. If there is a sign ("+" or "-"), it must
* come first.
*
* If an illegal digit for the base is encountered, this routine
* causes an exception (4001, illegal VAL argument).
*
function convert
parameters s
local convert,base,digits,sign,c,i,d,v
*
s = upper(s)
base = 10
sign = 1
*
c = left(s,1)
IF at(c,"-+") > 0 then
IF c = "-" then
sign = -1
endif
s = stuff(s,1,1,"")
c = left(s,1)
endif
*
IF at(c,"0&") > 0 then
s = stuff(s,1,1,"")
base = 8
c = left(s,1)
endif
*
i = 1
d = at(c,"$HXOQ")
IF d = 0 then
i = len(s)
d = at(substr(s,i,1),"$HXOQB")
endif
IF d > 0 then
base = 2*val(substr("888441",d,1))
s = stuff(s,i,1,"")
endif
*
digits = left("0123456789ABCDEF",base)
v = 0
*
FOR i = 1 to len(s)
d = at(substr(s,i,1),digits) - 1
IF d < 0 then
=ask("String "+s+" is not a proper number")
RETURN 0
endif
v = v*base + d
NEXT i
*
convert = sign * v
*
return convert
*--------------*
* Logical functions:
*
* AND(a,b) returns the bitwise logical and of a + b
* OR(a,b) returns the logical or
* XOR(a,b) returns the logical exclusive or
*
function and
parameters a, b
local and
m = 1
b = int(b)
DO while .T.
do divide with a, 2, a, aa
do divide with b, 2, b, bb
r = r + m*aa*bb && multiply is like AND
m = 2*m && m = current bit position
IF b = -1 then
r = r + m*a && if negative, treat as two's complement
exit && do
endif
if b = 0 then && loop until all bits of B are used
exit && do
endif
enddo
and = r
return and
*--------------*
function or
parameters a, b
local or
or = a + b - and(a, b)
return or
*--------------*
function xor
parameters a, b
local xor
xor = a + b - 2*and(a, b)
return xor
*--------------
procedure divide
lparameters x,y,q,r
local sign,sn
if y = 0 then
store 0 to q,r
else
q = int(x/y)
sn = sign(x)*sign
r = sn*mod(abs(x),abs)
endif
endproc
*--------------
How is using all that code less cryptic than Transform()? I expect that using those routines in a situation where a large number of conversions were necessary, would greatly slow up the process. I think these routines are more suited to a FoxBase app - the same generation of software as 'True Basic' - rather than in a VFP app.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.