Results 1 to 5 of 5

Thread: Use of SHR with signed integers

  1. #1

    Use of SHR with signed integers

    I'm using SHR and SHL to convert fixed point <-> integers but I've find a problem.

    Code:
    program project2;
    
      FUNCTION integer_to_fixed &#40;v&#58; LONGINT&#41;&#58; LONGINT;
      BEGIN
        integer_to_fixed &#58;= v SHL 16;
      END;
    
      FUNCTION fixed_to_integer &#40;v&#58; LONGINT&#41;&#58; LONGINT;
      BEGIN
        fixed_to_integer &#58;= v SHR 16;
      END;
    
    VAR
      v&#58; LONGINT;
    begin
      v &#58;= integer_to_fixed &#40;-1&#41;; &#123; Gets -1 in 16.16 fixed point. &#125;
      WriteLn &#40;v&#41;;      &#123; Writes the value as stored in memory. &#125;
      WriteLn &#40;fixed_to_integer &#40;v&#41;&#41;; &#123; Should write '-1' but writes '65535'. &#125;
      ReadLn;
    end.
    As you see, SHR doesn't add the '1' bit. What can I use in the "fixed_to_integer" function?

    [edit] Found a solution:
    Code:
      FUNCTION fixed_to_integer &#40;v&#58; LONGINT&#41;&#58; LONGINT;
      BEGIN
        IF v < 0 THEN
          fixed_to_integer &#58;= &#40;v SHR 16&#41; OR $FFFF0000
        ELSE
          fixed_to_integer &#58;= v SHR 16;
      END;
    Is this the bets one?
    No signature provided yet.

  2. #2

    Use of SHR with signed integers

    You can use DIV 65536 of course, but it's slow.

    Another way is to use assembler:

    Code:
    FUNCTION fixed_to_integer &#40;v&#58; LONGINT&#41;&#58; LONGINT; 
      asm 
        sar       eax, 16
      END;

  3. #3

    Use of SHR with signed integers

    Quote Originally Posted by Mirage
    You can use DIV 65536 of course, but it's slow.
    Actually when optimizations are enabled, this division will be translated into "sar" (at least in Delphi; is it the same in FPC?)

  4. #4

    Use of SHR with signed integers

    Yes, FPC uses sar, optimized or unoptimized. However, -3 div 2=-1, while -3 sar 1=-2. To compensate FPC generates this code (register variables off):

    Code:
    ; &#91;12&#93; fixed_to_integer &#58;= v div 65536;
                    mov     edx,dword &#91;ebp-4&#93;
                    mov     eax,edx
                    sar     eax,31
                    and     eax,65535
                    add     edx,eax
                    sar     edx,16
                    mov     dword &#91;ebp-8&#93;,edx

  5. #5

    Use of SHR with signed integers

    Code:
    function sar&#40;Value,Shift&#58;integer&#41;&#58;integer; &#123;$IFDEF CPU386&#125;assembler; register;&#123;$ELSE&#125;&#123;$IFDEF FPC&#125;inline;&#123;$ELSE&#125;register;&#123;$ENDIF&#125;&#123;$ENDIF&#125;
    &#123;$IFDEF CPU386&#125;
    asm
     mov ecx,edx
     sar eax,cl
    end;
    &#123;$ELSE&#125;
    begin
     result&#58;=&#40;Value shr Shift&#41; or &#40;&#40;$ffffffff+&#40;1-&#40;&#40;Value and &#40;1 shl 31&#41;&#41; shr 31&#41; and ord&#40;Shift<>0&#41;&#41;&#41; shl &#40;32-Shift&#41;&#41;;
    end;
    &#123;$ENDIF&#125;
    But Delphi does also optimize DIV (2^n) terms to signed shift SAR opcodes.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •