Fixed-point arithmetic: Difference between revisions

Content deleted Content added
Applications: Describe evaluation order using link to Horner's method, use {{math}} for equation, reverse order of polynomial to avoid {{math}} and prose close parentheses being adjacent. rm "DCT" and "BAM" initialisms, as they're not used anywhere else in article.
m unpiped links using script
Line 5:
{{Use list-defined references|date=December 2022}}
 
In [[computing]], '''fixed-point''' is a method of representing [[fraction (mathematics)|fractional]] (non-integer) numbers by storing a fixed number of digits of their fractional part. [[US dollar|Dollar]] amounts, for example, are often stored with exactly two fractional digits, representing the [[cent (currency)|cents]] (1/100 of dollar). More generally, the term may refer to representing fractional values as integer multiples of some fixed small unit, e.g. a fractional amount of hours as an integer multiple of ten-minute intervals. Fixed-point number representation is often contrasted to the more complicated and computationally demanding [[floating-point arithmetic|floating-pointrepresentation]] representation.
 
In the fixed-point representation, the fraction is often expressed in the same [[radix|number base]] as the integer part, but using negative [[exponentiation|powers]] of the base ''b''. The most common variants are [[decimal]] (base 10) and [[binary number|binary]] (base 2). The latter is commonly known also as '''binary scaling'''. Thus, if ''n'' fraction digits are stored, the value will always be an integer [[multiple (mathematics)|multiple]] of ''b''<sup>−''n''</sup>. Fixed-point representation can also be used to omit the low-order digits of integer values, e.g. when representing large dollar values as multiples of $1000.
 
When decimal fixed-point numbers are displayed for human reading, the fraction digits are usually separated from those of the integer part by a [[decimal separator|radix character]] (usually '.' in English, but ',' or some other symbol in many other languages). Internally, however, there is no separation, and the distinction between the two groups of digits is defined only by the programs that handle such numbers.
 
Fixed-point representation was the norm in [[mechanical calculator]]s. Since most modern [[centralProcessor processing unit(computing)|processors]] have fast [[floating-point unit]] (FPU), fixed-point representations in processor-based implementations are now used only in special situations, such as in low-cost [[embedded system|embedded]] [[microprocessor]]s and [[microcontroller]]s; in applications that demand high speed or low [[electric power|power]] consumption or small [[integrated circuit|chip]] area, like [[image processing|image]], [[video processing|video]], and [[digital signal processing]]; or when their use is more natural for the problem. Examples of the latter are [[accounting]] of dollar amounts, when fractions of cents must be rounded to whole cents in strictly prescribed ways; and the evaluation of [[function (mathematics)|functions]] by [[lookup table|table lookup]], or any application where rational numbers need to be represented without rounding errors (which fixed-point does but floating-point cannot). Fixed-point representation is still the norm for [[field-programmable gate array]] (FPGA) implementations, as floating-point support in an FPGA requires significantly more resources than fixed-point support.<ref name="Wong_2017"/>
 
==Representation==
Line 44:
===Choice of scaling factors===
 
For greater efficiency, scaling factors are often chosen to be [[exponentiation|powers]] (positive or negative) of the base ''b'' used to represent the integers internally. However, often the best scaling factor is dictated by the application. Thus one often uses scaling factors that are powers of 10 (e.g. 1/100 for dollar values), for human convenience, even when the integers are represented internally in binary. Decimal scaling factors also mesh well with the [[International System of Units|metric (SI) system]], since the choice of the fixed-point scaling factor is often equivalent to the choice of a unit of measure (like [[centimetre]]s or [[micrometers|microns]] instead of [[metre]]s).
 
However, other scaling factors may be used occasionally, e.g. a fractional amount of hours may be represented as an integer number of seconds; that is, as a fixed-point number with scale factor of 1/3600.
Line 79:
Similarly, any decimal fraction ''a''/10<sup>''m''</sup>, such as 1/100 or 37/1000, can be exactly represented in fixed point with a power-of-ten scaling factor 1/10<sup>''n''</sup> with any ''n'' ≥ ''m''. This decimal format can also represent any binary fraction ''a''/2<sup>''m''</sup>, such as 1/8 (0.125) or 17/32 (0.53125).
 
More generally, a [[rational number]] ''a''/''b'', with ''a'' and ''b'' [[coprime integers|relatively prime]] and ''b'' positive, can be exactly represented in binary fixed point only if ''b'' is a power of 2; and in decimal fixed point only if ''b'' has no [[prime number|prime]] factors other than 2 and/or 5.
 
===Comparison with floating-point===
Line 170:
 
==Computer language support==
Explicit support for fixed-point numbers is provided by a few computer languages, notably [[PL/I]], [[COBOL]], [[Ada programming language|Ada]], [[JOVIAL programming language|JOVIAL]], and [[Coral 66]]. They provide fixed-point [[data type]]s, with a binary or decimal scaling factor. The compiler automatically generates code to do the appropriate scaling conversions when doing operations on these data-types, when reading or writing variables, or when converting the values to other data types such as floating-point.
 
