La traduction de cette page n'est pas à jour. Cliquez ici pour voir la dernière version en anglais.
Opérations en arithmétique à virgule fixe
Arithmétique à virgule fixe
Addition et soustraction
Chaque fois que vous additionnez deux nombres à virgule fixe, il est possible que vous ayez besoin d’un bit de report pour représenter correctement le résultat. Pour cette raison, lors de l’addition de deux nombres à B bits (avec la même mise à l’échelle), la valeur résultante possède un bit supplémentaire par rapport aux deux opérandes utilisés.
a = fi(0.234375,0,4,6); c = a+a
c = 0.4688 DataTypeMode: Fixed-point: binary point scaling Signedness: Unsigned WordLength: 5 FractionLength: 6
a.bin
ans = 1111
c.bin
ans = 11110
Si vous additionnez ou soustrayez deux nombres d’une précision différente, il faut d’abord aligner la séparation fractionnaire pour pouvoir effectuer l’opération. Le résultat est qu’il y a une différence de plus d’un bit entre le résultat de l’opération et les opérandes.
a = fi(pi,1,16,13); b = fi(0.1,1,12,14); c = a + b
c = 3.2416 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 18 FractionLength: 14
Multiplication
Généralement un produit en précision totale nécessite une longueur de mot égale à la somme des longueurs de mot des opérandes. Dans l’exemple suivant, notez que la longueur de mot du produit c
est égale à la longueur de mot de a
plus la longueur de mot de b
. La longueur de la partie fractionnaire de c
est aussi égale à la longueur de la partie fractionnaire de a
plus la longueur de la partie fractionnaire de b
.
a = fi(pi,1,20), b = fi(exp(1),1,16)
a = 3.1416 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 20 FractionLength: 17 b = 2.7183 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
c = a*b
c = 8.5397 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 36 FractionLength: 30
Maths avec d’autres types de données prédéfinis
Notez qu'en C, le résultat d’une opération entre un type de données entier et un type de données double donne un double. Cependant, dans MATLAB®, le résultat d’une opération entre un type de données entier prédéfini et un type de données double est un entier. À cet égard, l’objet fi
se comporte comme les types de données entiers prédéfinis dans MATLAB.
Lors de l’addition entre fi
et double
, le double est converti (par cast) en un fi
ayant la même propriété numerictype que l’entrée fi
. Le résultat de l’opération est un fi
. Lors de la multiplication entre un fi
et un double
, le double est converti (par cast) en un fi
ayant la même longueur de mot et le même signe que le fi
, et une longueur de la partie fractionnaire avec la meilleure précision. Le résultat de l’opération est un fi
.
a = fi(pi);
a = 3.1416 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 13
b = 0.5 * a
b = 1.5708 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 32 FractionLength: 28
Lors d’opérations arithmétiques entre un fi
et l’un des types de données entiers prédéfinis, [u]int[8, 16, 32]
, la longueur du mot et le signe de l’entier sont préservés. Le résultat de l’opération est un fi
.
a = fi(pi); b = int8(2) * a
b = 6.2832 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 24 FractionLength: 13
Lors d’opérations arithmétiques entre un fi
et un type de données logique, le type logique est traité comme un objet fi
non signé avec une valeur de 0 ou 1, et une longueur de mot de 1. Le résultat de l’opération est un objet fi
.
a = fi(pi); b = logical(1); c = a*b
c = 3.1416 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 17 FractionLength: 13
L’objet fimath
Les propriétés de fimath
définissent les règles pour effectuer des opérations arithmétiques sur les objets fi
, y compris les propriétés mathématiques, d'arrondi et d'overflow. Un objet fi
peut avoir un objet fimath
local, ou utiliser les propriétés fimath
par défaut. Vous pouvez attacher un objet fimath
à un objet fi
en utilisant setfimath
. Sinon, vous pouvez spécifier les propriétés fimath
dans le constructeur fi
lors de la création. Lorsqu’un objet fi
a un fimath
local, plutôt que d’utiliser les propriétés par défaut, l’affichage de l’objet fi
montre les propriétés fimath
. Dans cet exemple, a
a la propriété ProductMode
spécifiée dans le constructeur.
a = fi(5,1,16,4,'ProductMode','KeepMSB')
a = 5 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 4 RoundingMethod: Nearest OverflowAction: Saturate ProductMode: KeepMSB ProductWordLength: 32 SumMode: FullPrecision
ProductMode
de a
est fixée à KeepMSB
tandis que les propriétés fimath
restantes utilisent les valeurs par défaut.Remarque
Pour plus d’informations sur l’objet fimath
, ses propriétés et leurs valeurs par défaut, voir fimath Object Properties.
Croissance des bits
Le tableau suivant montre la croissance des bits des objets fi
, A
et B
, lorsque leurs propriétés SumMode
et ProductMode
utilisent la valeur fimath
par défaut, FullPrecision
.
A | B | Somme = A+B | Produit = A*B | |
---|---|---|---|---|
Format | fi(vA,s1,w1,f1) | fi(vB,s2,w2,f2) | — | — |
Signe | s1 | s2 | Ssum = (s1 ||s2 ) | Sproduct = (s1 ||s2 ) |
Bits pour la partie entière | I1 = w1-f1-s1 | I2= w2-f2-s2 | Isum = max(w1-f1, w2-f2) + 1 - Ssum | Iproduct = (w1 + w2) - (f1 + f2) |
Bits de la partie fractionnaire | f1 | f2 | Fsum = max(f1, f2) | Fproduct = f1 + f2 |
Total des bits | w1 | w2 | Ssum + Isum + Fsum | w1 + w2 |
Cet exemple montre comment la croissance des bits peut survenir dans une boucle for
.
T.acc = fi([],1,32,0); T.x = fi([],1,16,0); x = cast(1:3,'like',T.x); acc = zeros(1,1,'like',T.acc); for n = 1:length(x) acc = acc + x(n) end
acc = 1 s33,0 acc = 3 s34,0 acc = 6 s35,0
acc
augmente à chaque itération de la boucle. Cette augmentation cause deux problèmes : D’une part, la génération de code ne permet pas de modifier le type de données dans une boucle. D’autre part, si la boucle est assez longue, vous vous retrouvez à court de mémoire dans MATLAB. Dans Contrôle de la croissance des bits, vous trouverez différentes stratégies pour éviter ce problème.Contrôle de la croissance des bits
Utilisation de fimath
En spécifiant les propriétés fimath
d’un objet fi
, vous pouvez contrôler la croissance des bits à mesure que les opérations sont effectuées sur l’objet.
F = fimath('SumMode', 'SpecifyPrecision', 'SumWordLength', 8,... 'SumFractionLength', 0); a = fi(8,1,8,0, F); b = fi(3, 1, 8, 0); c = a+b
c = 11 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 8 FractionLength: 0 RoundingMethod: Nearest OverflowAction: Saturate ProductMode: FullPrecision SumMode: SpecifyPrecision SumWordLength: 8 SumFractionLength: 0 CastBeforeSum: true
L’objet fi
nommé a
a un objet fimath
local F
. F
spécifie la longueur de mot et la longueur de la partie fractionnaire de la somme. Dans le cadre des paramètres fimath
par défaut, la sortie, c
, a normalement une longueur de mot de 9 et une longueur de partie fractionnaire de 0. Cependant, comme a
avait un objet fimath
local, l’objet fi
résultant a une longueur de mot de 8 et une longueur de partie fractionnaire de 0.
Vous pouvez également utiliser les propriétés fimath
pour contrôler la croissance des bits dans une boucle for
.
F = fimath('SumMode', 'SpecifyPrecision','SumWordLength',32,... 'SumFractionLength',0); T.acc = fi([],1,32,0,F); T.x = fi([],1,16,0); x = cast(1:3,'like',T.x); acc = zeros(1,1,'like',T.acc); for n = 1:length(x) acc = acc + x(n) end
acc = 1 s32,0 acc = 3 s32,0 acc = 6 s32,0
Contrairement à ce qui se passait quand T.acc
utilisait les propriétés fimath
par défaut, maintenant, la croissance des bits de acc
est restreinte. Ainsi, la longueur de mot de acc
reste égale à 32.
Affectation indicée
Une autre manière de contrôler la croissance des bits consiste à utiliser une affectation indicée. a(I) = b
affecte les valeurs de b
dans les éléments de a
spécifiés par le vecteur d’indice, I
, tout en retenant le numerictype
de a
.
T.acc = fi([],1,32,0); T.x = fi([],1,16,0); x = cast(1:3,'like',T.x); acc = zeros(1,1,'like',T.acc); % Assign in to acc without changing its type for n = 1:length(x) acc(:) = acc + x(n) end
acc (:) = acc + x(n) impose que les valeurs au vecteur d’indice, (:)
, changent. Toutefois, la propriété numerictype
de la sortie acc
reste inchangée. Puisque acc
est un scalaire, vous obtenez également la même sortie si vous utilisez (1)
comme vecteur d’indice.
for n = 1:numel(x) acc(1) = acc + x(n); end
acc = 1 s32,0 acc = 3 s32,0 acc = 6 s32,0
Le numerictype
de acc
reste le même à chaque itération de la boucle for
.
L’affectation indicée peut également vous aider à contrôler la croissance des bits dans une fonction. Dans la fonction cumulative_sum
, la propriété numerictype
de y
ne change pas, mais les valeurs dans les éléments spécifiés par n changent.
function y = cumulative_sum(x) % CUMULATIVE_SUM Cumulative sum of elements of a vector. % % For vectors, Y = cumulative_sum(X) is a vector containing the % cumulative sum of the elements of X. The type of Y is the type of X. y = zeros(size(x),'like',x); y(1) = x(1); for n = 2:length(x) y(n) = y(n-1) + x(n); end end
y = cumulative_sum(fi([1:10],1,8,0))
y = 1 3 6 10 15 21 28 36 45 55 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 8 FractionLength: 0
Remarque
Pour plus d’informations sur l’affectation indicée, voir la fonction subsasgn
.
accumpos
et accumneg
Une autre manière de contrôler la croissance des bits consiste à utiliser les fonctions accumpos
et accumneg
pour effectuer les opérations d’addition et de soustraction. Comme lorsqu’on utilise l'affectation indicée, accumpos
et accumneg
préservent le type de données de l’un de ses objets fi
d’entrée tout en vous permettant de spécifier une méthode d’arrondi, et l’action pour l'overflow sur les valeurs d’entrée.
Pour plus d’informations sur la manière d’implémenter accumpos
et accumneg
, voir Avoid Multiword Operations in Generated Code
Overflows et arrondis
Lorsque vous effectuez des opérations en arithmétique à virgule fixe, pensez à la possibilité et aux conséquences des overflows. L’objet fimath
spécifie les modes d'overflow et d’arrondi utilisés lors des opérations arithmétiques.
Overflows
Des overflows peuvent se produire lorsque le résultat d’une opération dépasse la valeur représentable maximale ou minimale. L’objet fimath
a une propriété OverflowAction
qui offre deux manières de gérer les overflows : la saturation et le wrap. Si l’on règle OverflowAction
sur saturate
, les overflows sont saturés à la valeur maximale ou minimale de la plage. Si l’on règle OverflowAction
sur wrap
, tous les overflows vont réaliser un « wrap » en utilisant l’arithmétique modulaire si les nombres sont non signés, ou le wrap en complément à deux, si les nombres sont signés.
Pour plus d’informations sur la manière de détecter un overflow, voir Underflow and Overflow Logging Using fipref.
Arrondis
Plusieurs facteurs interviennent lors du choix d’une méthode d’arrondi, notamment le prix, le biais, et le fait qu’il y ait ou non une possibilité d'overflow. Le software Fixed-Point Designer™ offre plusieurs fonctions d’arrondi pour répondre aux exigences de votre design.
Méthode d’arrondi | Description | Coût | Biais | Possibilité d'overflow |
---|---|---|---|---|
ceil | Arrondit au nombre représentable le plus proche dans la direction de l’infini positif. | Faible | Fortement positif | Oui |
convergent | Arrondit au nombre représentable le plus proche. Dans le cas d’une égalité de distance du nombre représentable le plus proche, convergent arrondit au nombre pair le plus proche. Cette approche est la méthode d’arrondi la moins biaisée de la toolbox. | Élevé | Non biaisée | Oui |
floor | Arrondit au nombre représentable le plus proche dans la direction de l’infini négatif, équivalent à la troncature en complément à deux. | Faible | Fortement négatif | Non |
nearest | Arrondit au nombre représentable le plus proche. Dans le cas d’une égalité de distance du nombre représentable le plus proche, nearest arrondit au nombre représentable le plus proche dans la direction de l’infini positif. Cette méthode d’arrondi est la méthode par défaut pour la création d’objets fi et l’arithmétique fi . | Modéré | Faiblement positif | Oui |
round | Arrondit au nombre représentable le plus proche. Dans le cas d’une égalité de distance du nombre représentable le plus proche, la méthode round arrondit :
| Élevé |
| Oui |
fix | Arrondit au nombre représentable le plus proche dans la direction de zéro. | Faible |
| Non |