Page 1 of 2

How convert this C code to PB?

Posted: Tue Sep 03, 2013 6:15 pm
by sec

Code: Select all

    uint64_t st[25];    
    uint8_t temp[144];
    int i;
  
  for (i = 0; i < 19; i++) {
        st[i] ^= ((uint64_t *) temp)[i];
    }
Thanks.

Re: How convert this C code to PB?

Posted: Tue Sep 03, 2013 6:29 pm
by IdeasVacuum
Well, it appears to be casting between two un-signed integer types (would need the type definition header file stdint.h). I think you can use quads in PB and not need the cast?

Re: How convert this C code to PB?

Posted: Tue Sep 03, 2013 7:16 pm
by sec
IdeasVacuum wrote:Well, it appears to be casting between two un-signed integer types (would need the type definition header file stdint.h). I think you can use quads in PB and not need the cast?
If i use two quad, the result is not same in C.
For same result in C, i wrote:
for example:
temp[0..3]=97,98,99,1
st[0]=0

In PB:
st(0) ! PeekQ(@temp(0))


But i feel wrong. could you please help me out?

Re: How convert this C code to PB?

Posted: Tue Sep 03, 2013 7:47 pm
by grabiller
For a straight forward port I would use:

Code: Select all

Structure st_25_t
  q.q[25]
EndStructure

Structure temp_144_t
  b.b[144]
EndStructure

Global st_25.st_25_t
Global temp_144.temp_144_t
Global i.l

For i=0 To 18
  st_25\q[i] ! temp_144\b[i]
Next
Another solution could be:

Code: Select all

Global Dim st_25.q(24)
Global Dim temp_144.b(143)
Global i.l

For i=0 To 18
  st_25(i) ! temp_144(i)
Next
But this may be not the best approaches. It depends on the all context of your application.

Cheers,
Guy.

Re: How convert this C code to PB?

Posted: Tue Sep 03, 2013 8:10 pm
by grabiller
Also, another approach, which I think (?) would be more efficient in terms of iteration:

Code: Select all

Structure st_25_t
  q.q[25]
EndStructure

Structure temp_144_t
  b.b[144]
EndStructure

Global st_25.st_25_t
Global temp_144.temp_144_t

Global *st_25.Quad = @st_25
Global *temp_144.Byte = @temp_144
Global i.l

#SIZE_OF_QUAD = SizeOf(Quad)
#SIZE_OF_BYTE = SizeOf(Byte)
i = 0
While i < 19
  *st_25\q ! *temp_144\b
  *st_25 + #SIZE_OF_QUAD : *temp_144 + #SIZE_OF_BYTE : i + 1
Wend
Cheers,
Guy.

Re: How convert this C code to PB?

Posted: Tue Sep 03, 2013 9:01 pm
by tinman
@grabiller: Your code uses the byte pointers incorrectly. The C code casts temp to an (uint64_t *) so it is addressing it as a pointer to uint64_t's, not bytes. So when you do the increment it should be by sizeof(QUAD), not sizeof(byte).

Re: How convert this C code to PB?

Posted: Tue Sep 03, 2013 9:05 pm
by grabiller
tinman wrote:@grabiller: Your code uses the byte pointers incorrectly. The C code casts temp to an (uint64_t *) so it is addressing it as a pointer to uint64_t's, not bytes. So when you do the increment it should be by sizeof(QUAD), not sizeof(byte).
You are right, indeed.

Here is the correct code:

Code: Select all

Structure st_25_t
  q.q[25]
EndStructure

Structure temp_144_t
  b.b[144]
EndStructure

Global st_25.st_25_t
Global temp_144.temp_144_t

Global *st_25.Quad = @st_25
Global *temp_144.Byte = @temp_144
Global i.l

#SIZE_OF_QUAD = SizeOf(Quad)
#SIZE_OF_BYTE = SizeOf(Byte)
i = 0
While i < 19
  *st_25\q ! *temp_144\b
  *st_25 + #SIZE_OF_QUAD : *temp_144 + #SIZE_OF_QUAD : i + 1
Wend
Thanks for correcting me.

Cheers,
Guy.

Re: How convert this C code to PB?

Posted: Tue Sep 03, 2013 9:08 pm
by tinman
There's another error, but it comes from the original C code. In the final iteration of the loop (i == 18) the code tries to access temp[144]...temp[151] which is past the end of the array.

Edit: I should also say that in your corrected version you are only readnig a byte from *temp_144\b whereas the C code reads a uint64_t, so it's really PeekQ() that's needed or assigning the temp pointer to a quad pointer.

Also, SizeOf(Quad) should resolve to a compile time constant so no need for the #SIZE_OF_QUAD. Same goes for the byte.

Edit 2: I'd convert it something like this:

Code: Select all

Dim st.q(24)
Dim temp.b(143)

For i = 0 To 18
  st(i) ! PeekQ(@temp(i * SizeOf(Quad)))
Next
But as I say there's an index out of bounds error from the original C code.

Edit 3: @sec you say the values do not match. You need to fill in 8 bytes in temp, not just 4 as you have done in your test code.

Re: How convert this C code to PB?

Posted: Wed Sep 04, 2013 3:30 am
by sec
Thanks both you :)

