Question

J'ai un code C qui utilise double. Je veux être en mesure d'exécuter le code sur un DSP ( TMS320 ). Mais le DSP ne supporte pas les doubles, seuls les nombres à virgule fixe. Quelle est la meilleure façon de convertir le code en virgule fixe? Y at-il une bonne bibliothèque C pour les nombres à virgule fixe (mis en œuvre sous forme d'entiers)?

Était-ce utile?

La solution

TI fournit une bibliothèque de point fixe appelé "IQmath":

http://focus.ti.com/lit/sw/sprc990/ sprc990.pdf

La conversion consiste à analyser votre code actuel - pour chaque variable que vous devez savoir quelle gamme il peut contenir, et quelle précision dont il a besoin. Ensuite, vous pouvez décider quel type de stocker dans. IQMath fournit des types de Q30 avec une plage de +/- 2 et une précision de 0,0000000001 au 1er trimestre avec une gamme de ~ +/- 1 million et une précision de 0,5.

Pour les opérations qui peuvent éventuellement déborder la plage des variables, vous devez ajouter des contrôles de débordement, et de décider comment le gérer -. Pin il max, magasin avec une échelle différente, relevez une erreur, etc

Il n'y a vraiment aucun moyen de convertir en point fixe sans prendre vraiment une compréhension profonde du flux de données de votre processus.

Autres conseils

Le code suivant définit un type fixe, en utilisant des nombres entiers que sa représentation interne. Les ajouts et les soustractions sont effectuées simplement avec les opérateurs de + et -. Est réalisée en utilisant la multiplication de la macro MULT définie.

#include <stdio.h>
typedef int Fixed;

#define FRACT_BITS 16
#define FRACT_BITS_D2 8
#define FIXED_ONE (1 << FRACT_BITS)
#define INT2FIXED(x) ((x) << FRACT_BITS)
#define FLOAT2FIXED(x) ((int)((x) * (1 << FRACT_BITS))) 
#define FIXED2INT(x) ((x) >> FRACT_BITS)
#define FIXED2DOUBLE(x) (((double)(x)) / (1 << FRACT_BITS))
#define MULT(x, y) ( ((x) >> FRACT_BITS_D2) * ((y)>> FRACT_BITS_D2) )

J'utilisais le code ci-dessus pour représenter des fractions dans mon algorithme de traitement d'image. Il a été plus rapide que la version qui utilisait double et les résultats étaient presque exactement la même chose.

La plupart des DSP toolchains comprennent les bibliothèques pour l'émulation à virgule flottante dans le logiciel. Ce sera lent, mais vous devez d'abord construire votre code avec le support à virgule flottante, profil, puis de voir s'il y a seulement quelques endroits que vous devez convertir à point fixe pour obtenir des performances suffisantes. Vous aurez aussi besoin d'avoir les choses à virgule flottante en cours d'exécution pour fournir une comparaison que vous le port à point fixe, pour vous assurer que vous avez rien perdu dans le processus.

Si le code C utilise très rarement doubles / à faible densité, alors vous pourriez être en mesure d'utiliser une bibliothèque d'émulation de virgule flottante sans provoquer votre code C pour exécuter 10X plus lent à 100X. Si ne veulent pas que ce coup de performance et il y a beaucoup de opérations en virgule flottante, et vous savez l'échelle et la précision nécessaire à chaque opération arithmétique et à stocker pour chaque entrée réaliste, alors vous pourriez être en mesure de convertir chaque opération arithmétique, manuellement, à il utilisé à l'échelle entier types et les opérations de données. Mais l'analyse des besoins de précision est, en général, non trivial pour le code de type DSP. Il existe de nombreuses méthodes DSP et numériques manuels chapitres sur le sujet.

Il y a quelques bibliothèques là-bas qui peut le faire pour vous. Il est plus probable, cependant, la PSP pour votre appareil devrait inclure une sorte de bibliothèque de mathématiques. Il doit être documenté. Vous devrez probablement réécrire certains votre code, parce que les structures de contrôle que vous utilisez lorsque vous faites l'arithmétique primitive basée à virgule flottante ne peut pas donner un sens lorsque vous utilisez l'API fournie par votre PSP.

Par exemple - vous pouvez convertir cette

double arraysum = 0.0;
for (int i = 0; i < arraylen; i++) 
{
    arraysum += array[i];
}

à cette

psp_decimal_t arraysum;
if (0 != psp_sum_elements(&array, arraylen, &arraysum))
{
    printf("error!");
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top