19

I have a 16 bit fixed point processor and I want to do fixed point processing with it. I'm looking for the correct datatype to use for unsigned 16 bit ints..

My question is: what is the difference between a uint16_t and uint_fast16_t? (These are included in the stdint.h.) Is uint_fast16_t better since it is faster??

Thanks!!

hlovdal
  • 26,565
  • 10
  • 94
  • 165
O_O
  • 4,397
  • 18
  • 54
  • 69

2 Answers2

19

uint16_t is an unsigned 16-bit integer. uint_fast16_t is the fastest available unsigned integer with at least 16 bits.

Sven
  • 22,475
  • 4
  • 52
  • 71
  • 14
    Answer would be more helpful if you could define "fastest." – Chris Tonkinson Feb 10 '11 at 19:47
  • 4
    Never mind: "The standard does not mandate anything about these types except that their widths must be greater than or equal to N. It also leaves it up to the implementor to decide what it means to be a "fast" integer type." – Chris Tonkinson Feb 10 '11 at 19:48
  • Interesting... it strikes me odd that this datatype doesn't have a size specified.. it is up to the user.. o_o so would doing sizeof() to this datatype result in an error? In any case, I don't think uint_fast16_t would apply to me. I'll just stick to the uint16_t as my datatype for fixed point arithmetic. :) Thanks... – O_O Feb 10 '11 at 20:01
  • 3
    On a 32-bit or greater system, a 16-bit integer may be slower than a 32-bit integer because of the way memory addresses are accessed. I found this on a 32-bit system implementing a fixed-point CORDIC algorithm; using *int* proved to be faster than *short int*, even when the algorithm processed only 16 bits. On O_O's undefined 16-bit processor, I would imagine that there would be no difference between unint16_t and uint_fast16_t, but if the code were ported to a 32 or 64-bit system there may be a big difference. – oosterwal Feb 10 '11 at 20:06
  • 3
    @O_O "it strikes me odd that this datatype doesn't have a size specified" -- its size is >= 16 bits. "it is up to the user" -- no idea what you mean by that; it's up to the *implementation*. "so would doing sizeof() to this datatype result in an error?" -- No, of course not; uint_fast16_t is just a typedef, to either uint16_t or uint32_t. "In any case, I don't think uint_fast16_t would apply to me. I'll just stick to the uint16_t as my datatype for fixed point arithmetic" -- that's fine if you don't care whether your program is fast, and just care about memory usage. – Jim Balter Feb 11 '11 at 04:33
  • @ChrisTonkinson Better late than never: When using e.g. the "uint16_t" type for local variables such as loop counters, this implicitly requests 16bit overflow behavior, requiring the truncating after each calculation, even though the overflow may actually never happen. Because the truncation does not need to be done/checked, a 32bit variable is faster on a lot of platforms such as ARM32. It just requires less computations. – MrD Sep 04 '20 at 08:37
10

uint16_t is more restrictive than uint_fast16_t and uint_least16_t. Not only that the later two may be wider than 16 bits, they may also have padding bits (bits that don't account for the value such as parity bits).

This difference is even more pronounced for the signed types. Here the exact width types must use the two's complement to represent negative values.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • Does that mean any non-two's complement system can't have the optional `uint16_t` version? – user16217248 May 07 '23 at 19:13
  • @user16217248 yes, such a theoretical system can't have that. That said, there seem to be no such platforms out there anymore, so starting with C23 all signed integer types will have to use two's complement. The definitions for these types in the standard then also become a bit simpler. – Jens Gustedt May 09 '23 at 11:43