Code: Select all

Dim temp.c(7) 
temp(0) = 0
temp(1) = 0
temp(2) = 0
temp(3) = 0
temp(4) = 0
temp(5) = 0
temp(6) = 0
temp(7) = $80

Debug PeekQ(@temp())


Above code, PB output:
-9223372036854775808
C output with %llu, printf("%llu\n", ((uint64_t *) temp)[0]);
9223372036854775808
How to convert that PB sign? in PB, I tried & $FFFFFFFFFFFFFFFF but output is incorrect (-9223372036854775808)

Thanks.

Re: How convert this C code to PB?

Posted: Wed Sep 04, 2013 4:16 am
by IdeasVacuum
SkyWalk wrote a sprintf function for PB: http://www.purebasic.fr/english/viewtopic.php?p=315920

Search this forum for "large numbers", I recall that someone has worked on this requirement.

A possibility is to work with strings, as the integer/quad value is too big for 32bit

Re: How convert this C code to PB?

Posted: Wed Sep 04, 2013 4:53 am
by sec
IdeasVacuum wrote:SkyWalk wrote a sprintf function for PB: http://www.purebasic.fr/english/viewtopic.php?p=315920

Search this forum for "large numbers", I recall that someone has worked on this requirement.

A possibility is to work with strings, as the integer/quad value is too big for 32bit
Thanks, I want to know sure that the number's value is stored correct.

Code: Select all

Dim temp.c(7)
temp(0) = 0
temp(1) = 0
temp(2) = 0
temp(3) = 0
temp(4) = 0
temp(5) = 0
temp(6) = 0
temp(7) = $80

a.q = PeekQ(@temp())

Debug StrU(a)

Re: How convert this C code to PB?

Posted: Wed Sep 04, 2013 5:36 am
by grabiller
tinman wrote:Edit: I should also say that in your corrected version you are only readnig a byte from *temp_144\b whereas the C code reads a uint64_t, so it's really PeekQ() that's needed or assigning the temp pointer to a quad pointer.
Right, so it should be:

Code: Select all

Global *temp_144.Quad = @temp_144
And:

Code: Select all

  *st_25\q ! *temp_144\q
  *st_25 + #SIZE_OF_QUAD : *temp_144 + #SIZE_OF_QUAD : i + 1
I was not paying attention enough to the subtleties of the C code. :oops:

Thanks tinman.

Re: How convert this C code to PB?

Posted: Wed Sep 04, 2013 5:51 am
by sec
@grabiller:
@Tinman:

How can i handle this numbeR vrol in PB?:

Code: Select all

ImportC ""
  sprintf(*out,format.p-Ascii,val.q)
EndImport

Procedure.s outQ(v.q)
  Protected sout.s,*output 
  *output = AllocateMemory(64)
  sprintf(*output,"%llu",v)
  sout = PeekS(*output,-1,#PB_Ascii)
  FreeMemory(*output)
  ProcedureReturn sout
EndProcedure   


Macro ROTL64(x, y) 
  ((x) << (y)) | ((x) >> (64 - (y)))
EndMacro

Dim temp.c(7)
temp(0) = 0
temp(1) = 0
temp(2) = 0
temp(3) = 0
temp(4) = 0
temp(5) = 0
temp(6) = 0
temp(7) = $80

v.q = PeekQ(@temp())
vrol.q = ROTL64(v,1)
Debug StrU(vrol) ;[b]18446744073709551615[/b] << seem this range limit of PB
debug OutQ(vrol) ; 18446744073709551615
in C's ouput is 1

Thanks

Re: How convert this C code to PB?

Posted: Wed Sep 04, 2013 6:13 am
by idle
try this macro

Code: Select all

Macro RotLeft64(var,pp) 
   !if defined v_#var
      !rol qword [v_#var],pp
   !else 
      !rol qword [p.v_#var],pp
   !end if    
EndMacro 

Dim temp.a(7)
temp(0) = 0
temp(1) = 0
temp(2) = 0
temp(3) = 0
temp(4) = 0
temp(5) = 0
temp(6) = 0
temp(7) = $80

v.q = PeekQ(@temp())
Debug RSet(Bin(v,#PB_Quad),64,"0");
RotLeft64(v,1) 
Debug RSet(Bin(v,#PB_Quad),64,"0");


Re: How convert this C code to PB?

Posted: Wed Sep 04, 2013 7:00 am
by sec
idle wrote:try this macro

Code: Select all

Macro RotLeft64(var,pp) 
   !if defined v_#var
      !rol qword [v_#var],pp
   !else 
      !rol qword [p.v_#var],pp
   !end if    
EndMacro 

Dim temp.a(7)
temp(0) = 0
temp(1) = 0
temp(2) = 0
temp(3) = 0
temp(4) = 0
temp(5) = 0
temp(6) = 0
temp(7) = $80

v.q = PeekQ(@temp())
Debug RSet(Bin(v,#PB_Quad),64,"0");
RotLeft64(v,1) 
Debug RSet(Bin(v,#PB_Quad),64,"0");

@idle: it got
PureBasic.asm [194]:
rol qword [p.v_v],pp
error: illegal instruction
Thanks,