2016-11-03 1 views
1

Le processeur ARM Cortex-M4F a une instruction qui charge une constante immédiate dans un registre en virgule flottante, comme dans:Algorithme pour ARM acceptable Cortex-M4F instantané à virgule flottante?

 VMOV S0,+6.75 

Cependant, la valeur de l'est limité constante et doit être égal à une valeur qui peut être exprimé par +/- mx 2 -n, où m est un nombre entier compris entre 16 et 31 et n est un nombre entier dans l'intervalle 0-7. Par exemple, l'instruction ci-dessus fonctionne parce que vous pouvez obtenir 6,75 avec m = 27 et n = 2. Je voudrais vraiment trouver un algorithme qui détermine si un nombre réel particulier peut être représenté de cette façon, et si oui, donne les valeurs correspondantes de m et n.

Des idées brillantes?

Dan

+0

FWIW, je ne sais pas la réponse, mais je _can_ déduire qu'il doit exister une façon simple, parce que c'est précisément ce que les assembleurs doivent faire quand ils encodent une telle instruction en premier lieu.Pour sauver un peu de problème, [voici un assembleur] (https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gas/config/tc-arm.c;h= 061aaa8222d03f6e52953ae3fdcd1e047d7bbee3; hb = HEAD # l4995) - quel que soit le vaudou qui semble impliquer d'avoir le nombre comme un flotteur régulier IEEE754 pour commencer, ce qui signifie que vous devrez commencer par comprendre s'il peut être représenté comme l'un de ceux-là. – Notlikethat

+0

Si vous avez la bibliothèque mathématique C disponible, frexp pourrait être un moyen de commencer – dmuir

Répondre

0

En fait, je na pas tester, mais il semble assez facile. Prenez le nombre multipliez-le par 1, 2, 4, 8, etc, jusqu'à 0x80. Cela entraîne-t-il un nombre entier/entier compris entre 16 et 31? dans ce cas 6,75 * 4 = 27. si m est 27 n est 2. 2,8750 * 8 = 23 m est donc 23, n est 3.

float vut; //value under test 
float f; 
unsigned int nn; 
int n; 
unsigned int m; 

for(nn=0x01;nn<=0x80;nn<<=1) 
{ 
    f=vut*n; 
    if(is_an_integer_no_fraction(f)) 
    { 
     m=f; 
     if((m>=16)&&(m<=31)) 
     { 
      n=nn; 
      n=-n; 
      //FOUND m and n 
      break; 
     } 
    } 
} 
if(nn>=0x80) 
{ 
    //NOPE doesnt work 
} 
else 
{ 
    //YEP found m and n 
} 
0

Si vous le souhaitez, vous pouvez le faire en passant à un flotteur régulier de précision simple, puis examinant ses bits. Tous les nombres représentables par votre formule sont également représentables en tant que flottants, mais seulement certains flottants sont représentables par votre formule.

Pour tout nombre représentable par votre formule, l'exposant est garanti entre -3 (16 * 2^-7) et +4 (16 * 2^0) inclusivement et la mantisse est garantie d'avoir des zéros dans tous mais les quatre premiers bits après la décimale. Ainsi, l'octet contenu dans les bits 23-30 inclus doit avoir une valeur comprise entre 124 et 131 inclusivement et les bits 0-18 inclus doivent être nuls. Pour déterminer n, soustrayez l'octet exposant de 131; Pour déterminer m, utilisez les bits 19-22 inclus et ajoutez 16.

Notez que tout cela suppose que vous savez que le nombre peut être stocké comme un flottant en premier lieu.

0

Il ne s'agit que de 8 * 16 * 2 = 256 valeurs, il est donc facile d'utiliser une table de hachage. En Python:

D = set() 

for m in range(16,32): 
    for n in range(8): 
     x = m*2.0**-n 
     D.add(x) 
     D.add(-x) 

def iscortexable(x): 
    return x in D 

Donne

>>> iscortexable(6.75) 
True 
>>> iscortexable(8.75) 
False 

Une façon plus raisonnée utiliserait frexp

from math import frexp 

def iscortexable(x): 
    if x == 0: 
     return False 
    m, e = frexp(x) # 0.5 <= m < 1 
    m = m*32   # 16 <= m < 32 
    n = -(e - 5) 
    return m.is_integer() and 0 <= n <= 7 
0

Merci à vous tous pour vos excellentes suggestions. Rétrospectivement, j'aurais probablement dû fournir un peu plus de contexte. J'enseigne un cours sur la programmation en langage assembleur aux étudiants de deuxième année et j'utilise le Cortex-M4F comme plate-forme cible. J'essayais de trouver un moyen simple pour eux de savoir quand un VMOV immédiat était possible. J'ai finalement réalisé (avec un certain embargo) qu'il y avait si peu de combinaisons de m et n que la meilleure solution était d'imprimer simplement toutes les combinaisons sous la forme d'un document. :-)

Merci encore!

Dan -