# IonicWind Software

## IWBasic => General Questions => Topic started by: Andy on August 10, 2017, 12:58:19 am

Title: Converting C to IWB
Post by: Andy on August 10, 2017, 12:58:19 am
Here is an example in C of how to convert a uint64 number to hex:

Code Select
`static char hex [] = { '0', '1', '2', '3', '4', '5', '6', '7',                        '8', '9' ,'A', 'B', 'C', 'D', 'E', 'F' }; int uintToHexStr(unsigned int num,char* buff){    int len=0,k=0;    do//for every 4 bits    {        //get the equivalent hex digit        buff[len] = hex[num&amp;0xF];        len++;        num>>=4;  //shift right 4 chars    }while(num!=0);`

buff receives the corresponding hex (in reverse order - but that's easy enough to sort out).

I'm having trouble converting the above to IWB - can anyone help please?

On the face of it, it looks simple enough - but how do I translate the line:
buff[len] = hex[num&amp;0xF];

I'm quite happy if the number to be converted is a string - if that makes it easier.

OR:

Could this code be placed in an IWB sub routine and called? - never attempted that before.

Thanks,
Andy.
Title: Re: Converting C to IWB
Post by: Andy on August 10, 2017, 04:16:42 am
As far as I can work out (and I could be wrong as usual), the line:

buff[len] = hex[num&amp;0xF]; is getting the binary XOR value by comparing the binary number against 1111 (0xF), which then gets the corresponding hex value stored in the hex[] Array.

Title: Re: Converting C to IWB
Post by: Egil on August 10, 2017, 04:44:24 am
Hi Andy,

I think the characters &amp; is the result of conversion errors when copying the code. And should read just & instead.

Then for  the decimal to hex conversion... why not use hex\$(nnnn), where nnnn is the decimal value to be converted, and  then arrange the hex expression in 8 bit chunks so the result is presented in the wanted order (reverse or normal)?

As far as I can see (whithout remebering much C coding), that's what your code example does.

EDIT:  Forgot to say that by using  8 bit chunks, it is easy to see if you need to insert a leading zero into the expressions, e.g. 07 instead of just 7.

Title: Re: Converting C to IWB
Post by: LarryMc on August 10, 2017, 07:07:14 am
I guess I'm not understanding something.
Why are you trying to create a function that converts a Uint64 to HEX when we already have one called HEX\$
What am I missing?

Title: Re: Converting C to IWB
Post by: Andy on August 10, 2017, 08:17:50 am
Thanks Egil I will have a look now, been out all day.

Larry,

If I take a uint64 number for example.....    12345678901234567890
and use HEX\$ I get:   FFFFFFFFEB1F0AD2

Now when a registry qword displays the hex version of the above decimal number it gives:
AB54A98CEB1F0AD2 which is different from FFFFFFFFEB1F0AD2 (not displaying the AB54A98C part but replacing them with F's).

Title: Re: Converting C to IWB
Post by: LarryMc on August 10, 2017, 11:07:28 am
This is the HEX\$ code. See if you can see why you get a different answer.
Code Select
`SUB HEX\$(num as UINT64)DEF strrev[17] as ISTRINGDEF outstr as POINTERDEF count,i as INTDEF remain as INTDEF div as UINT64:div = 16count = 0outstr = AllocHeap(17)do remain = num % div num = num / div if remain > 9 strrev[count] = (remain-10) + asc("A") else strrev[count] = remain + asc("0") endif count = count + 1until num = 0qstrrev[count] = chr\$(0)for i = 0 to count-1 #<STRING>outstr[i] = strrev[count-1-i]next i#<STRING>outstr[i] = 0RETURN #<STRING>outstrENDSUB`
Title: Re: Converting C to IWB
Post by: LarryMc on August 10, 2017, 12:39:30 pm
OK, we can fix this but we need someone smarter than me to sort it out.
I know why it's not working and I know HOW to fix it but I just don't know how to write the code to do it.
First I wrote this simple little sub that right shifts 4 bits at a time and then uses the existing HEX\$ function to get the hex value and add it on to a string and then return it.
Code Select
`openconsoleUINT64 numin = 12345678901234567890'AB54A98CEB1F0AD2 which is different from FFFFFFFFEB1F0AD2.'FFFFFFFFEB1F0AD2? hex\$2(NUMIN)waitconSUB HEX\$2(num as UINT64),stringstring outstruint64 num2NUM2=NUMFOR i = 1 TO 15  outstr = Hex\$(num2 & 0xF) +outstr? outstr num2=num2 >> 4 if num2=0 then breakNEXT iRETURN outstrENDSUB`
When you run the program with Andy's input you get the same wrong result as you do with the HEX\$ FUNCTION.
It demonstrates the problem with the HEX\$ function: after 32 bits there is a problem with shifting.

Now, I found a discussion about a problem with shifting 64 bits numbers past 32 bits.  The discussion, with Turley's reasoning for using his implementation, and Sapero's workaround fix, is all in assembly and in terms of LEFT shifting.   To solve our problem, we need a version of my little sub(or a variation thereof) to be built around RIGHT shifting and with Sapero's assembly workaround converted over to right shifting.

Like I implied, the info is there. We just need someone smart enough to take it and run. I'm not the who on this one.

http://www.ionicwind.com/forums/index.php?topic=1707.msg15766#msg15766
Title: Re: Converting C to IWB
Post by: Andy on August 10, 2017, 12:53:38 pm
Larry, I think that's the answer, wether I'm clever enough to do it remains to be seen, I will have a look at it in the morning as I really need to get some sleep now.

Thanks Larry.
Title: Re: Converting C to IWB
Post by: jalih on August 10, 2017, 01:03:11 pm
Hi all,

You could probably use this simple asm trick to convert one byte to ascii hexadecimal and process INT64 one byte at a time:

Code Select
`istring hexnum[2]char num = 255_asm mov al, [\$num] aam 16 @digit2: add al, 090h daa adc al, 040h daa @digit1: xchg al, ah add al, 090h daa adc al, 040h daa mov word [\$hexnum], ax_endasmprint hexnum`
Title: Re: Converting C to IWB
Post by: fasecero on August 10, 2017, 10:12:38 pm
Try using the q modifier literal

Code Select
`UINT64 numin = 12345678901234567890qprint HEX\$(NUMIN)waitcon`
Title: Re: Converting C to IWB
Post by: jalih on August 11, 2017, 12:59:29 am
I wrote a fast 32-bit hex32\$() subroutine in asm for quick ascii hex conversion. Fast 64-bit version should be possible by just calling routine twice to handle hi -and low-dwords separately.

I will post some code later today...
Title: Re: Converting C to IWB
Post by: Andy on August 11, 2017, 03:38:40 am
Fasecero,

I forgot about adding the Q to the end of the uint64 - that works, but brings back the old Problem of adding a Q to a number you don't know.

Larry,

I copied the Hex\$ Code, renamed it - that's all, added a Q to the unit64 number and that didn't work, but the built in IWB Hex\$ function does.

Jalih,
That would be great if you could post a copy and explain how to use it.

Thanks guys.
Title: Re: Converting C to IWB
Post by: jalih on August 11, 2017, 09:04:46 am
Quote from: Andy on August 11, 2017, 03:38:40 am
Jalih,
That would be great if you could post a copy and explain how to use it.

Here are hex32\$() and hex64\$() functions:

Code Select
`uint num1 = 0xFF00FF00uint64 num2 = 12345678901234567890qprint hex32\$(num1)print hex64\$(num2)waitconend\$option "/p 1"sub hex32\$(uint num), string    istring hexnum[9]_asm    lea esi, [num]    lea edi, [hexnum]    mov al, byte [esi]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov edx, eax    shl edx, 16    mov al, byte [esi+1]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov dx, ax    mov [edi+4], edx    mov al, byte [esi+2]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov ecx, eax    shl ecx, 16    mov al, byte[esi+3]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov cx, ax    mov [edi], ecx    mov byte [edi+8], 0_endasm    return hexnumendsubsub hex64\$(uint64 num), string    istring hexnum[17]_asm    lea esi, [num+4]    lea edi, [hexnum]    mov al, byte [esi]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov edx, eax    shl edx, 16    mov al, byte [esi+1]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov dx, ax    mov [edi+4], edx    mov al, byte [esi+2]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov ecx, eax    shl ecx, 16    mov al, byte[esi+3]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov cx, ax    mov [edi], ecx    sub esi, 4    add edi, 8    mov al, byte [esi]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov edx, eax    shl edx, 16    mov al, byte [esi+1]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov dx, ax    mov [edi+4], edx    mov al, byte [esi+2]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov ecx, eax    shl ecx, 16    mov al, byte[esi+3]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov cx, ax    mov [edi], ecx    mov byte [edi+8], 0_endasm    return hexnumendsub\$option "/p 0"`
Title: Re: Converting C to IWB
Post by: Andy on August 11, 2017, 09:15:52 am
Jalih,

I will try that, thanks for posting it, the only problem is you have added the letter q to the uint64 number, and I don't know what the number will be and cannot hard code it.

Title: Re: Converting C to IWB
Post by: jalih on August 11, 2017, 09:51:08 am
Quote from: Andy on August 11, 2017, 09:15:52 am
I will try that, thanks for posting it, the only problem is you have added the letter q to the uint64 number, and I don't know what the number will be and cannot hard code it.

You don't need to hard code a number. The q modifier is  only needed when you enter a numeric literal (constant) in code. Without the q modifier, compiler treats it as INT.
Title: Re: Converting C to IWB
Post by: srvaldez on August 11, 2017, 02:43:09 pm
Andy, maybe make a union with a Uint64 and two ints, then take the hex of the two ints.
Title: Re: Converting C to IWB
Post by: fasecero on August 11, 2017, 04:32:10 pm
Quote
I forgot about adding the Q to the end of the uint64 - that works, but brings back the old Problem of adding a Q to a number you don't know.

Wow, I didn't know that.

It seems that INT() return an INT64 from a double, so theoretically you can use this to "attach" the q to a non literal integer.

Code Select
`INT a = 106335683 ' MAX: 2147483647INT b = 12772387INT c = 9090INT64 a64 = MakeINT64(a)INT64 b64 = MakeINT64(b)INT64 c64 = MakeINT64(c)INT64 numin = a64 * b64 * c64print HEX\$(numin)PRINT HEX\$(12345678901234567890q)WAITCONSUB MakeINT64(INT value), INT64 double a = FLT(value) INT64 b = INT(a) RETURN bENDSUB`

If this works for you then you should stick to INT64 in your whole program, and when some external func gives you an INT you should cast it to INT64 right away.
Title: Re: Converting C to IWB
Post by: jalih on August 12, 2017, 12:05:49 am
Quote from: fasecero on August 11, 2017, 04:32:10 pm
It seems that INT() return an INT64 from a double, so theoretically you can use this to "attach" the q to a non literal integer.

On Andy's application, it's not probably a good idea. With double you get 52-bits of precision, not the full range of INT64.
Title: Re: Converting C to IWB
Post by: fasecero on August 12, 2017, 02:07:43 am
And you are right. A double has 64 bits but can represent an "int55" (assuming such a thing existed), so the funcion I made will not work, thank you very much for pointing this out. I was trying to avoid this suggestion, but the solution I can think of would be to make a c dll that does the casting from int to int64. Can't find another "native" way to do it.

EDIT: Now that I think about it better, I think it will work just fine. The MakeINT64() function is used to pass a number from 32 to 64 bits, a number that you already know it will be 32 bits, only then you use this function. If you have a number greater than 32 bits you just use an INT64 variable from the beginning, and forget about that function. Can you guys think of an example where something doesn't work fine?
Title: Re: Converting C to IWB
Post by: ckoehn on August 12, 2017, 08:47:22 pm
The biggest problem is getting the number into a 64 bit variable.  Using double, like fascero said is the easiest way.

Code Select
`openconsoleint64 bignumberstring hexdouble smallnumber = 1234567bignumber = smallnumber * smallnumber * smallnumberhex = makehex(bignumber)print bignumber,hexdountil inkey\$=chr\$(27)   'press ESC to exitcloseconsoleendsub makehex(int64 bnum),string istring num[17] = "0123456789ABCDEF\0" istring ans[17] = "----------------\0" int ptr=1 for i=15 to 0 step -1 ans[i] = mid\$(num,(bnum % 16) + 1,1) bnum = bnum >> 4 next i while mid\$(ans,ptr,1)="0" 'remove leading 0's ptr++ endwhile ans = mid\$(ans,ptr) return ansendsub`
Title: Re: Converting C to IWB
Post by: jalih on August 13, 2017, 12:08:36 am
Quote from: fasecero on August 12, 2017, 02:07:43 am
EDIT: Now that I think about it better, I think it will work just fine. The MakeINT64() function is used to pass a number from 32 to 64 bits, a number that you already know it will be 32 bits, only then you use this function. If you have a number greater than 32 bits you just use an INT64 variable from the beginning, and forget about that function. Can you guys think of an example where something doesn't work fine?

You can't use double to convert input to 64-bit INT and use the full number range. IWBasic uses VAL() for conversion and it's limited to DOUBLE precision. Easiest way is to use the C-library or you can write your own function.

With binary data there is no problem, as any 8-byte buffer for data will suffice.

Code below demonstrates limited range of DOUBLE:

Code Select
`Uint64 num1, num2, num4double num3 num1 = 9223372036854775807uqnum3 = 9223372036854775807uqnum2 = Uint64(num3)num4 = val("9223372036854775807")print hex64\$(num1)print hex64\$(num2)print hex64\$(num4)waitconend\$option "/p 1"sub hex32\$(uint num), string    istring hexnum[9]_asm    lea esi, [num]    lea edi, [hexnum]    mov al, byte [esi]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov edx, eax    shl edx, 16    mov al, byte [esi+1]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov dx, ax    mov al, byte [esi+2]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov ecx, eax    shl ecx, 16    mov al, byte[esi+3]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov cx, ax    mov [edi], ecx    mov [edi+4], edx    mov byte [edi+8], 0_endasm    return hexnumendsubsub hex64\$(uint64 num), string    istring hexnum[17]_asm    lea esi, [num+4]    lea edi, [hexnum]    mov al, byte [esi]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov edx, eax    shl edx, 16    mov al, byte [esi+1]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov dx, ax    mov al, byte [esi+2]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov ecx, eax    shl ecx, 16    mov al, byte[esi+3]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov cx, ax    mov [edi], ecx    mov [edi+4], edx    sub esi, 4    add edi, 8    mov al, byte [esi]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov edx, eax    shl edx, 16    mov al, byte [esi+1]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov dx, ax    mov al, byte [esi+2]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov ecx, eax    shl ecx, 16    mov al, byte[esi+3]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov cx, ax    mov [edi], ecx    mov [edi+4], edx    mov byte [edi+8], 0_endasm    return hexnumendsub\$option "/p 0"`
Title: Re: Converting C to IWB
Post by: ckoehn on August 13, 2017, 06:50:52 am
I agree with Jalih.  Using double to convert to large of numbers results in an inaccurate conversion.  I tried it and wondered why my routine wasn't working.  Printing out the int64 number showed that it wasn't what i expected it to be.

This routine works too.

Code Select
`openconsoleuint64 bignumberstring hexdouble smallnumbersmallnumber = 1234567bignumber = smallnumber ^ 3print "converting: ", smallnumber, "^3 = ",  bignumber,hex = makehex(bignumber)print "to hex: ",hexDOuntil inkey\$=chr\$(27)closeconsoleendsub makehex(uint64 bnum),string String num = "0123456789ABCDEF" string ans ="" int ptr=1 for i=15 to 0 step -1 ans = mid\$(num,(bnum % 16) + 1,1) + ans bnum = bnum >> 4 next i while (mid\$(ans,ptr,1)="0") and (ptr<16) 'remove leading 0's ptr++ endwhile ans = mid\$(ans,ptr) return ansendsub`
Title: Re: Converting C to IWB
Post by: jalih on August 13, 2017, 08:29:17 am
Quote from: ckoehn on August 13, 2017, 06:50:52 am
This routine works too.

I timed IWBasic's HEX\$() and my hex64\$() functions and found that my routine is over five times faster. Inline asm really makes the difference:

Code Select
`DECLARE "kernel32.dll", GetTickCount(),intint i, start, finishUINT64 num =9223372036854775807uqstring resultprint "Execution times in millisecs for 1000000 iterations:"start = GetTickCount()for i = 1 to 1000000 result = hex\$(num)next ifinish = GetTickCount()print "IWBasic HEX\$() command: ",  finish-startstart = GetTickCount()for i = 1 to 1000000 result = hex64\$(num)next ifinish = GetTickCount()print "hex64\$ function written in inline asm: ", finish-startwaitconend\$option "/p 1"sub hex64\$(uint64 num), string    istring hexnum[17]_asm    lea esi, [num+4]    lea edi, [hexnum]    mov al, byte [esi]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov edx, eax    shl edx, 16    mov al, byte [esi+1]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov dx, ax    mov al, byte [esi+2]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov ecx, eax    shl ecx, 16    mov al, byte[esi+3]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov cx, ax    mov [edi], ecx    mov [edi+4], edx    sub esi, 4    add edi, 8    mov al, byte [esi]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov edx, eax    shl edx, 16    mov al, byte [esi+1]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov dx, ax    mov al, byte [esi+2]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov ecx, eax    shl ecx, 16    mov al, byte[esi+3]    aam 16    add al, 090h    daa    adc al, 040h    daa    xchg al, ah    add al, 090h    daa    adc al, 040h    daa    mov cx, ax    mov [edi], ecx    mov [edi+4], edx    mov byte [edi+8], 0_endasm    return hexnumendsub\$option "/p 0"`
Title: Re: Converting C to IWB
Post by: Andy on August 13, 2017, 08:49:39 am
This is all good stuff guys,

Clint I found you routine works, but if I just say bignumber = 12345678901234567890 directly it doesn't.

Jalih, I tried to assign a number like this:
result = hex64\$(9223372036854775806)

It came back with FFFFFFFFFFFFFFFE which is 18446744073709551614 decimal.

Am I missing something?

Thanks guys - please keep trying.
Title: Re: Converting C to IWB
Post by: jalih on August 13, 2017, 09:10:33 am
Quote from: Andy on August 13, 2017, 08:49:39 am
Jalih, I tried to assign a number like this:
result = hex64\$(9223372036854775806)

It came back with FFFFFFFFFFFFFFFE which is 18446744073709551614 decimal.

Am I missing something?

You need to add q or uq modifier for numeric literal. It's IWBasic limitation not fault in my code.
Title: Re: Converting C to IWB
Post by: Andy on August 13, 2017, 10:17:45 am
Thanks for that, but it brings me back to the same old problem - how do you add a literal to X when you don't know before hand the value of X?

Many thanks again for trying!

Andy.
Title: Re: Converting C to IWB
Post by: fasecero on August 13, 2017, 04:55:52 pm
Well, last attempt for me lol. I put aside the double problem by using the runtime functions, as jalih suggested. For some reason, I haven't been able to use c-runtime f that uses 64-bit variables (failed with DECLARE EXTERN approach and with LoadLibrary + GetProcAddress thing ), so I made a small vs dll that encapsulates the functions it needs. C++ source code included, just in case. Create an import library, place the dll at the same directory as the code below.

Code Select
`SETPRECISION 0' integer 64INT64 num64 = 9223372036854775807qprint num64' integer 64 to hex stringstring str_16 = HEX\$(num64)print str_16 ' integer 64 to decimal stringstring str_10 = STR\$(num64)print str_10 ' hex string to integer 64INT64 num16 = VAL(str_16)print num16' decimal string to integer 64INT64 num10 = VAL(str_10)print num10PRINTPRINTPRINT' THE SAME USING THE DLL\$USE "cast64.lib"DECLARE CDECL IMPORT, VAL64(string str, int base), INT64DECLARE CDECL IMPORT, STR64(INT64 value, string buffer)DECLARE CDECL IMPORT, HEX64(INT64 value, string buffer)' integer 64INT64 _num64 = 9223372036854775807qprint _num64' integer 64 to hex stringstring _str_16HEX64(_num64, _str_16)print _str_16 ' integer64 to decimal stringstring _str10STR64(_num64, _str10)print _str10 ' hex string to integer 64INT64 _num16 = VAL64(_str_16, 16)print _num16' decimal string to integer 64INT64 _num10 = VAL64(_str10, 10)print _num10waitconend`
Title: Re: Converting C to IWB
Post by: Andy on August 14, 2017, 03:23:59 am
I've come to the same conclusion, the only way for now is to write a Routine in another language that we can use.

I'm currently looking into a vb.net solution as I can understand that better than C and C ++

Andy.
Title: Re: Converting C to IWB
Post by: ckoehn on August 14, 2017, 07:27:24 am
QuoteClint I found you routine works, but if I just say bignumber = 12345678901234567890 directly it doesn't.

Like Jahil said, you need to add a q or uq to the end of a literal value.  IWBASIC limitation.  There is no way that making these routines in another language will help, because you could never transfer a int64 literal number from IWBASIC to that routine wiithout adding a q or uq. Just liike you have to now to use jahil or my routine.
Title: Re: Converting C to IWB
Post by: Andy on August 14, 2017, 08:54:30 am
But I can send a uint64 to a dll which returns a hex string, I'm only one step away from doing that, work permitting.
Title: Re: Converting C to IWB
Post by: fasecero on August 14, 2017, 09:09:29 am
QuoteI'm currently looking into a vb.net solution as I can understand that better than C and C ++

Ok, you'll find a way.

QuoteClint I found you routine works, but if I just say bignumber = 12345678901234567890 directly it doesn't.

Yeah about this, I'm just curious on how you can get a number like 12345678901234567890 without the "q". For example if I use some random function

Code Select
`UINT64 ticks = GetTickCount64()`

ticks variable will have an unknown value but it will have the "q" already attached.
Title: Re: Converting C to IWB
Post by: jalih on August 14, 2017, 09:27:51 am
Quote from: Andy on August 14, 2017, 08:54:30 am
But I can send a uint64 to a dll which returns a hex string, I'm only one step away from doing that, work permitting.

You can already send uint64 to IWB HEX\$() function, use my routine or some other routine.  It's not the problem, your real problem is getting user or program input as uint64. As I already said, if data is binary data then you can just read it into 8 byte buffer and pass that to HEX\$() routine.

Writing a function to validate ascii input and convert it to int64 is probably not that hard to write. Simple state machine can be used to validate input string and build uint64 from ascii digits.

We could write IVAL() function for IWB to handle 64-bit integers?
Title: Re: Converting C to IWB
Post by: Andy on August 14, 2017, 10:03:46 pm
Yes, I agree about how you get a unit64, at the moment I'm focusing on registry qwords -  so the number has already been inputted.

Title: Re: Converting C to IWB
Post by: ckoehn on August 15, 2017, 05:03:42 am
What is trying to be said here, if you already have a number in uint64 format, the routines already given you will work.  You don't need an external dll.
Title: Re: Converting C to IWB
Post by: Andy on August 15, 2017, 05:10:05 am
Clint,

Unless I'm missing something I cannot get a hex value greater than 7fffffffffffffff with the routines and qwords go all the way up to 16 f's.

Don't get me wrong - I really do appreciate the work you guys are doing on this!
Title: Re: Converting C to IWB
Post by: jalih on August 15, 2017, 07:40:46 am
Quote from: Andy on August 15, 2017, 05:10:05 am
Unless I'm missing something I cannot get a hex value greater than 7fffffffffffffff with the routines and qwords go all the way up to 16 f's.

Like Clint said, just read qword into 8-byte buffer and it will just work. You can use Union to map bytes into uint64.

Code Select
`union dat uint64 value uint dword[2]endunion def num as datnum.dword[0] = 0xffffffffnum.dword[1] = 0xffffffffprint hex\$(num.value)`
Title: Re: Converting C to IWB
Post by: Andy on August 16, 2017, 12:09:34 am
That's fantastic guys! - think maybe my brain cells were on a "go slow" for a while.

With the code amended I can read a qword and return it's hex string value - this means I can finish off my RegExport function which exports all values of a key to a file.

Code Select
`\$include "C:\\Include Files\\Registry\\registrylib.inc"openconsoleprintprintprint RegGetQWValueHex("HKEY_CURRENT_USER\\Software\\Test\\One","qword")printprintdo:until inkey\$ <> ""closeconsoleend`

So for registry Qwords I now have two functions for reading them:

RegGetQWValue - returns the decimal (uint64) value
RegGetQWValueHex - returns the hex string value.

I will post the library and include file when I'm done.

Thanks again!!!
:)
Title: Re: Converting C to IWB
Post by: fasecero on August 17, 2017, 08:40:06 pm
Just a side note. My dll works for INT64, anyway it can be easily ported for UINT64. But, today I give it another try by using c-runtime & 64 bits from the interface, without using a dll, and it seems that I succeeded. This problem is already solved by the union, I share it simply for the pleasure that gave me to achieve my goal xD

Code Select
`\$INCLUDE "windowssdk.inc"' string to UINT64UINT64 value = StringToUINT64("FFFFFFFFFFFFFFFF") ' hex numberprint value' UINT64 to stringstring text = UINT64ToString(value)print textPRINT WAITCON' -------------------------------------------------------------------------------------' C-Library Data Conversion Functions' https://msdn.microsoft.com/en-us/library/0heszx3w.aspx' -------------------------------------------------------------------------------------DECLARE CDECL _strtoui64Template(pointer nptr, pointer endptr, uint base), UINT64SUB StringToUINT64(string text), UINT64 UINT64 value = 0 UINT hInst=LoadLibrary("msvcrt.dll") IF hInst THEN UINT proc = GetProcAddress(hInst, "_strtoui64") IF proc THEN value = !<_strtoui64Template>proc(text, 0, 16) ENDIF FreeLibrary(hInst) ENDIF RETURN valueENDSUBDECLARE CDECL _ui64toa_sTemplate(UINT64 value, pointer buffer, INT sizeInCharacters, INT radix), INTSUB UINT64ToString(UINT64 value), string string buffer = "" UINT hInst=LoadLibrary("msvcrt.dll") IF hInst THEN UINT proc = GetProcAddress(hInst, "_ui64toa_s") IF proc THEN value = !<_ui64toa_sTemplate>proc(value, buffer, 200, 16) ENDIF FreeLibrary(hInst) ENDIF RETURN UCASE\$(buffer)ENDSUB`
Title: Re: Converting C to IWB
Post by: Andy on August 17, 2017, 10:47:47 pm
Fasecero,

That is fantastic - great job!

A good while ago I wrote an alternative registry editor, but ran into difficulties when it came to adding / amending qwords.

I can now (when I have time) go back to the program and update it - your code will allow a user to add / amend a qword value (in hex) which can then be translated into a uint64 and saved.

Modifying this code in the StringToUINT64 sub with the line :
value = !<_strtoui64Template>proc(text, 0, 10)

also allows me to take a string decimal e.g. "12345678901234567890" and turn it into a uint64 of 12345678901234567890 which will enable a user to add / amend a qword with decimal as well.

Thanks,
Andy.