Page 1 of 1
GUID as number
Posted: Wed Jan 24, 2024 5:10 am
by adale
I am looking for a purely numeric unique ID.
Reviewing the stored *GUID value, I see it as alphanumeric (32 length), as hex?
Within VL is there a "hex to decimal" BIF or Intrinsic, of some other means to convert this hex string to a numeric value?
I could not find much info on the *GUIDSEQUENTIAL system value either?
Or is the better option to use the *AUTONUM system variable?
Re: GUID as number
Posted: Wed Jan 24, 2024 6:06 am
by appbuilder
Re: GUID as number
Posted: Wed Jan 24, 2024 9:50 am
by BrendanB
Arlyn,
if you want to convert a HEX value to a numeric, you can easily do it with some RDMLX code:
with these 2 routines available (i would put them in a #Utils RP) so that you can call like:
define #myNumericGUID reffld(#XLib_INT64)
#myNumericGUID := #Utils.ConvertHextToInteger(*GUID)
Code: Select all
Mthroutine Name(ConvertHexToInteger) Access(*PRIVATE)
Define_Map For(*INPUT) Class(#PRIM_DC.UnicodeString) Name(#Hex)
Define_Map For(*RESULT) Class(#XLib_INT64) Name(#Result)
Define Field(#i) Type(*INT)
Begin_Loop Using(#i) To(#Hex.CurChars)
#Result += #Com_self.GetHexCharacterValue( #Hex.UpperCase.Substring( #i 1 ) ) * (16).AsFloat.Power( (#Hex.CurChars - #i) )
End_Loop
Endroutine
Mthroutine Name(GetHexCharacterValue) Access(*PRIVATE)
Define_Map For(*INPUT) Class(#PRIM_DC.UnicodeString) Name(#HexCharacter)
Define_Map For(*RESULT) Class(#Prim_nmbr) Name(#Result)
If (#HexCharacter.IsNumber)
#Result := #HexCharacter.AsNumber
Else
Case Of_Field(#HexCharacter)
When (= "A")
#Result := 10
When (= "B")
#Result := 11
When (= "C")
#Result := 12
When (= "D")
#Result := 13
When (= "E")
#Result := 14
When (= "F")
#Result := 15
Endcase
Endif
Endroutine
Re: GUID as number
Posted: Sat Jan 27, 2024 7:47 am
by adale
Brendan,
Thanks for this bit.
I copied the code into a RUP, compiles fine, but crashes when runs.
Doing some debug work, the crash occurs in the BEGIN_LOOP statement during the #Result calc.
If it makes a difference, my RUP is server side based (running on IBM i server).
#Result += #Com_self.GetHexCharacterValue( #Hex.UpperCase.Substring( #i 1 ) ) * (16).AsFloat.Power( (#Hex.CurChars - #i) )
>> result of the calculated Hex Character Value * (16) as a Float value to the power of 'the number of characters in the #hex field less the current character count (#i)'
- for each loop iteration, the .Power would be 1 less working its way down to 1.
*GUID is basically 32 characters, so in the first loop this would be .Power( 31 ) ?
I haven't calculated this out the way out, but to the power of 31, exceeds the Max digits of 19 for an Int(8) field (#Result), which is causing the crash.
For use on an IBM i server, do I just need to define a larger *SIGNED numeric field as the *Result? Or is there some other issue I am just not catching?
Re: GUID as number
Posted: Mon Jan 29, 2024 9:18 am
by BrendanB
Arlyn,
you will note that in my code the result field is:
Code: Select all
Define_Map For(*RESULT) Class(#XLib_INT64) Name(#Result)
the #XLib_INT64 is large enough -- if you wish to use your own variable, use:
define #myLargeInt *INT 8
Brendan.
Re: GUID as number
Posted: Tue Jan 30, 2024 2:04 am
by adale
Interesting. I will need to research this further.
I used the same #Result definition you had (reffld: XLib_INT64), double checked my repository to verify that XLib_INT64 was defined as 8 byte Integer.
Yet in my tests, it calcs fine all the way through the iterations to the 15th power, but on the 16th power run it crashes when the result becomes 20 digits long. Maybe there is something on the IBM i partition definition that is causing this.