How convert this C code to PB?

Just starting out? Need help? Post your questions and find answers here.
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

How convert this C code to PB?

Post 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.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: How convert this C code to PB?

Post 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?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: How convert this C code to PB?

Post 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?
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: How convert this C code to PB?

Post 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.
guy rabiller | radfac founder / ceo | raafal.org
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: How convert this C code to PB?

Post 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.
guy rabiller | radfac founder / ceo | raafal.org
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Re: How convert this C code to PB?

Post 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).
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: How convert this C code to PB?

Post 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.
guy rabiller | radfac founder / ceo | raafal.org
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Re: How convert this C code to PB?

Post 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.
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: How convert this C code to PB?

Post 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.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: How convert this C code to PB?

Post 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
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: How convert this C code to PB?

Post 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)
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: How convert this C code to PB?

Post 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.
guy rabiller | radfac founder / ceo | raafal.org
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: How convert this C code to PB?

Post 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
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: How convert this C code to PB?

Post 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");

Windows 11, Manjaro, Raspberry Pi OS
Image
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: How convert this C code to PB?

Post 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,
Post Reply