Board index » delphi » Fixed Point Math in Delphi

Fixed Point Math in Delphi

Quote
>   dauwa...@tempest.adsnet.net (Tyler Dauwalder) writes:
[snip]
> I've tried all the kinds of typecasting that I
>  could find explained in the help files. So, does anyone else know how to
>  assign a floating point value to a fixed point number? Also, if so, how
>  would I then read that value?

Check the OnLine Help for trunc() and/or round()

HTH

/LG

____________________________________________________
Lars G. Oerne   (SM7BLJ)     MoSoft
P.O.Box 72                   S-340 36 MOHEDA Sweden
Cell Phone +46 0705441225    "The House of FRITSON"
____________________________________________________

 

Re:Fixed Point Math in Delphi


 I'm having trouble implementing fixed point math in Delphi. I've been
translating from a book that explains it in C, and I can't figure out how
to assign values to a fixed point number. The book's example (in C) is
this:

Long Fix_1 = (long)(23.45 * 256);

 It explains that you assign values by doing a typecast. Attempting a
typecast in Delphi has thus far not worked for me. (I get errors such as
"types do not match", etc.) I've tried all the kinds of typecasting that I
could find explained in the help files. So, does anyone else know how to
assign a floating point value to a fixed point number? Also, if so, how
would I then read that value?

--
              _   __   -------------------------------------------------
  .,,        ( `-'  \  | Tyler Dauwalder                               |
 C:::]|||||||||() | |  | dauwa...@adsnet.net                           |
  `'`        (_.-.__/  | http://metro.turnpike.net/M/MrBill/index.html |
                       -------------------------------------------------

Re:Fixed Point Math in Delphi


In article <4aucn9$...@mn5.swip.net>, l...@mosoft.se (Lars G. Oerne) wrote:

Quote
>   dauwa...@tempest.adsnet.net (Tyler Dauwalder) writes:
> I've tried all the kinds of typecasting that I
>  could find explained in the help files. So, does anyone else know how to
>  assign a floating point value to a fixed point number? Also, if so, how
>  would I then read that value?

My news reader has been acting up lately so I missed the first post. Here's
what I use.

Function RealToFixed(x : Real) : FixedPoint;
Begin
  x := x * 65536.0 + 0.49;
  RealToFixed := Round(x);
End;

-----------------------------------------------
Mike Chapin
Powder River
-----------------------------------------------

Re:Fixed Point Math in Delphi


Quote
mcha...@vcn.com (Michael Chapin) wrote:

|}> I've tried all the kinds of typecasting that I
|}>  could find explained in the help files. So, does anyone else know how to
|}>  assign a floating point value to a fixed point number? Also, if so, how
|}>  would I then read that value?
|}
|}My news reader has been acting up lately so I missed the first post. Here's
|}what I use.
|}
|}Function RealToFixed(x : Real) : FixedPoint;
|}Begin
|}  x := x * 65536.0 + 0.49;
|}  RealToFixed := Round(x);
|}End;

I caught this reponse that you gave to someone in the newsgroup, and I was
wondering why you multiply the incoming real number by 65536.0 ?
---------------------------------------------------------------
Kerry Sanders                   | "Cause when ya stop dreaming
ksand...@bham.mindspring.com   |    its time to die" - CHANGE
MindSpring Lifers - Club Member |
---------------------------------------------------------------

Re:Fixed Point Math in Delphi


In article <4au050$...@news1.wolfe.net>,

Quote
Tyler Dauwalder <dauwa...@tempest.adsnet.net> wrote:
> I'm having trouble implementing fixed point math in Delphi. I've been
>translating from a book that explains it in C, and I can't figure out how
>to assign values to a fixed point number. The book's example (in C) is
>this:

>Long Fix_1 = (long)(23.45 * 256);

const
  Fix_1: LongInt = Round( 23.45 * 256 );

Quote
> It explains that you assign values by doing a typecast. Attempting a
>typecast in Delphi has thus far not worked for me. (I get errors such as
>"types do not match", etc.) I've tried all the kinds of typecasting that I
>could find explained in the help files. So, does anyone else know how to
>assign a floating point value to a fixed point number? Also, if so, how
>would I then read that value?

C and Delphi handle typecasting a bit differently.  In C, a typecast can
imply a call to a type conversion function.  (In C++, you can even specify
this function.)  Thus, you can typecast a float to an integer.

In Delphi, you can only typecast between like-sized types:  A typecast is
your way to tell the compiler to interpret the same bitstream in different
ways.  To convert a float to an integer, you have to explicitly call a
conversion function like Trunc() or Round().

_________________________________________________________________________

Larger Question Time:  Why Are You Still Bothering With Fixed-Point?

I've done a fair amount of fixed-point math in my day, but I don't do much
anymore. Once float-point "coprocessors" started being part of the CPU,
float-point got very fast.  Just for an example, I [used to] sell a Mandelbrot/
Julia set explorer.  The all-in-the-registers 32-bit fixed point assembler
routine that was roughly twice as fast as the .387 routine running on a
Cyrix 387 (which was slightly faster than the Intel 387) was less than 10%
faster than the same routine running on a 486-33 - and is about five times
*slower* than the float-point code on a P90.

