Fixed-point numbers use integers and integer arithmetic to approximate real numbers. They are an efficient means for performing computations involving real numbers without requiring floating-point support in underlying system hardware.
Fixed-point numbers represent real numbers by using the encoding scheme:
V ≈ V_{approx} = SQ + B.
V is a precise real-world value that you want to approximate with a fixed-point number.
V_{approx} is the approximate real-world value that results from the fixed-point representation.
Q is an integer that encodes the fixed-point number. This value is called the quantized integer.
S is a coefficient that determines the precision of the fixed-point representation. This value is called the slope.
B is an additive correction called the bias.
The quantized integer Q is the only part of the fixed-point representation that varies in value. In the generated code, the quantities S and B are constant and appear only as literal numbers or expressions. If a fixed-point number changes, its quantized integer Q changes but S and B remain unchanged.
To determine the quantized integer Q corresponding to a real-world value V, round the quantity (V – B)/S to an integer. For example, to represent the number V = 15.345 in a fixed-point type with slope S = 0.5 and bias B = 0.1, you use the quantized integer
Q = round((V – B)/S) = round((15.345 – 0.1)/0.5) = round(30.49) = 30.
Because you round Q to an integer, you lose some precision in representing the number 15.345. The number that Q actually represents is
V_{approx} = SQ + B = 0.5 ⨉ 30 + 0.1 = 15.1.
Using fixed-point numbers to represent real numbers with integers involves the loss of some precision. However, with a suitable choice of S and B, you can minimize this loss to acceptable levels. For instance, by changing the coding scheme to use S = 0.25 and B = 0.1, you can represent the number V = 15.345 with greater precision as:
Q = round((V – B)/S) = round((15.345 – 0.1)/0.25) = round(60.98) = 61
V_{approx} = SQ + B = 0.25 ⨉ 61 + 0.1 = 15.35.
The difference between V_{approx} and V is always less than the slope S.
In the Model Explorer, you can specify the fixed-point encoding for a data object by
using the Data Type Assistant, as described in Fixed-Point Data Properties. Set the Mode field to
Fixed point
and specify these properties:
Signedness: Choose Signed
or
Unsigned
.
Word length: Specify the bit size of the word that holds the quantized integer Q.
Scaling: Choose Binary point
or
Slope and bias
.
If you select Binary point
, the Data Type
Assistant displays the Fraction length field,
which specifies the binary point location. Choosing a Fraction length of n defines a fixed-point
encoding with a slope of S =
2^{-n} and a bias of B = 0 .
If you select Slope and bias
, the Data Type
Assistant displays fields for entering the Slope
S and Bias
B for the fixed-point encoding scheme.
Alternatively, you can specify the encoding for a fixed-point data object directly by
using the fixdt
function. In the Property Inspector
or the Model Explorer, in the Type field, enter an expression in one of
these
formats:
fixdt(Signed, WordLength, FractionLength)
fixdt(Signed, WordLength, Slope, Bias)
Some encoding schemes are computationally expensive, particularly in multiplication and division operations. Selecting a slope that is an integer power of two and a zero bias avoids these computationally expensive instructions. Using binary point scaling is recommended.
Stateflow^{®} charts convert real numbers into fixed-point numbers during data initialization and as part of casting operations in the application. These conversions compute a quantized integer Q from a real number input. The type of conversion depends on the action language for the chart.
In a chart that uses MATLAB^{®} as the action language, you define the method for all conversions through the fixed-point properties for the chart. See Fixed-Point Properties.
For example, if you set the MATLAB Chart fimath
property to Same as
MATLAB
, then the chart rounds the resulting quantized integer to its
nearest integer value.
Charts that use C as the action language employ two methods for converting fixed-point data:
Offline conversions initialize data during code generation. Offline conversions are designed to maximize accuracy. These conversions round the resulting quantized integer to its nearest integer value. Offline conversions are performed for initialization of data (variables and constants) in the Stateflow hierarchy and from the MATLAB workspace.
Online conversions perform casting operations during run time. Online conversions are designed to maximize computational efficiency. They are faster and more efficient, but less precise than offline conversions. Instead of rounding Q to its nearest integer, online conversions round to the floor (except for division, which can round to 0, depending on the C compiler).
For example, this table illustrates the difference between offline and online conversions of real numbers to fixed-point numbers defined with a slope of S = 2^{-4} and a bias of B = 0. For each real-world value V, the chart computes a quantized integer Q by rounding (V-B)/S to the nearest integer (in offline conversion) or to the floor (in online conversion). For each conversion, V_{approx} = QS + B is the approximate real-world value resulting from Q.
Real-World Value | Offline Conversion | Online Conversion | |||
---|---|---|---|---|---|
V | (V-B)/S | Q | V_{approx} | Q | V_{approx} |
15.345 | 245.52 | 246 | 15.375 | 245 | 15.3125 |
3.45 | 55.2 | 55 | 3.4375 | 55 | 3.4375 |
1.0375 | 16.6 | 17 | 1.0625 | 16 | 1 |
2.06 | 32.96 | 33 | 2.0625 | 32 | 2 |
In charts that use C as the action language, you can avoid explicit type casts by using
fixed-point context-sensitive constants. These constants infer their type from the context
in which they occur. They are written like ordinary numbers with the suffix
C
or c
. For example, 4.3C
and
123.4c
are valid fixed-point context-sensitive constants that you can
use in action statements.
Although fixed-point context-sensitive constants can appear in expressions with any data types (including integers and floating-point data), their main use is with fixed-point numbers. The algorithm that interprets the context-sensitive constant computes a type that provides maximum accuracy without overflow. The algorithm depends on:
The operations in the expression
The other data types in the context
The value of the constant
Fixed-point context-sensitive constants infer their type according to these rules:
In a casting operation, the constant has the type to which it is being cast.
In a simple assignment operation of the form a = b
:
If b
is a context-sensitive constant, it has the same type
as a
.
If b
is an addition or subtraction operation, then the
constant has the same type as the other operand.
If b
is a multiplication or division operation with a
fixed-point operand, then the constant has the type that provides the best
possible precision for a fixed-point result, as determined by the fixptbestexp
function.
If b
is a multiplication or division operation with a
floating-point operand of type double
or
single
, then the constant has the same type as the
floating-point operand.
In a special assignment operation of the form a := b
:
If b
is a context-sensitive constant, it has the same type
as a
.
If b
is an arithmetic operation with a floating-point
operand of type double
or single
, or if
a
is a floating-point data object, then the constant has the
same type as the floating-point number.
If b
is an addition or subtraction operation with a
fixed-point operand and a
is a fixed-point data object, then
the constant has the same type as a
.
If b
is a multiplication or division operation with a
fixed-point operand and a
is a fixed-point data object, then
the constant has the type that provides the best possible precision for a
fixed-point result.
As an argument in a function call, the constant has the same type as the formal argument.
You cannot use context-sensitive constants as both operands of a binary operation or as the leftmost operand of an assignment operation.
Develop and test your application by using double- or single-precision floating-point numbers. Using double- or single-precision floating-point numbers does not limit the range or precision of your computations. Once your application works as designed, you can start substituting fixed-point data for double-precision data.
In the Model Configuration Parameters dialog box, on the Hardware Implementation pane, set the integer word size for the simulation environment to the integer size of the intended target environment. Code generated by Stateflow uses this integer size to select result types for your fixed-point operations. See Hardware Implementation Pane (Simulink).
When you simulate your model, use overflow detection to warn you
when the result of a fixed-point operation exceeds the numeric capacity of its
fixed-point type. In the Model Configuration Parameters dialog box, on the Diagnostics > Data Validity pane, set Wrap on overflow and Saturate on
overflow to error
or warning
. If you encounter overflow errors in fixed-point
data, increase the range of your data by:
Increasing the Word length value for the overflowing
fixed-point data. For example, change the number of bits used to encode the
fixed-point data from 16 to 32. This action changes the base integer type for
Q from int16
to
int32
.
Decreasing the Fraction length value (if using
Binary point
scaling) or increasing the
Slope value (if using Slope and
bias
scaling). For example, decrease the Fraction
length value from 4 to 1 (or, equivalently, increase the
Slope value from S = 2^{-4} =
0.0625 to S = 2^{-1} =
0.5). This action increases the range of your fixed-point data but
decreases the available precision.
For more information, see Data Range Violations.
If you encounter issues with model behavior stemming from
inadequate precision in your fixed-point data, increase the precision of your data by
increasing the Fraction length value (if using Binary
point
scaling) or decreasing the Slope value (if
using Slope and bias
scaling). For example, increase the
Fraction length value from 2 to 3 (or, equivalently, decrease the
Slope value from S = 2^{-2} = 0.25 to S = 2^{-3} = 0.125). This action increases the precision of your fixed-point data but
decreases the available range.
In charts that use C as the action language, you can use a special assignment
operation :=
and context-sensitive constants to maintain as much
precision as possible. See Override Fixed-Point Promotion in C Charts and Fixed-Point Context-Sensitive Constants.
If you do not use context-sensitive constants with fixed-point types, noninteger numeric constants (constants that have a decimal point) can force fixed-point operations to produce floating-point results.
Automatic scaling tools can change the settings of Stateflow fixed-point data. You can prevent automatic scaling by selecting the Lock data type setting against changes by the fixed-point tools option for the fixed-point data object. See Lock Data Type Against Fixed-Point Tools. For methods on autoscaling fixed-point data, see Choosing a Range Collection Method (Fixed-Point Designer).
To share fixed-point data with Simulink^{®} models:
Use the same property values to specify the data in the Stateflow chart and in the Simulink model. For an example of this method of sharing input data from a Simulink model, see Model Bang-Bang Temperature Control System.
For some Simulink blocks, you can specify the type of input or output data directly. For
example, you can specify the fixed-point data type for a Constant block
directly in the Output data type field by using the fixdt
function.
Define the data as Input or Output in the Stateflow chart and instruct the sending or receiving block in the Simulink model to inherit its type from the chart data. In many blocks, you can set data types through inheritance from the driving block, or through back propagation from the next block. You can set the data type of a Simulink block to match the data type of the Stateflow port to which it connects.
For example, you can set the Constant block to inherit its type from the Stateflow
Input to Simulink port that it supplies. Set the Output
data type block parameter to Inherit via back
propagation
.
Stateflow charts define fixed-point data types from the values that you specify for S, B, and the base integer type for Q.
For each fixed-point data, the chart defines an integer variable for
Q in the generated code. This integer is the only part of a
fixed-point number that changes in value. The available base types for
Q are the unsigned integer types uint8
,
uint16
, and uint32
, and the signed integer types
int8
, int16
, and int32
. If a
fixed-point number has a slope S = 1 and a bias B
= 0, it is equivalent to its quantized integer Q and behaves exactly
as its base integer type.
The slope S is factored into a coefficient F with 1 ≤ F < 2 and an integer power of two with exponent E:
S = F ⨉ 2^{E}.
If the fractional slope F is greater than 1, it is converted into a fixed-point number. Encoding schemes with F > 1 can be computationally expensive, particularly in multiplication and division operations. Setting F = 1 avoids these computationally expensive instructions. In this setting, scaling by a power of 2 is implemented as bit shifts, which are more efficient than multiply instructions. Therefore, using binary-point-only scaling, in which F = 1 and B = 0, is recommended.
Operations for fixed-point types are implemented with solutions for the quantized integer as described in Arithmetic Operations for Fixed-Point Data. To generate efficient code, the fixed-point promotion rules choose values for slope and bias that cancel difficult terms in the solutions. See Promotion Rules for Fixed-Point Operations.