FixedPoint Designer 

This example shows the basics of how to use the fixedpoint numeric object fi.
The fixedpoint numeric object is called fi because J.H. Wilkinson used fi to denote fixedpoint computations in his classic texts Rounding Errors in Algebraic Processes (1963), and The Algebraic Eigenvalue Problem (1965).
This example may use display settings or preferences that are different from what you are currently using. To ensure that your current display settings and preferences are not changed by running this example, the example automatically saves and restores them. The following code captures the current states for any display settings or properties that the example changes.
originalFormat = get(0, 'format'); format loose format long g % Capture the current state of and reset the fi display and logging % preferences to the factory settings. fiprefAtStartOfThisExample = get(fipref); reset(fipref);
Default FixedPoint Attributes
To assign a fixedpoint data type to a number or variable with the default fixedpoint parameters, use the fi constructor. The resulting fixedpoint value is called a fi object.
For example, the following creates fi objects a and b with attributes shown in the display, all of which we can specify when the variables are constructed. Note that when the FractionLength property is not specified, it is set automatically to "best precision" for the given word length, keeping the mostsignificant bits of the value. When the WordLength property is not specified it defaults to 16 bits.
a = fi(pi)
a = 3.1416015625 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
b = fi(0.1)
b = 0.0999984741210938 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 18
Specifying Signed and WordLength Properties
The second and third numeric arguments specify Signed (true or 1 = signed, false or 0 = unsigned), and WordLength in bits, respectively.
% Signed 8bit
a = fi(pi, 1, 8)
a = 3.15625 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 8 FractionLength: 5
The sfi constructor may also be used to construct a signed fi object
a1 = sfi(pi,8)
a1 = 3.15625 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 8 FractionLength: 5
% Unsigned 20bit
b = fi(exp(1), 0, 20)
b = 2.71828079223633 DataTypeMode: Fixedpoint: binary point scaling Signedness: Unsigned WordLength: 20 FractionLength: 18
The ufi constructor may be used to construct an unsigned fi object
b1 = ufi(exp(1), 20)
b1 = 2.71828079223633 DataTypeMode: Fixedpoint: binary point scaling Signedness: Unsigned WordLength: 20 FractionLength: 18
The data is stored internally with as much precision as is specified. However, it is important to be aware that initializing high precision fixedpoint variables with doubleprecision floatingpoint variables may not give you the resolution that you might expect at first glance. For example, let's initialize an unsigned 100bit fixedpoint variable with 0.1, and then examine its binary expansion:
a = ufi(0.1, 100);
bin(a)
ans = 1100110011001100110011001100110011001100110011001101000000000000000000000000000000000000000000000000
Note that the infinite repeating binary expansion of 0.1 gets cut off at the 52nd bit (in fact, the 53rd bit is significant and it is rounded up into the 52nd bit). This is because doubleprecision floatingpoint variables (the default MATLAB® data type), are stored in 64bit floatingpoint format, with 1 bit for the sign, 11 bits for the exponent, and 52 bits for the mantissa plus one "hidden" bit for an effective 53 bits of precision. Even though doubleprecision floatingpoint has a very large range, its precision is limited to 53 bits. For more information on floatingpoint arithmetic, refer to Chapter 1 of Cleve Moler's book, Numerical Computing with MATLAB. The pdf version can be found here: http://www.mathworks.com/company/aboutus/founders/clevemoler.html
So, why have more precision than floatingpoint? Because most fixedpoint processors have data stored in a smaller precision, and then compute with larger precisions. For example, let's initialize a 40bit unsigned fi and multiply using fullprecision for products.
Note that the fullprecision product of 40bit operands is 80 bits, which is greater precision than standard doubleprecision floatingpoint.
a = fi(0.1, 0, 40); bin(a)
ans = 1100110011001100110011001100110011001101
b = a*a
b = 0.0100000000000045 DataTypeMode: Fixedpoint: binary point scaling Signedness: Unsigned WordLength: 80 FractionLength: 86
bin(b)
ans = 10100011110101110000101000111101011100001111010111000010100011110101110000101001
The data can be accessed in a number of ways which map to builtin data types and binary strings. For example,
a = fi(pi); double(a)
ans = 3.1416015625
returns the doubleprecision floatingpoint "realworld" value of a, quantized to the precision of a.
We can also set the realworld value in a double.
a.double = exp(1)
a = 2.71826171875 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
sets the realworld value of a to e, quantized to a's numeric type.
storedInteger(a)
ans = 22268
returns the "stored integer" in the smallest builtin integer type available, up to 64 bits.
Relationship Between Stored Integer Value and RealWorld Value
In BinaryPoint scaling, the relationship between the stored integer value and the realworld value is
There is also SlopeBias scaling, which has the relationship
where
and
The math operators of fi work with BinaryPoint scaling and realvalued SlopeBias scaled fi objects.
BIN(A), OCT(A), DEC(A), HEX(A)
return the stored integer in binary, octal, unsigned decimal, and hexadecimal strings, respectively.
bin(a)
ans = 0101011011111100
oct(a)
ans = 053374
dec(a)
ans = 22268
hex(a)
ans = 56fc
A.BIN = ..., A.OCT = ..., A.DEC = ..., A.HEX = ...
set the stored integer from binary, octal, unsigned decimal, and hexadecimal strings, respectively.
a.bin = '0110010010001000'
a = 3.1416015625 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
a.oct = '031707'
a = 1.6180419921875 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
a.dec = '22268'
a = 2.71826171875 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
a.hex = '0333'
a = 0.0999755859375 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
When the FractionLength property is not specified, it is computed to be the best precision for the magnitude of the value and given word length. You may also specify the fraction length directly as the fourth numeric argument in the fi constructor or the third numeric argument in the sfi or ufi constructor. In the following, compare the fraction length of a, which was explicitly set to 0, to the fraction length of b, which was set to best precision for the magnitude of the value.
a = sfi(10,16,0)
a = 10 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 0
b = sfi(10,16)
b = 10 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 11
Note that the stored integer values of a and b are different, even though their realworld values are the same. This is because the realworld value of a is the stored integer scaled by 2^0 = 1, while the realworld value of b is the stored integer scaled by 2^11 = 0.00048828125.
storedInteger(a)
ans = 10
storedInteger(b)
ans = 20480
Specifying Properties with Parameter/Value Pairs
Thus far, we have been specifying the numeric type properties by passing numeric arguments to the fi constructor. We can also specify properties by giving the name of the property as a string followed by the value of the property:
a = fi(pi,'WordLength',20)
a = 3.14159393310547 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 20 FractionLength: 17
For more information on fi properties, type
help fi
or
doc fi
at the MATLAB command line.
All of the numeric type properties of fi are encapsulated in an object named numerictype:
T = numerictype
T = DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 15
The numeric type properties can be modified either when the object is created by passing in parameter/value arguments
T = numerictype('WordLength',40,'FractionLength',37)
T = DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 40 FractionLength: 37
or they may be assigned by using the dot notation
T.Signed = false
T = DataTypeMode: Fixedpoint: binary point scaling Signedness: Unsigned WordLength: 40 FractionLength: 37
All of the numeric type properties of a fi may be set at once by passing in the numerictype object. This is handy, for example, when creating more than one fi object that share the same numeric type.
a = fi(pi,'numerictype',T)
a = 3.14159265359194 DataTypeMode: Fixedpoint: binary point scaling Signedness: Unsigned WordLength: 40 FractionLength: 37
b = fi(exp(1),'numerictype',T)
b = 2.71828182845638 DataTypeMode: Fixedpoint: binary point scaling Signedness: Unsigned WordLength: 40 FractionLength: 37
The numerictype object may also be passed directly to the fi constructor
a1 = fi(pi,T)
a1 = 3.14159265359194 DataTypeMode: Fixedpoint: binary point scaling Signedness: Unsigned WordLength: 40 FractionLength: 37
For more information on numerictype properties, type
help numerictype
or
doc numerictype
at the MATLAB command line.
The display preferences for fi can be set with the fipref object. They can be saved between MATLAB sessions with the savefipref command.
When displaying realworld values, the closest doubleprecision floatingpoint value is displayed. As we have seen, doubleprecision floatingpoint may not always be able to represent the exact value of highprecision fixedpoint number. For example, an 8bit fractional number can be represented exactly in doubles
a = sfi(1,8,7)
a = 0.9921875 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 8 FractionLength: 7
bin(a)
ans = 01111111
while a 100bit fractional number cannot (1 is displayed, when the exact value is 1  2^99):
b = sfi(1,100,99)
b = 1 DataTypeMode: Fixedpoint: binary point scaling Signedness: Signed WordLength: 100 FractionLength: 99
Note, however, that the full precision is preserved in the internal representation of fi
bin(b)
ans = 0111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
The display of the fi object is also affected by MATLAB's format command. In particular, when displaying realworld values, it is handy to use
format long g
so that as much precision as is possible will be displayed.
There are also other display options to make a more shorthand display of the numeric type properties, and options to control the display of the value (as realworld value, binary, octal, decimal integer, or hex).
For more information on display preferences, type
help fipref help savefipref help format
or
doc fipref doc savefipref doc format
at the MATLAB command line.
The following code sets any display settings or preferences that the example changed back to their original states.
% Reset the fi display and logging preferences fipref(fiprefAtStartOfThisExample); set(0, 'format', originalFormat);