On Wed, Mar 6, 2013 at 9:13 PM, David Rowe <da...@rowetel.com> wrote:
> So yes those sorts of macros are certainly one way to go...Can't help
>
feeling their might be a better way though .......
>
One thing I like about the macro approach is that for targets with FPU they
can collapse into normal floating point operations. Maintaining only one
implementation of the algorithms is definitely a good thing. But the way
they obscure the intent is a pretty high price to pay.
I am not sure I can completely justify it, but my tendency would be to to
use C++ classes to represent the numeric values. If the variables were
declared using typedefs, it would be easy to control whether they used
native float/double or the C++ classes. Naturally a C++ compiler would be
needed to use the classes, but I don't think it would be too hard to make
the source also compile as C when using the native floats/doubles.
The big advantage of using C++ classes for numeric values is their support
for operator overloading. The algorithm code could potentially stay
exactly as it is now, with only the variable declarations changing to use
the typedefs. The typedefs could select C++ classes with a variety of
characteristics and capabilities:
* Do normal float/double math but instrument the min/max values
* Implement fixed point math for a certain format (Q13.3, etc)
* Implement automatic conversions between formats (from Q13.3 to Q10.6,
for example)
* Implement saturation arithmetic
The missing piece, which might require some changes to the algorithm
source, would be handling the datatype for intermediate values and the
order of calculations to prevent excessive rounding. Consider these
different ways of computing the average:
SignedQ10_6_t w(500.123);
SignedQ10_6_t x(-275.321);
SignedQ10_6_t y(56.234);
SignedQ10_6_t z(-85.232);
// Calculate the average of w, x, y and z several different ways:
SignedQ10_6_t ave1 = ( w + x + y + z ) / 4;
SignedQ10_6_t ave2 = ( ( ( w + x ) / 2 ) + ( ( y + z ) / 2 ) ) / 2;
SignedQ10_6_t ave3 = ( ( w / 4 ) + ( x / 4 ) + ( y / 4 ) + ( z / 4 ) );
SignedQ26_6_t sum;
SignedQ26_6_t ave_temp;
SignedQ10_6_t ave4;
sum = w;
sum += x;
sum += y;
sum += z;
ave_temp = sum / 4;
ave4 = ave_temp; // automatic type conversion equivalent to
// static_cast<SignedQ10_6_t>( ave_temp );
Unless I made a mistake, each of the methods of computing the average would
give the same result when using floats (within rounding error), but would
round/overflow differently when using fixed point numbers. Even if the
source did need to be somewhat rearranged, have temporaries inserted, etc,
the code for the algorithm is still separated from the scaling information
(implicit in the datatypes), which makes the algorithms easier to read than
when the two are interwoven as with macros.
Steve
--
Steve Strobel
Link Communications, Inc.
1035 Cerise Rd
Billings, MT 59101-7378
(406) 245-5002 ext 102
(406) 245-4889 (fax)
WWW: http://www.link-comm.com
MailTo:steve.stro...@link-comm.com
------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
Freetel-codec2 mailing list
Freetel-codec2@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freetel-codec2