Talk:Q (number format)

From Wikipedia, the free encyclopedia
Jump to: navigation, search
WikiProject Computer science  
WikiProject icon This article is within the scope of WikiProject Computer science, a collaborative effort to improve the coverage of Computer science related articles on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
 ???  This article has not yet received a rating on the project's quality scale.
 ???  This article has not yet received a rating on the project's importance scale.

Article needs more work[edit]

It needs more work; the introduction assumes too much knowledge. The Q number does not carry the field size. Q numbers get used even if the processor has a floating point unit. Another day. Charles Esson 23:04, 8 April 2007 (UTC)

Original research?[edit]

I think this was invented by TI; but we need a reference to say it.Charles Esson 11:52, 10 April 2007 (UTC)

Actually we need a reference to prove that that "Q number format" is an established name for binary fixed-point. In any case, I wholly support the merge into binary scaling. I would even merge both articles into fixed-point arithmetic, according to the proposal in Talk:fixed-point arithmetic. --Jorge Stolfi (talk) 18:34, 24 June 2009 (UTC)

Notation description is misleading[edit]

The article states for the Qm.n format:

m is the number of bits set aside to designate the two's complement integer portion of the number, exclusive of the sign bit (therefore if m is not specified it is taken as zero).

This might be true for Texas Instruments (among others), but they are not the only ones using this notation. ARM, in their CMSIS (vendor-independent hardware-abstraction layer for ARM-Cortex devices, see, have e.g. Q31 numbers ("q31_t" in C) and describe them as "32-bit fractional data type in 1.31 format" (actually a mix between "Qf" and "s.f" notation). IMHO the article implies that there are several common notations for fixed-point numbers, but in reality there is basically a custom notation for every other vendor, and those notations often conflict/are ambiguous. The article should reflect this by explicitly mentioning *which* vendors us a described notation, and should make clear that there are other notations in use which are not described (discuss! I'll change this if no one is opposed). 2001:4CA0:0:F221:D194:90F0:4D26:25AE (talk) 17:45, 14 January 2013 (UTC)

Range Error in Article[edit]

I dispute the following statement in the article:

For a given Q format, using an N-bit signed integer container with Q fractional bits:

  • Its range is [-2N-1-Q, 2N-1-Q-1]

A common usage is storing a Q15 value in a 16-bit signed integer object, so we have N=16 and Q=15. According to the article, the range would be [-216-1-15, 216-1-15-1] or [-20, 20-1] or [-1, 0] which, of course, is incorrect. The correct range is [-1, 0.99996948]. —Ksn 21:05, 16 April 2007 (UTC)

  • It is my view ( not worth much); your both right in a way. I think the article ( or at least the formula) is referring to the integer range. Your referring to the real range. I wonder what to do about it, cause your right it is not clear.Charles Esson 08:47, 18 April 2007 (UTC)
  • I added integer for now, but I think your right it has to be fixed. Charles Esson 08:54, 18 April 2007 (UTC)
  • Fixed it.Charles Esson 09:24, 18 April 2007 (UTC)

Thanx for the fix. It didn't make much sense to present the range in terms of integers when the point of the Q format is to express real numbers. —Ksn 00:02, 20 April 2007 (UTC)

Why does 2's complement refer to a "sign bit"? It is a misnomer. Sign-and-magnitude numbers have a "sign bit", and the sign bit has no magnitude...only sign. The most-significant bit in 2's complement with bit indices [n:m] has place value -2n. The n in Qn.m notation refers to the number of integer bits exclusive of the sign bit. Radix complement numbers [1] do not have a sign bit. The MSB connotes both the sign information AND MAGNITUDE, namely -2n. Therefore, it is misleading to say that a Q0.15 number has no integer bits. It has one integer bit that represents either 0 or negative 1, and should, therefore, be denoted as Q1.15, despite how (I believe) it is currently used. Chelmite (User:Steve_Kelem) 21:20, 2 November 2011 (UTC)

Proposal to Dereference Referenced Paper[edit]

I propose that the external link to the paper Fixed Point Representation And Fractional Math be removed as it is not authoritative and contains errors, for example:

  • p. 2, after talking about using two's complement format it gives an example of an 8-bit value being specified as Q3.5, which does not accommodate the sign bit.
  • p. 2, it asserts that a C "int" is 16 bits, contrary to its actual definition; furthermore, int's are increasingly implemented as 32 bits.
  • p. 3, it gives the incorrect inequality "0 ≤ a ≤ 2QI", where the second "≤" should be "<".
  • p. 3, the equation "QI = ceiling(log2(abs(a)))" is incorrect for the same edge condition.
  • P. 3, it then presents different formulae when discussing the impact of signed numbers, but no change is necessary because QI is defined as being the number of integer bits, which implies not including the sign bit.

I didn't see the need to review the document further. —Ksn 13:56, 20 April 2007 (UTC)

  • I haven't read the document but I agree with your points.Charles Esson 06:08, 25 April 2007 (UTC)

These issues appear to have been addressed in a new release of the referenced paper User:anonymous —Preceding unsigned comment added by (talk) 21:48, 30 August 2007 (UTC)

Using m and n instead of Q in the Math section; mixed fractional sizes in multiplication and division.[edit]

I've changed the first half of the article to uniformly use m and n (for a Qm.n format) instead of introducing Q and N variables. I think the math section that follows should follow suit, but I disagree with the statement that multiplication and division require the number of fractional digits in the dividend to be the same. Multiplying a Qa.b format number by a Qc.d format number can be done naturally by treating the Q format numbers as signed integers, and it will generally give a Qa+c.b+d format number. Division I'm not as sure about; I expect that Knuth's The Art of Computer Programming Volume 2 would have all the answers. Wdfarmer 04:06, 25 April 2007 (UTC)

  • If you don't keep the fractional digits the same then you change the type of Q number you are dealing with (as you have pointed out). Lets say you have Q14.17 by Q14.17, you end up with Q28.34, bit hard to fit it in a 32 bit register. If you don't fix up your base the division result is the different Q number(Qa-c.b-c); not the same Q number once again. Now if you going to change Q number type with multiplication and division than the statement 'resolution is constant' is wrong, resolution is only constant if you maintain the Q number type. What I have provided is a consistent set of operators that maintain the Q number type you start with and highlighted the need for rounding care. I think that is a lot more helpful than saying something along the line "If you don't fix you base the number will underflow or overflow". Charles Esson 06:04, 25 April 2007 (UTC)
  • Altered article to reflect your concern; there probable should be another section on treating m and n as indexes.Charles Esson 06:38, 25 April 2007 (UTC)

C sample code[edit]

There are more problems here than there are lines of code. I suspect it was written by someone who doesn't actually write C. Here are the issues, in descending severity:

  • Q is not defined anywhere in the code, so this won't compile.
  • The code is not valid C89, because it uses C++-style (//) comments. It may be valid C99, or C++, or C89 plus Microsoft or gcc extensions, but when people say "C" they generally mean C89.
  • If the code is meant to be C99, C++, VC, or gcc code, it's not idiomatic; variables should be declared at initialization rather than all together at the top.
  • The comment "2**(Q-1)" isn't going to help a C programmer, as there is no ** exponentiation operator in C.
  • K is clearly meant to be a constant. So, why not define it as such? Or, even better, give it a name?
  • You're allowed to give variables names longer than one letter.

Here's a suggestion:

static const short Q15_N = 15; /* fractional bits, n in a Q15 or Qm.15 format */

short Q15_add(short a, short b) {
  return a+b;

short Q15_subtract(short a, short b) {
  return a-b;

short Q15_multiply(short a, short b) {
  /* Rounding: mid values are rounded up */
  static const short Q15_ONE_HALF = 1 << (Q15_N - 1);
  long resultTimes2N = (long)a * b + Q15_ONE_HALF;
  /* Correct by dividing by base */
  return (short)(resultTimes2N >> Q15_N);

short Q15_divide(short a, short b) {
  /* pre-multiply by the base */
  long aTimes2N = (long)a << Q15_N;
  /* So the result will be rounded; mid values are rounded up */
  long roundedATimes2N = aTimes2N + b/2;
  return (short)(roundedATimes2N / b);

This still isn't really safe, as short isn't guaranteed to be smaller than long--but I can't think of any platforms where it isn't. (If you're worried, #if sizeof(short) == sizeof(long) #error "Wow!" #endif...) -- 11:28, 28 July 2007 (UTC)

It wouldn't be compliant with C89, but you could use the C99 types defined in stdint.h: int16_t, int32_t, et cetera, to make sure your variables had the desired length. -- (talk) 14:23, 15 January 2009 (UTC)

Still not compliant, because:

  • Signed bit shift is implementation-defined and might produce wrong results depending on the compiler and optimization options. Division by power of two is portable and automatically causes truncation. Multiplication by power of two is also portable as long as signed overflow cannot happen.
  • Rounding up (ceil) tends to break algorithms defined on real numbers - they are designed with round-to-nearest in mind. It will especially break statistics by introducing bias. See the page on Rounding. Truncation is better though still not ideal.

--AstralStorm (talk) 12:48, 27 October 2014 (UTC)

  1. ^ Digital Systems and Hardware/Firmware Algorithms, Ercegovac and Lang 1985