fixed point vs floating point 
Author Message
 fixed point vs floating point


        >As to expecting the language to do scaling autoamtically, I think this is
        >a mistake for fixed-point. PL/1 tried and failed,

PL/I did not fail.  Automatic scaling of fixed-point intermediate
results is highly successful.  It works on the principle
of preserving as many digits after the binary/decimal point
as possible.

        > and COBOL certainly
        >does not succeed (a common coding rule in COBOL is never to use the
        >COMPUTE verb, precisely because the scaling is not well defined).

        >I think any attempt to automatically determine the scaling of intermediate
        >results in multiplications and divisions in fixed-point is doomed to failure.

It isn't really, but the user needs to understand how fixed-point
arithmetic -- with a fractional part -- works.

        >This just *has* to be left up to the programmer, since it is highly
        >implementation dependent.



Sun, 21 May 2000 03:00:00 GMT  
 fixed point vs floating point


        >Anyway, I'll accept that fixed point operations are slower, but the
        >question remains: Why do most programmers insist on using floating point
        >when a fixed point better models the abstraction?  Is the reason solely
        >based on efficiency?

        >By the way, are there off-the-shelf subprograms (in Ada preferably, but I'd
        >take any language) for computing the elementary functions (sin, cos, etc)
        >of a fixed point angle?

The following evaluates sine using fixed point, for a limited range of
angles.
_____________________________________________________

/* Copyright (c) 1996, 1997 by R. A. Vowels. */
/* This subroutine computes the sine of an angle using fixed-point binary arithmetic. */
SINE:
        PROCEDURE(XX) OPTIONS (REORDER) RETURNS (FIXED BINARY(31,28));
                DECLARE XX FIXED BINARY(31,24);
                DECLARE X               FIXED BINARY (31,28);
                DECLARE Sum             FIXED BINARY (31,28);
                DECLARE Term            FIXED BINARY (31,28);
                DECLARE (J, K)          FIXED BINARY;
                DECLARE Neg             BIT(1);

   DECLARE (HiX, HiY) FIXED BINARY (31,14);
   DECLARE (LoX, LoY) FIXED BINARY (31,28);
   DECLARE (ProdHiXLoY, ProdHiYLoX, Prod) FIXED BINARY (31,28);

/* This macro procedure forms the product of the fixed-point arguments X1 and Y1. */
%MULT: PROCEDURE(LHS, X1, Y1);
                DECLARE (LHS, X1, Y1) CHARACTER;
                        ANSWER ('HiX = ' || X1 || ';') SKIP; /* Extract the upper 14 bits of X. */
                        ANSWER ('HiY = ' || Y1 || ';') SKIP; /* Extract the upper 14 bits of X. */
                        ANSWER ('LoX = ' || X1 || ' - HiX;' ) SKIP; /* Extract the lower 14 bits of X. */
                        ANSWER ('LoY = ' || Y1 || ' - HiY;' ) SKIP; /* Extract the lower 14 bits of Y. */

                        ANSWER ('Prod = HiX * HiY;') SKIP;  /* the product of the high bits. */
                        ANSWER ('ProdHiXLoY = HiX * LoY;') SKIP; /* Product of the upper bits of X, lower bits of Y. */
                        ANSWER ('ProdHiYLoX = HiY * LoX;') SKIP; /* Product of the upper bits of Y, lower bits of X. */
                        ANSWER (LHS || ' = Prod + ProdHiXLoY + ProdHiYLoX') SKIP; /* Sum them all. */

%END MULT;
%ACTIVATE MULT NORESCAN;

                        /* The following code segment evaluates the sine of an angle x using the   */
                        /* first 6 terms of the Taylor series:                                     */
                        /* sine x = x - x**3/3! + x**5/5! - x**7/7! + x**9/9! - x**11/11!          */
                        /* Range: -pi <= x <= pi                                                   */
                        /* Accuracy: 8 decimal places (typically better than 7 significant digits).*/
                        X = XX;

                        Sum = X;
                        Neg = X < 0;
                        IF Neg THEN X = -X;
                        IF X > 1.5707963 THEN /*sin(x) = sin(180-x). */
                                X = 3.1415927 - X;

                        /* For small angles, the radian angle is closer to the sine than this approximation. */
                        /* Therefore, we only execute the following DO group for larger angles. */
                        IF X > 0.002 THEN
                                DO;

                                        Sum = X;
                                        Term = X / 6;
                                        MULT(Term, Term, X);
                                        MULT(Term, Term, X);   /* To give x**3/3! */
                                        Sum = Sum - Term;

                                        Term = Term / 20;
                                        MULT(Term, Term, X);
                                        MULT(Term, Term, X);   /* To give x**5/5! */
                                        Sum = Sum + Term;

                                        Term = Term / 42;
                                        MULT(Term, Term, X);
                                        MULT(Term, Term, X);   /* To give x**7/7! */
                                        Sum = Sum - Term;

                                        Term = Term / 72;
                                        MULT(Term, Term, X);
                                        MULT(Term, Term, X);   /* To give x**9/9! */
                                        Sum = Sum + Term;

                                        Term = Term / 110;
                                        HiX = X;
                                        Term = Term * HiX;
                                        Term = Term * HiX;   /* To give x**11/11! */
                                        Sum = Sum - Term;

                                        IF Neg THEN Sum = -Sum;
                                END;
   RETURN (Sum);
