Recent

Author Topic: [SOLVED] c to pascal translation (binary operation)  (Read 768 times)

Phoenix

  • Full Member
  • ***
  • Posts: 107
[SOLVED] c to pascal translation (binary operation)
« on: July 21, 2024, 04:29:14 pm »
hi I would like to translate this piece of code into pascal
Code: C  [Select][+][-]
  1. typedef unsigned long long  uint64;
  2. #define CACHE_L1_SELECTION_MASK(_bitCount) (~((~(uint64)0) >> (_bitCount)))
but using the following code i get different values ​​and i dont know how to get the correct value (it's probably the binary not)
Code: Pascal  [Select][+][-]
  1.  function CACHE_L1_SELECTION_MASK(_bitCount: QWord): NativeInt;
  2.  begin
  3.   Result:= not ((not QWord(0)) shr _bitCount);
  4.  end;
I used lazarus 64bit and Code::Blocks

Code: C  [Select][+][-]
  1. printf("CACHE_L1_SELECTION_MASK %d \n", CACHE_L1_SELECTION_MASK(17888));  //-1
  2. printf("CACHE_L1_SELECTION_MASK %d \n", CACHE_L1_SELECTION_MASK(255));    //-1
  3. printf("CACHE_L1_SELECTION_MASK %d \n", CACHE_L1_SELECTION_MASK(0));      //0
  4. printf("CACHE_L1_SELECTION_MASK %d \n", CACHE_L1_SELECTION_MASK(1));      //0
  5. printf("CACHE_L1_SELECTION_MASK %d \n", CACHE_L1_SELECTION_MASK(48));     //-65536
  6. printf("CACHE_L1_SELECTION_MASK %d \n", CACHE_L1_SELECTION_MASK(128));    //-1
  7.  

Code: Pascal  [Select][+][-]
  1. ShowMessage(
  2.    IntToStr(CACHE_L1_SELECTION_MASK(17888))+LineEnding+  //-4294967296
  3.    IntToStr(CACHE_L1_SELECTION_MASK(255))+LineEnding+    //-2
  4.    IntToStr(CACHE_L1_SELECTION_MASK(0))+LineEnding+      //0
  5.    IntToStr(CACHE_L1_SELECTION_MASK(1))+LineEnding+      //-9223372036...
  6.    IntToStr(CACHE_L1_SELECTION_MASK(48))+LineEnding+     //-65536
  7.    IntToStr(CACHE_L1_SELECTION_MASK(128))+LineEnding);   //0
« Last Edit: July 21, 2024, 08:39:05 pm by Phoenix »

tetrastes

  • Hero Member
  • *****
  • Posts: 517
Re: c to pascal translation (binary operation)
« Reply #1 on: July 21, 2024, 06:52:04 pm »
According to C standard, the behaviour of shift for 17888, 255 and 128 is undefined, and compilers give warnings about that. The behaviour of fpc in these cases is unknown. There was a discussion about that: https://forum.lazarus.freepascal.org/index.php/topic,40340.0.html. In any case you cannot rely on those results.

As for results for 0, 1 and 48, note that in your C code you use %d format, i.e. results are converted to int. If you change your pascal function to return integer longint (edited for accuracy), results for 64-bit program are:
Code: Pascal  [Select][+][-]
  1.    IntToStr(CACHE_L1_SELECTION_MASK(17888))+LineEnding+  //0 - do not trust!
  2.    IntToStr(CACHE_L1_SELECTION_MASK(255))+LineEnding+    //-2 - do not trust!
  3.    IntToStr(CACHE_L1_SELECTION_MASK(0))+LineEnding+      //0
  4.    IntToStr(CACHE_L1_SELECTION_MASK(1))+LineEnding+      //0
  5.    IntToStr(CACHE_L1_SELECTION_MASK(48))+LineEnding+     //-65536
  6.    IntToStr(CACHE_L1_SELECTION_MASK(128))+LineEnding);   //0 - do not trust!
what corresponds to your C results for those arguments, which we can trust.

And if you change format to %lld in C code, you'll get for 64-bit program
Code: C  [Select][+][-]
  1. printf("CACHE_L1_SELECTION_MASK %lld \n", CACHE_L1_SELECTION_MASK(17888));  //-1 - undefined!
  2. printf("CACHE_L1_SELECTION_MASK %lld \n", CACHE_L1_SELECTION_MASK(255));    //-1 - undefined!
  3. printf("CACHE_L1_SELECTION_MASK %lld \n", CACHE_L1_SELECTION_MASK(0));      //0
  4. printf("CACHE_L1_SELECTION_MASK %lld \n", CACHE_L1_SELECTION_MASK(1));      //-9223372036854775808
  5. printf("CACHE_L1_SELECTION_MASK %lld \n", CACHE_L1_SELECTION_MASK(48));     //-65536
  6. printf("CACHE_L1_SELECTION_MASK %lld \n", CACHE_L1_SELECTION_MASK(128));    //-1 - undefined!
what corresponds to your pascal results for those arguments, for which the behaviour is defined.
« Last Edit: July 21, 2024, 07:06:10 pm by tetrastes »

jamie

  • Hero Member
  • *****
  • Posts: 6529
Re: c to pascal translation (binary operation)
« Reply #2 on: July 21, 2024, 07:04:24 pm »
Try this
Code: Pascal  [Select][+][-]
  1. function CACHE_L1_SELECTION_MASK(_bitCount:Integer):Integer;
  2.  
  3. begin
  4.   if _BitCount > 63 Then Exit(-1);  {it may need to be 64?}
  5.  Result:= not (UInt64(Not 0) shr _BitCount);
  6. end;                                                              
  7.  
  8.  

There are two things wrong with the original code.
First of., Normal Integers should be assumed here since the C code didn't specify the return type. This corrects a lot.

Also you can't shift more bits than you have so I assume the C compiler is generating a -1 for a default value.

I ran the numbers you gave, and it seems to be ok.
The only true wisdom is knowing you know nothing

Phoenix

  • Full Member
  • ***
  • Posts: 107
Re: c to pascal translation (binary operation)
« Reply #3 on: July 21, 2024, 08:38:34 pm »
Thank you both!  :)

tetrastes

  • Hero Member
  • *****
  • Posts: 517
Re: c to pascal translation (binary operation)
« Reply #4 on: July 21, 2024, 10:06:32 pm »
First of., Normal Integers should be assumed here since the C code didn't specify the return type.

No, the type is explicitly defined in macro, otherwise the output of printf for %d and %lld would be identical.

MSC warns about that:

warning C4477: 'printf' : format string '%d' requires an argument of type 'int', but variadic argument 1 has type 'unsigned __int64'
note: consider using '%lld' in the format string

though gcc doesn't.

Also the results of msc in undefined cases are the same as of fpc (not -1, as of gcc).
« Last Edit: July 21, 2024, 10:09:20 pm by tetrastes »

 

TinyPortal © 2005-2018