About the only fixed-point I do anymore is MulDiv(A, B, C) for (A * B) / C
where A, B, and C are all integers, and the macro uses the DX:AX A*B result as
the input to the division.

Note to anyone who's still following:  
function WinProcs.MulDiv(A, B, C: integer): integer *is not* the same as
assembler; asm
mov ax,[A]
mul [B]
idiv [C]
end; - it *rounds the result* to the nearest integer.  `
--

http://www.armory.com/~jon               Personal Pages
http://www.armory.com/~jon/pubs             Programming Publications
http://www.armory.com/~jon/hs         Home School Resource List

Re:Fixed Point Math in Delphi


Quote
In article <4b71b5$...@news.scruz.net>, Jon Shemitz <j...@armory.com> wrote:
>I've done a fair amount of fixed-point math in my day, but I don't do much
>anymore. Once float-point "coprocessors" started being part of the CPU,
>float-point got very fast.  Just for an example, I [used to] sell a Mandelbrot/
>Julia set explorer.  The all-in-the-registers 32-bit fixed point assembler
>routine that was roughly twice as fast as the .387 routine running on a
>Cyrix 387 (which was slightly faster than the Intel 387) was less than 10%
>faster than the same routine running on a 486-33 - and is about five times
>*slower* than the float-point code on a P90.

Ooops!  I was in a rush yesterday - it's the 8088-mode, double-precision
fixed point code which is five times slower; the 386-mode single-precision
32-bit fixed point code is "only" ca 35% slower than the 387 version.

--

http://www.armory.com/~jon               Personal Pages
http://www.armory.com/~jon/pubs             Programming Publications
http://www.armory.com/~jon/hs         Home School Resource List

Re:Fixed Point Math in Delphi


Quote
ksand...@bham.mindspring.com (Kerry Sanders) wrote:
>mcha...@vcn.com (Michael Chapin) wrote:
>|}> I've tried all the kinds of typecasting that I
>|}>  could find explained in the help files. So, does anyone else know how to
>|}>  assign a floating point value to a fixed point number? Also, if so, how
>|}>  would I then read that value?
>|}
>|}My news reader has been acting up lately so I missed the first post. Here's
>|}what I use.
>|}
>|}Function RealToFixed(x : Real) : FixedPoint;
>|}Begin
>|}  x := x * 65536.0 + 0.49;
>|}  RealToFixed := Round(x);
>|}End;
>I caught this reponse that you gave to someone in the newsgroup, and I was
>wondering why you multiply the incoming real number by 65536.0 ?
>---------------------------------------------------------------
>Kerry Sanders                       | "Cause when ya stop dreaming
>ksand...@bham.mindspring.com       |    its time to die" - CHANGE
>MindSpring Lifers - Club Member     |
>---------------------------------------------------------------

PMJI...
Probably because 65536 = 2^16, so the result is 32-bit fixed point
with 16 bits of fraction, a good useful format for many things
such as fixed point graphics calculations. E.g., if 1.0 is one
inch, then you have a range of -32768.0 to 32767.99998474 or so
inches in steps of 0.00001525879 inches or so. Even when you
square something to do distance calculation, you can deal with
up to 181+ inches, which is a pretty large screen. I guess you
might have to rescale if you were doing that for one of those
mural printers.

Another point though: I don't know that the 0.49 makes much sense
in the Delphi environment, if anywhere. I suspect Round by itself
does exactly the desired thing, so it's hardly worth the overhead
of making a function. Use
  integerVar := Round(realVar*SC);
instead, where SC is an easy-to-type name for a scaling constant such
as 65536.0 or 256.0.

To see the effect of Round vs Trunc, run the following. Black is
for identity y=x, red is Trunc, and Lime is Round.
Just do a new project and put the following in the
OnPaint event handler for the form and go.

Trunc is a bit weird, if you ask me. If that is what Trunc
is going to do, there ought to be another that just zeroes
the fractional bits, IMHO.

HTH,
Regards,
Bengt Richter
Seasons Greetings, BTW.
-----------------------------------------------------------------
implementation

{$R *.DFM}

procedure TForm1.FormPaint(Sender: TObject);
const PPS=32;NS=4; XOrg=PPS*NS+16; YOrg=PPS*NS+16;
var
  x,y:integer;
  yT,yR,yI: longint;
  xF: real;
begin
  with canvas do begin
    Moveto(XOrg-NS*PPS,YOrg);
    LineTo(XOrg+NS*PPS,YOrg);
    Moveto(XOrg,YOrg-NS*PPS);
    LineTo(XOrg,YOrg+NS*PPS);
  end;
  for x:= -NS*PPS to NS*PPS do begin
    xF := x/PPS;
    yT := Trunc(xF)*PPS;
    yR := Round(xF)*PPS;
    yI :=  x;
    with Canvas do begin
      Pixels[x+XOrg,YOrg-yI]:= clBlack;
      Pixels[x+XOrg,YOrg-yT-1]:= clRed;  {-1 to see it}
      Pixels[x+XOrg,YOrg-yR+1]:= clLime; {+1 ditto}
    end;
  end;
end;

end.
-------------------------------------------------------------------------

Other Threads