END SINE;



Sun, 21 May 2000 03:00:00 GMT  
 fixed point vs floating point


        >  > I think any attempt to automatically determine the scaling of intermediate
        >  > results in multiplications and divisions in fixed-point is doomed to failure.
        >  > This just *has* to be left up to the programmer, since it is highly
        >  > implementation dependent.

        >Joe said

        >  <<No, it isn't hopeless.  It's quite simple and mechanical, actually.  If it
        >  were imposssible, why then did Ada83 attempt it?  It's exactly the same
        >  rules we were taught in grade school for the handling of decimal points
        >  after arithmetic on decimals, especially multiplication and division.
        >  Ada83 should have been able to do it, given the information provided when
        >  the various variables types were defined.>>

        >Actually it is this paragraph that makes me pretty certain that the problems
        >may have been misunderstandings of how Ada works. First of all, it is simply
        >wrong that Ada83 attempts to determine the proper normalization (to use
        >Joe's term) of multiplication and division. Both the Ada 83 and Ada 95
        >design require that the programmer specify the scale and precision of
        >intermediate results for multiplication and division (in fact in Ada 83,
        >this specification is *always* explicit, in some cases in Ada 95 it is
        >implicit, but only in trivial cases, e.g. where in Ada 83 you have to
        >write

        >   X := Type_Of_X (Y * Z);

        >In Ada 95, this particular conversion can be omitted.

        >Secondly, it is not at all true that the rules are obvious or that they
        >are exactly the same as the "rules we were taught in grade school". If
        >you write

        >  x := y * (V1 / V3);

        >where V1 is 1.0 and V3 is 3.0, then the issue of the precision of the
        >intermediate value is critical, and no, there are no simple grade school
        >answers to answer this. I suggest looking at PL/1 for an attempt at
        >defining this, an attempt which most consider a failure.

Rubbish.  If evaluation of this expression fails, it
is because of exceeding the capacity of the fixed-point
multiplier.  It has -- incidentally -- nothing to do
with the division.

The above is the WRONG way to compute an expression
using fixed-point facilities.

You would write it x = (y * V1) / V3;

This way gives the fullest accuracy; the way suggested
x - y * (V1/V3);
succumbs to truncation error, which is duly
magnified by the multiplication!

Incidentally, in PL/I, if the evaluation of the multiplication
overflows, it is because the intermediate precision
would be too great for the hardware unit.

x = y * 0.33333333333333;

If y has 1 or more decimal places, overflow may occur
because the number of places (in the product) after
the point exceeds the capacity of the hardware unit.

In PL/I, in such situations, when one or both operands
has a large number of digits, you specify the precision of
the intermediate product, using the MULIPLY built-in
function.  In this manner, you avoid fixed-point overflow.

        >As I mentioned
        >earlier, COBOL simply gives up in the COMPUTE statement and says that
        >the results are implementation dependent.

        >Robert Dewar



Sun, 21 May 2000 03:00:00 GMT  
 fixed point vs floating point


        >Joe said:

        ><<Portability was not an issue .. and so was never raised.

        >  However, now that you have raised the issue, some comments:  Portability
        >  is less important than workability.  And, we were always assured that use
        >  of Ada guaranteed portability.  Apparently that was a lie; we also need to
        >  be Ada experts to achieve portability?  Just like all other languages?

        >I always find it amazing that anyone would ever have, even for a moment,
        >thought that using an Ada compiler would somehow guarantee that their code
        >was portable. And it is even more amazing that someone with this strange
        >viewpoint would turn around later and complain that they were lied to.

        >Really Joe, surely you know that you cannot achieve portability without
        >some care on the programmer's part. Yes, it is true that programs can be
        >written in Ada that are portable. BUT, and this is a big BUT, you do have
        >to know the language. No, you do not have to be an Ada expert, but you DO
        >have to know the language, and you do have to know the language well enough
        >so that you know the difference between Ada the language, and what your
        >compiler happens to implement for implementation dependent constructs.
        >If you don't know Ada, and you don't care about portability (as was
        >apparently the case in your project -- by don't know Ada here, I mean
        >that you do not bother to carefully study the definition of the language),
        >then you definitely CANNOT write portable code in Ada.

        >If anyone ever promised you that using an Ada compiler would guarantee that
        >your programs they were an ignorant fool, and it surprises me that anyone
        >would believe such nonsense. Certainly you never heard anything of the kind
        >from anyone who knew anything about the language!

        ><<Well, too many people failed to make it work for #3 to be a likely cause,
        >  and the compilers of the day are known to have been a work in progress.

        >  This has degenerated into a pointless yes-you-did, no-I-didn't cycle.
        >  Suffice it to say that we disagree on a minor issue too far in the past to
        >  remember the details clearly enough to have a useful debate, assuming of
        >  course that the limitations of 1980s compilers have any relevance
        >  whatsoever in the 1990s.>>

        >I have NO clear idea what you did or didn't do. You made certain claims in
        >your original post, and I was interested to see if you could substantiate
        >them. It seems that really you can't, which I don't find too surprising,
        >because they did not make much sense to me. But I did not want to jump to
        >that conclusion, which is why I was trying to find out more details.

        > [snip}

        >No, you did not read carefully. Ada 95 absolutely DOES require programmers
        >to provide intermediate precision precisely. It is just that in certain
        >cases, this can be implicit in Ada 95. For example

        >   x := y(A * B) + y(C * D);

        >the conversions to type y here, specifying the intermediate scale and
        >precision are required in Ada 83 and Ada 95, and those are the important
        >cases. The case which has changed is relatively unimportant:

        >   x := y(A * B);

        >Ada 83 required the explicit conversion here, but since the most likely case
        >is that y is the type of x, Ada 95 allows a shorthand IN THIS SITUATION ONLY
        >of leaving out the type conversion.

        >So it is not at all the case that Ada83 should be able to handle fixed point
        >arithmetic automatically. Neither Ada 83 nor Ada 95 attempts this. As I noted,
        >PL/1 tried, but most people (not all, Robin characteristically dissents :-)
        >would agree that the attempt was a failure, for example the rule that requires

        >   22 + 5/3

        >to overflow in PL/1, where

        >   22 + 05/3

        >succeeds, is hardly a masterpiece of programming language
        >design,

Do you have something better?

This silly example has been bandied about on quite a few
occasions in cases like this so "show" that the conversion
rules for fixed-point working in PL/I are silly or not
optimum.

In fact, what you are doing is adding two very large nunmbers,
both of which are at the capacity of the decimal arithmetic
unit.

i.e. You are asking, what is 25.00000000000000 + 1.33333333333333 ?
on a machine with 15 digits of precision.

Of course it will overflow.  That's the nature of fixed-point
working.

so as to have at least one fewer digits after the point. (there's
a standard function for this.)
nd BTW, PL/I detects the overflow, should it occur,
and tells you.

        > but to be fair, PL/1 was really trying to solve an
        >impossible problem, so it is not surprising that its
        >solution has glitches. Indeed the reason that 22 + 5/3
        >overflows bears looking at, since it is a nice example
        >of good decisions
        >combining to have unintended consequences.

        >Question 1: What should be the precision of A/B?
        >Answer: The maximum precision possible guaranteeing no overflow.

        >Question 2: What happens when two numbers with different scales are added?
        >Answer: One is shifted left to line up decimal points (we do not want to
        >         lose pennies!)

        >Now 5/3 is a case of one digit divided by one digit, which can have at most
        >one digit before the decimal point (for the case of 9/1), so the result is

        >   1.6666666666666666666666666667

Pl/I doesn't round up.

        >Where by definition the number of digits is the maximum number of digits that
        >can be handled.

        >Now we add the 22 and

        >   1.6666666666666666666666666667
        >  22.0000000000000000000000000000

        >oops, the 2 fell out the left hand side.
        >But if the literal is 05 (with a leading zero), then it is two digits, and we
        >get:

        >  01.666666666666666666666666667
        >  22.000000000000000000000000000

        >It is really hard to get these rules to behave well without anomolies of this
        >type. To my taste no one has succeeded, and the decision in Ada 83 and Ada 95
        >to make the programmer specify intermediate precision and scaling seems
        >exactly right.

        ><<But, the compilers we used in those days couldn't get it *exactly* right,
        >  so we didn't use fixed point arithmetic in Ada83.>>

        >There goes that claim again, but we still have seen no evidence or data to
        >back up this claim, other than "that must have been it, otherwise we would
        >not have thought it was the case". NOT very convincing!

        >Incidentally, if you want to read more about fixed-point issues in Ada,
        >a good starting point is the special issues report on Ada fixed-point
        >that I did for the Ada 9X project.



Sun, 21 May 2000 03:00:00 GMT  
 fixed point vs floating point

Robin says

<<Rubbish.  If evaluation of this expression fails, it
is because of exceeding the capacity of the fixed-point
multiplier.  It has -- incidentally -- nothing to do
with the division.

The above is the WRONG way to compute an expression
using fixed-point facilities.

You would write it x = (y * V1) / V3;

No that's quite wrong, the fixed point expressions

   y * (V1 / V3)

and

   (y * V1) / V3

are quite different expressions (to substitute one for the other, for
example in the computation of interest in a bond, would not only be
an error, but might actually be a violation of the law, since the
details of such calculations are often contained in the bond instruments
and mandated).

These two expressions give quite different values, it is wrong to say
that one is right and one is wrong. Which one is right depends on the
problem at hand, and the intermediate precision required in both cases
must be carefully controlled.

I can easily see how the fixed-point facilities in PL/1 would seduce
PL/1 enthusiasts into such errors. It is one of the reasons that the
fixed-point design in PL/1 is generally considered a failure. Please
note I am talking a very specific language design point here. I quite
realize that most language designers consider the whole of PL/1 a
dismal failure, but I don't go that far, PL/1 is not nearly as bad
as its reputation, but it did make a number of serious mistakes,
and the fixed-point design was one of them.



Sun, 21 May 2000 03:00:00 GMT  
 fixed point vs floating point

Quote:

>I quite
>realize that most language designers consider the whole of PL/1 a
>dismal failure, but I don't go that far, PL/1 is not nearly as bad
>as its reputation, but it did make a number of serious mistakes,
>and the fixed-point design was one of them.

Very interesting; a few questions:
1. Why do they "consider the whole of PL/1 a dismal failure"?
2. What do you consider the serious mistakes, apart from the one you mention?
3. Which imperative language do  most language designers consider a success?

Bill Rowe



Sun, 21 May 2000 03:00:00 GMT  
 fixed point vs floating point

Quote:

> 3. Which imperative language do  most language designers consider a success?

The design they're currently working on, of course ;-)

From a non-language designers point of view I would suggest the whole
philosophy of type conversions in expression evaluation is a trouble
spot.  I usually have to break up complex expressions to get the
"expected" results.



Mon, 22 May 2000 03:00:00 GMT  
 fixed point vs floating point

Quote:


>> 3. Which imperative language do  most language designers consider a
>success?

>The design they're currently working on, of course ;-)

>From a non-language designers point of view I would suggest the whole
>philosophy of type conversions in expression evaluation is a trouble
>spot.  I usually have to break up complex expressions to get the
>"expected" results

This belongs to a subset of language faults that fall into the "things to
avoid" category. I would add to this implicit defintions of variables, label
variables and highly-nested procedures. These superficially do not appear to be
major faults in the language because you can keep them out of your own code;
but the working programmer is often (and very often in PL/I) working with
somebody else's code, and, as we all know, other programmers are not as prudent
and far-sighted as we are. If the language offers the opportunity to make a
hash of things, someone will seize it. It is for that reason that these
characteristcs are not minor flaws.

Bill Rowe.



Mon, 22 May 2000 03:00:00 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. fixed point vs floating point

2. fixed point vs floating point

3. Floating Point vs Fixed Point

4. code with fixed-point or floating-point

5. fixed point vs floating point (When do you use it ?)

6. floating vs. fixed point

7. An alternative to floating point (was Re: Floating point non-exactness)

8. IBM 370 Floating point to IEEE floating point

9. fixed point vs fixed decimal

10. Bug fix to floating point emulation.

11. Fixed or Floating point for MP3 algorithim?

12. Fixed or floating point?

 

 
Powered by phpBB® Forum Software