13

Thankfully, the complex type modifier was introduced into C99 standard. What I don't understand is why it was decided to omit support for fixed point arithmetic (specifically, support fractional types like 1.15 {signed} or 0.32 {unsigned}) where these types are so fundamental to DSP programming?

Does GCC support these through an extension?

ysap
  • 7,723
  • 7
  • 59
  • 122
  • 3
    Fixed point types are the same as integers, right? – Carl Norum Mar 27 '12 at 04:52
  • 2
    @CarlNorum: not really; they are scaled a bit like integers, but when you multiply two numbers, you also end up shifting the result. – Jonathan Leffler Mar 27 '12 at 04:54
  • 3
    @CarlNorum - Integers are a subset of fixed-point numbers, where the binary point is to the right of the lsb. In general, you can place the point wherever in your register, but you have to maintain consistency along arithmetic operators. – ysap Mar 27 '12 at 04:54
  • 3
    @CarlNorum - for eaxmple, if you have numbers in the format signed 1.15 (one bit left the binary point and 15 bits to its right), then using integer multiplication will give 2.30 result. You then must shift it left 1 position and truncate the lower 16 bits to return to the 1.15 format. – ysap Mar 27 '12 at 04:58
  • 2
    Most of us would call that shifting the result right 15 bits.. :-) – R.. GitHub STOP HELPING ICE Mar 27 '12 at 05:04
  • 3
    @R.. - the end result may be the same, but the devil is in the details: first, if the result is signed, then you may end up with 15 leading 1's. Secondly, technically, you don't *shift* the result to the right, you are *discarding* the lower half of the word to get your original numeric format. – ysap Mar 27 '12 at 05:18
  • A 1.15 value sounds rather unsigned to me... In any case, if you prefer you can call it dividing the result by 32768. – R.. GitHub STOP HELPING ICE Mar 27 '12 at 06:02
  • 3
    @R.. - the 1.15 is the standard representation for signed 16-bit fractionals. The leading 1 has a weight of (-1), just as the msb of a signed integer has a negative weight. Thus, 0x8000 represents the value (-1), while 0x7fff represents the value 0.999... (more or less). Similarly, 0x4000 is 0.5, 0x2000 is 0.25 and 0xc000 is -0.5. – ysap Mar 27 '12 at 13:07
  • 2
    At the same time, 0.16 is the standard for unsigned fractionals, where 0x8000 is 0.5, 0xffff is 0.999... etc. – ysap Mar 27 '12 at 13:07
  • Why not parameterise all numerical data types - signed/unsigned, significand size, exponent size, exponent bias? An integer has an exponent size of zero and exponent bias of zero. A fixed-point number has an exponent size of zero and a non-zero exponent bias. Floating point has non-zero exponent size and non-zero exponent bias. – Brendan Jun 27 '14 at 01:27

3 Answers3

13

