Note: This page has been translated by MathWorks. Click here to see

To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

This example shows how to set fixed point math attributes in MATLAB® code.

You can control fixed-point math attributes for assignment, addition, subtraction, and multiplication using the `fimath`

object. You can attach a `fimath`

object to a `fi`

object using `setfimath`

. You can remove a `fimath`

object from a `fi`

object using `removefimath`

.

You can generate C code from the examples if you have MATLAB Coder™ software.

You can insulate your fixed-point operations from global and local `fimath`

settings by using the `setfimath`

and `removefimath`

functions. You can also return from functions with no `fimath`

attached to output variables. This gives you local control over fixed-point math settings without interfering with the settings in other functions.

**MATLAB Code**

function y = user_written_sum(u) % Setup F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'SumMode','KeepLSB',... 'SumWordLength',32); u = setfimath(u,F); y = fi(0,true,32,get(u,'FractionLength'),F); % Algorithm for i=1:length(u) y(:) = y + u(i); end % Cleanup y = removefimath(y); end

**Output has no Attached FIMATH**

When you run the code, the `fimath`

controls the arithmetic inside the function, but the return value has no attached `fimath`

. This is due to the use of `setfimath`

and `removefimath`

inside the function `user_written_sum`

.

>> u = fi(1:10,true,16,11); >> y = user_written_sum(u)

```
y =
55
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 32
FractionLength: 11
```

**Generated C Code**

If you have MATLAB Coder software, you can generate C code using the following commands.

>> u = fi(1:10,true,16,11); >> codegen user_written_sum -args {u} -config:lib -launchreport

Functions `fimath`

, `setfimath`

and `removefimath`

control the fixed-point math, but the underlying data contained in the variables does not change and so the generated C code does not produce any data copies.

int32_T user_written_sum(const int16_T u[10]) { int32_T y; int32_T i; /* Setup */ y = 0; /* Algorithm */ for (i = 0; i < 10; i++) { y += u[i]; } /* Cleanup */ return y; }

When you operate on `fi`

objects, their `fimath`

properties must be equal, or you get an error.

>> A = fi(pi,'ProductMode','KeepLSB'); >> B = fi(2,'ProductMode','SpecifyPrecision'); >> C = A * B

Error using embedded.fi/mtimes The embedded.fimath of both operands must be equal.

To avoid this error, you can remove `fimath`

from one of the variables in the expression. In this example, the `fimath`

is removed from `B`

in the context of the expression without modifying `B`

itself, and the product is computed using the `fimath`

attached to `A`

.

>> C = A * removefimath(B)

C =

6.283203125

DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 32 FractionLength: 26

RoundingMethod: Nearest OverflowAction: Saturate ProductMode: KeepLSB ProductWordLength: 32 SumMode: FullPrecision

If you have variables with no attached `fimath`

, but you want to control a particular operation, then you can attach a `fimath`

in the context of the expression without modifying the variables.

For example, the product is computed with the `fimath`

defined by `F`

.

>> F = fimath('ProductMode','KeepLSB','OverflowAction','Wrap','RoundingMethod','Floor'); >> A = fi(pi); >> B = fi(2); >> C = A * setfimath(B,F)

C =

6.2832

DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 32 FractionLength: 26

RoundingMethod: Floor OverflowAction: Wrap ProductMode: KeepLSB ProductWordLength: 32 SumMode: FullPrecision MaxSumWordLength: 128

Note that variable `B`

is not changed.

>> B

B =

2

DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13

You can compute products and sums to match the accumulator of a DSP with floor rounding and wrap overflow, and use nearest rounding and saturate overflow on the output. To avoid mismatched `fimath`

errors, you can remove the `fimath`

on the output variable when it is used in a computation with the other variables.

**MATLAB Code**

In this example, the products are 32-bits, and the accumulator is 40-bits, keeping the least-significant-bits with floor rounding and wrap overflow like C's native integer rules. The output uses nearest rounding and saturate overflow.

function [y,z] = setfimath_removefimath_in_a_loop(b,a,x,z) % Setup F_floor = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'ProductMode','KeepLSB',... 'ProductWordLength',32,... 'SumMode','KeepLSB',... 'SumWordLength',40); F_nearest = fimath('RoundingMethod','Nearest',... 'OverflowAction','Wrap'); % Set fimaths that are local to this function b = setfimath(b,F_floor); a = setfimath(a,F_floor); x = setfimath(x,F_floor); z = setfimath(z,F_floor); % Create y with nearest rounding y = coder.nullcopy(fi(zeros(size(x)),true,16,14,F_nearest)); % Algorithm for j=1:length(x) % Nearest assignment into y y(j) = b(1)*x(j) + z(1); % Remove y's fimath conflict with other fimaths z(1) = (b(2)*x(j) + z(2)) - a(2) * removefimath(y(j)); z(2) = b(3)*x(j) - a(3) * removefimath(y(j)); end % Cleanup: Remove fimath from outputs y = removefimath(y); z = removefimath(z); end

**Code Generation Instructions**

If you have MATLAB Coder software, you can generate C code with the specified hardware characteristics using the following commands.

N = 256; t = 1:N; xstep = [ones(N/2,1);-ones(N/2,1)]; num = [0.0299545822080925 0.0599091644161849 0.0299545822080925]; den = [1 -1.4542435862515900 0.5740619150839550];

b = fi(num,true,16); a = fi(den,true,16); x = fi(xstep,true,16,15); zi = fi(zeros(2,1),true,16,14);

B = coder.Constant(b); A = coder.Constant(a);