Most of those languages were designed between 1955 and 1990. More modern languages usually do not offer any fixed-point data types or support for scaling factor conversion. That is also the case for several older languages that are still very popular, like [[FORTRAN]], [[C (programming language)|C]] and [[C++]]. The wide availability of fast floating-point processors, with strictly standardized behavior, have greatly reduced the demand for binary fixed point support.{{cn|date=October 2021}} Similarly, the support for [[decimal floating point]] in some programming languages, like [[C Sharp language|C#]] and [[Python (programming language)|Python]], has removed most of the need for decimal fixed-point support. In the few situations that call for fixed-point operations, they can be implemented by the programmer, with explicit scaling conversion, in any programming language.
Line 234:
* The notation {{mono|B}}''m'' has been used<!--BY WHO?--> to mean a fixed binary format with ''m'' bits in the integer part; the rest of the word being fraction bits. For example, the maximum and minimum values that can be stored in a signed {{mono|B16}} number are ≈32767.9999847 and −32768.0, respectively.
* The [[VisSim]] company used {{mono|fx}}''m''{{mono|.}}''b'' to denote a binary fixed-point value with ''b'' total bits and ''m'' bits in the integer part; that is, a ''b''-bit integer with scaling factor 1/2<sup>''b''−''m''</sup>. Thus {{mono|fx1.16}} would mean a 16-bit number with 1 bit in the integer part and 15 in the fraction.<ref name="vsi"/>
* The [[PlayStation 2|PS2]] GS ([[PlayStation 2 technical specifications#Graphics processing unit|"Graphics Synthesizer"]]) User's Guide uses the notation ''s''{{mono|:}}''m''{{mono|:}}''f'', where ''s'' specifies the presence (0 or 1) of sign bit.<ref name="PS2"/> For example, {{mono|0:5:3}} represents an unsigned 8-bit integer with a scaling factor of 1/2<sup>3</sup>.
* The [[LabVIEW]] programming language uses the notation {{mono|<}}''s''{{mono|,}}''b''{{mono|,}}''m''{{mono|>}} to specify the parameters of an 'FXP' fixed point numbers. The ''s'' component can be either '+' or '±', signifying either an unsigned or 2's complement signed number, respectively. The ''b'' component is the total number of bits, and ''m'' is the number of bits in the integer part.
 
==Software application examples==
* The popular [[TrueType]] font format uses 32-bit signed binary fixed-point with 26 bits to the left of the decimal for some numeric values in its instructions.<ref name="TTS"/> This format was chosen to provide the minimal amount of precision required for [[Font hinting|hinting]] and for performance reasons.<ref name="Freetype"/>
* With the exception of the [[Nintendo 64]], all 3D games for the [[fifth generation of video game consoles]], including the [[3DO Interactive Multiplayer]], [[PlayStation]], [[Sega Saturn|Saturn]], and [[Atari Jaguar|Jaguar]]<ref name="Dolphin_2014"/> use fixed-point arithmetic, as the systems lack hardware floating-point units. The PlayStation transformation coprocessor supports 16-bit fixed point with 12 fraction bits - whereas the Sega Saturn VDP coprocessors used a 32-bit fixed point format reserving the lower 16 bits for the fractional part.
* The [[TeX]] typesetting software, widely used by scientists and mathematicians, uses 32-bit signed binary fixed point with 16 fraction bits for all position calculations. The values are interpreted as fractions of a [[point (typography)|typographer's point]]. [[TeX font metric]] files use 32-bit signed fixed-point numbers, with 12 fraction bits.
* [[Tremor (software)|Tremor]], [[Toast (GSM)|Toast]] and [[MPEG Audio Decoder|MAD]] are software libraries which decode the [[Vorbis|Ogg Vorbis]], [[Full Rate|GSM Full Rate]] and [[MP3]] audio formats respectively. These codecs use fixed-point arithmetic because many audio decoding hardware devices do not have an FPU.
* The [[WavPack|Wavpack]] lossless audio compressor uses fixed point arithmetic. The choice was justified by, among other things, the worry that different floating-point rounding rules in different hardware could corrupt the lossless nature of the compression.<ref name="WavPack"/>
* The Nest Labs Utilities library,<ref name="nlu"/> provides a limited set of macros and functions for fixed point numbers, particularly when dealing with those numbers in the context of sensor sampling and sensor outputs.
* The [[OpenGL ES]] 1.x specification includes a fixed point profile, as it is an API aimed for embedded systems, which do not always have an FPU.
* The [[dc (computer program)|dc]] and [[bc programming language|bc]] programs are [[arbitrary-precision arithmetic|arbitrary precision]] calculators, but only keep track of a (user-specified) fixed number of fractional digits.
* [[Fractint]] represents numbers as [[Q (number format)|Q2.29]] fixed-point numbers,<ref name="Fractint_2005"/> to speed up drawing on old PCs with [[Intel 80386|386]] or [[Intel 80486SX|486SX]] processors, which lacked an FPU.
* ''[[Doom (1993 video game)|Doom]]'' was the last [[first-person shooter]] game by [[id Software]] to use a 16.16 fixed point representation for all of its non-integer computations, including map system, geometry, rendering, and player movement. This representation is still used in modern [[List of Doom source ports|''Doom'' source port]]s.
* The [[Q Sharp|Q#]] programming language for the [[Microsoft Azure|Azure]] [[quantum computer]]s, that implement [[quantum logic gates]], contains a standard numeric library for performing fixed-point arithmetic on [[quantum register|registers]] of [[qubit]]s.<ref name="Quantum"/>