It's been discussed/proposed (e.g., in N938, N953) but those papers have only proposed it as extensions, not additions to the main standard. Those seem to have led to its inclusion in N1169, which is a draft of TR 18037 ("Extensions to support embedded processors"), but that isn't considered complete (and the draft doesn't seem to have been updated in quite a while).

My guess (though it's only a guess) is that work on it probably got dropped (at least temporarily) to concentrate on finishing C11. Whether work on it will resume now will probably depend on whether there are still people around who still care. Writing and submitting a paper based on those earlier ones that covers more detail, provides more supporting evidence, etc., might help to get it back in motion again (though I obviously can't guarantee anything).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • 2
    FYI, in April of 2016 I was in contact with David Keaton, convener for WG14. His reply then with regard to the status of TR18037 an N1169 is as follows: "... At this time, we do not have any plans to add TR 18037 into the C standard. However, we have noticed that the TR is definitely being used in the industry, and we plan to keep it available. ..." – Toby Apr 27 '17 at 11:28
12

To address the question 'Does GCC support these through an extension', we can quote from 'Using the GNU Compiler Collection' (for GCC version 4.4.0 — bullet points added to clarify). (The GCC 4.9.0 URL equivalent is Fixed Point — Using the GNU Compiler Collection (GCC), but the section is 6.15 instead of 5.13.)

§5.13 Fixed-Point Types

As an extension, the GNU C compiler supports fixed-point types as defined in the N1169 draft of ISO/IEC DTR 18037. Support for fixed-point types in GCC will evolve as the draft technical report changes. Calling conventions for any target might also change. Not all targets support fixed-point types.

The fixed-point types are:

  • short _Fract, _Fract, long _Fract, long long _Fract,
  • unsigned short _Fract, unsigned _Fract, unsigned long _Fract, unsigned long long _Fract,
  • _Sat short _Fract, _Sat _Fract, _Sat long _Fract, _Sat long long _Fract,
  • _Sat unsigned short _Fract, _Sat unsigned _Fract, _Sat unsigned long _Fract, _Sat unsigned long long _Fract,
  • short _Accum, _Accum, long _Accum, long long _Accum,
  • unsigned short _Accum, unsigned _Accum, unsigned long _Accum, unsigned long long _Accum,
  • _Sat short _Accum, _Sat _Accum, _Sat long _Accum, _Sat long long _Accum,
  • _Sat unsigned short _Accum, _Sat unsigned _Accum, _Sat unsigned long _Accum, _Sat unsigned long long _Accum.

Fixed-point data values contain fractional and optional integral parts. The format of fixed-point data varies and depends on the target machine.

You can find the text of the draft proposal here.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Note that this was excluded from standardization in C11 (and was not included in C99 either but I doubt it had even been designed at that point). So while it might be practically useful to OP, I don't think it answers the question of why it wasn't included. – R.. GitHub STOP HELPING ICE Mar 27 '12 at 05:02
  • 3
    But it does answer the last question: Does GCC support them? – Jonathan Leffler Mar 27 '12 at 05:03
  • Kind-of supports, but it depends on platform. In particular, GCC does not seem to support fixed point types for x86 or x86_64. – jpa Jan 07 '20 at 20:16
-1

Like Carl said in the comment, fixed-point is really exactly the same thing as integer. I suppose the language could have added a feature to do the scaling for you after mult/div (this would be on about the same level as pointer-to-VLA types: cleaning up the syntax by hiding scaling arithmetic for you) but considering the diverse range of scales and mix of types (e.g. fixed 8.24 times fixed 24.8, or fixed times integer) people want to use with fixed-point, it would be really hard to cover it all well.

Another major issue is the distinction of purpose. Fixed point is almost always a hack for speed at the expense of correctness (and as such it's much easier to roll your own). Floating point arithmetic, including the new complex support in C99, is for when you want rigorous results with known error bounds, safety from false overflows, etc. C99 complex support does a lot more for you than just FOIL'ing your complex binomials for you. It hides all the heavy work involved in making sure your results don't get trashed by corner cases.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 5
    Sorry, but I have to disagree here. It is *not* exactly the same as integer. See my comment to carl. You are right that there are many possible combinations, but in the realm of DSP's the two dominant are integers and fractionals (with the nuance of signed vs unsigned fractionals - 1.15 vs 0.16). – ysap Mar 27 '12 at 05:09
  • 4
    In the general sense, you could argue that it is a hack for speed, but in reality, it may be that a processor supports just these types natively - no FP in hardware, so it really maps the C code to the underlying hardware. Also FP is not always more accurate than fixed-point arithmetic. If the exponent of your intermediate results is relatively constant, then for a given word length you actually have more precision using fixed point arithmetic. – ysap Mar 27 '12 at 05:11
  • 8
    Fixed point is also for the case where you want the same absolute precision over the range of values you're interested in (classic example: lat/long). – caf Mar 27 '12 at 10:06
  • 3
    In my opinion, your arguments speak *for* the inclusion in the language, rather than against it. Handling all that shifting correctly is something that should be automated, and *not* something which the programmer has to worry about, because that's how bugs are made! And, contrary to what you say, automating it is rather easy as long the compiler knows the widths of the fractional and integer parts. – Fritz May 29 '15 at 15:26
  • 1
    @Fritz: Fixed-point types whose sizes weren't standardized would be pretty useless. Fixed-point sizes whose sizes were standardized might be nice, but should probably be a lower priority than wrapping unsigned integer types whose sizes are standardized, such that `wrap16_t x=65535; x*=x;` would be guaranteed to set `x` to 1 independent of the size of `int`. – supercat Jul 25 '15 at 21:41