config_obj = coder.config('lib'); config_obj.GenerateReport = true; config_obj.LaunchReport = true; config_obj.TargetLang = 'C'; config_obj.GenerateComments = true; config_obj.GenCodeOnly = true; config_obj.HardwareImplementation.ProdBitPerChar=8; config_obj.HardwareImplementation.ProdBitPerShort=16; config_obj.HardwareImplementation.ProdBitPerInt=32; config_obj.HardwareImplementation.ProdBitPerLong=40;

codegen -config config_obj setfimath_removefimath_in_a_loop -args {B,A,x,zi} -launchreport

**Generated C Code**

Functions `fimath`

, `setfimath`

and `removefimath`

control the fixed-point math, but the underlying data contained in the variables does not change and so the generated C code does not produce any data copies.

void setfimath_removefimath_in_a_loop(const int16_T x[256], int16_T z[2], int16_T y[256]) { int32_T j; int40_T i0; int16_T b_y;

/* Setup */ /* Set fimaths that are local to this function */ /* Create y with nearest rounding */ /* Algorithm */ for (j = 0; j < 256; j++) { /* Nearest assignment into y */ i0 = 15705 * x[j] + ((int40_T)z[0] << 20); b_y = (int16_T)((int32_T)(i0 >> 20) + ((i0 & 524288L) != 0L));

/* Remove y's fimath conflict with other fimaths */ z[0] = (int16_T)(((31410 * x[j] + ((int40_T)z[1] << 20)) - ((int40_T)(-23826 * b_y) << 6)) >> 20); z[1] = (int16_T)((15705 * x[j] - ((int40_T)(9405 * b_y) << 6)) >> 20); y[j] = b_y; }

/* Cleanup: Remove fimath from outputs */ }

You can write MATLAB code that can be used for both floating-point and fixed-point types using `setfimath`

and `removefimath`

.

function y = user_written_function(u) % Setup F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'SumMode','KeepLSB'); u = setfimath(u,F); % Algorithm y = u + u; % Cleanup y = removefimath(y); end

**Fixed Point Inputs**

When the function is called with fixed-point inputs, then `fimath`

`F`

is used for the arithmetic, and the output has no attached `fimath`

.

>> u = fi(pi/8,true,16,15,'RoundingMethod','Convergent'); >> y = user_written_function(u)

y =

0.785400390625

DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 32 FractionLength: 15

**Generated C Code for Fixed Point**

If you have MATLAB Coder software, you can generate C code using the following commands.

>> u = fi(pi/8,true,16,15,'RoundingMethod','Convergent'); >> codegen user_written_function -args {u} -config:lib -launchreport

Functions `fimath`

, `setfimath`

and `removefimath`

control the fixed-point math, but the underlying data contained in the variables does not change and so the generated C code does not produce any data copies.

int32_T user_written_function(int16_T u) { /* Setup */ /* Algorithm */ /* Cleanup */ return u + u; }

**Double Inputs**

Since `setfimath`

and `removefimath`

are pass-through for floating-point types, the `user_written_function`

example works with floating-point types, too.

function y = user_written_function(u) % Setup F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'SumMode','KeepLSB'); u = setfimath(u,F); % Algorithm y = u + u; % Cleanup y = removefimath(y); end

**Generated C Code for Double**

When compiled with floating-point input, you get the following generated C code.

>> codegen user_written_function -args {0} -config:lib -launchreport

real_T user_written_function(real_T u) { return u + u; }

Where the `real_T`

type is defined as a `double`

:

typedef double real_T;

This function is written so that the output is created to be the same type as the input, so both floating-point and fixed-point can be used with it.

function y = user_written_sum_polymorphic(u) % Setup F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'SumMode','KeepLSB',... 'SumWordLength',32);

u = setfimath(u,F);

if isfi(u) y = fi(0,true,32,get(u,'FractionLength'),F); else y = zeros(1,1,class(u)); end

% Algorithm for i=1:length(u) y(:) = y + u(i); end

% Cleanup y = removefimath(y);

```
end
```

**Fixed Point Generated C Code**

If you have MATLAB Coder software, you can generate fixed-point C code using the following commands.

>> u = fi(1:10,true,16,11); >> codegen user_written_sum_polymorphic -args {u} -config:lib -launchreport

`fimath`

, `setfimath`

and `removefimath`

control the fixed-point math, but the underlying data contained in the variables does not change and so the generated C code does not produce any data copies.

int32_T user_written_sum_polymorphic(const int16_T u[10]) { int32_T y; int32_T i;

/* Setup */ y = 0;

/* Algorithm */ for (i = 0; i < 10; i++) { y += u[i]; }

/* Cleanup */ return y; }

**Floating Point Generated C Code**

If you have MATLAB Coder software, you can generate floating-point C code using the following commands.

>> u = 1:10; >> codegen user_written_sum_polymorphic -args {u} -config:lib -launchreport

real_T user_written_sum_polymorphic(const real_T u[10]) { real_T y; int32_T i;

/* Setup */ y = 0.0;

/* Algorithm */ for (i = 0; i < 10; i++) { y += u[i]; }

/* Cleanup */ return y; }

Where the `real_T`

type is defined as a `double`

:

typedef double real_T;

Following the established pattern of treating built-in integers like `fi`

objects, `setfimath`

converts integer input to the equivalent `fi`

with attached `fimath`

.

>> u = int8(5); >> codegen user_written_u_plus_u -args {u} -config:lib -launchreport

function y = user_written_u_plus_u(u) % Setup F = fimath('RoundingMethod','Floor',... 'OverflowAction','Wrap',... 'SumMode','KeepLSB',... 'SumWordLength',32); u = setfimath(u,F); % Algorithm y = u + u; % Cleanup y = removefimath(y); end

The output type was specified by the `fimath`

to be 32-bit.

int32_T user_written_u_plus_u(int8_T u) { /* Setup */ /* Algorithm */ /* Cleanup */ return u + u; }