IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Assembleur Discussion :

Conversion fpu -> notation scientifique décimale


Sujet :

Assembleur

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 8
    Points : 8
    Points
    8
    Par défaut Conversion fpu -> notation scientifique décimale
    bonjour tout le monde,

    Voilà quelques heures que je passe a chercher comment pouvoir prendre un registre se trouvant dans le fpu et le convertir en chaine de caractères , mais en respectant la notation scientifique décimale.

    Dans le fpu les exposants utilisés sont en base 2, alors qu'il est préférable ( et plus facile a comprendre ) d'afficher les valeurs à l'ecran en utilisant la notation scientifique en base 10. Malgrès mes efforts et mes diverses tentative tout ce que je reussi à faire c'est me planter. Peut être que qqun d'ici à déjà eu affaire a ce petit contre temps, si c'est le cas merci bcp de me venir en aide parce que je commence a perdre patience malheureusement.

    J'ai déjà effectué un algorithme permettant de trouver le nombre de chiffre avant ou apres la virgule, mais le probleme est pour recuperer l'entier se trouvant a chaque fois devant la virgule pour me permettre de l'afficher.

    L'ideal serait de pouvoir effectuer un modulo ou quelques chose de ce genre mais impossible de faire en sorte que ca marche, ou ca affiche des 0 sans arret ou alors il plante carrement.

    Un grand merci a ceux qui peuvent me venir en aide.

    PS : toutes les idées sont les bienvenues, ca me donnera peut etre un declic quand à la facon de s'y prendre.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Le nombre est défini dans le fpu par la formule :

    mantisse * 2^exposant

    et tu dois le mettre sous la forme :

    manitsse' * 10^exposant'

    Alors, j'ai une solution, je ne sais pas si elle est très efficace, où s'il y a plus simple, mais elle consiste à considérer la mantisse à part, et savoir quel exposant il faut. C'est peut être ce que tu as fais. Donc résoudre l'équation :

    2^exposant = 10^x

    Donc, ce sont des exponentielles base 2 et base 10, il y a des relations, mais, je vais résoner en néperien. (Je connais pas les relations) L'équation est équivalente à :

    e^(exposant*ln(2)) = e^(x*ln(10))

    Comme la fonction ln, est injective sur IR+ :

    exposant*ln(2) = x*ln(10)

    eq à :

    x = exposant * ln(2) / ln(10)

    C'est calculable par le fpu, mais il y a un problème de précision dont je discuterais plus tard.

    Il faut pour notre problème que x soit entier. Donc, on va prendre sa partie entière n et le reste r :

    x = n + r, ou n entier relatif et 0 <= r < 1

    on a donc :

    mantisse * 2^exposant = mantisse * 10^x = mantisse * 10^n * 10^r


    La mantisse devient :

    mantisse' = mantisse * 10^r

    C'est là qu'intervient la précision de l'opération sur la division des logs. Mais j'arrive pas à calculer l'erreur, va falloir que j'y réflechisse plus.

    Cette nouvelle mantisse, tu peux la mettre sous la forme x,xxxxxx et modifiant l'exposant précedement calculé, et tu as ton nombre.


    Enfin voilà je suis désolé si ca marche mal, c'est une solution que j'ai trouvée.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    J'ai écrit un programme en C qui illustre la décomposition d'un nombre à virgule flottante au format IEEE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    #include <math>
    #include <iostream>
    using namespace std;
     
    struct Reel
    {
      union
      {
        struct
        {
          unsigned Mantisse : 23;
          unsigned Exposant : 8;
          unsigned Signe : 1;
        };
     
        unsigned Representation;
      };
    };
     
     
    void AffichageBinaire(unsigned int n, int Chiffres)
    {
      for (int i = Chiffres - 1 ; i >= 0 ; i--)
        cout << ((n & (1 << i)) ? 1 : 0);
    }
     
     
    int main()
    {
      float f = 0.487654;
      Reel r = *((Reel*)&f);
     
      cout << "Nombre Reel : " << f << endl << endl;
     
      cout << "Representation binaire : ";
      AffichageBinaire(r.Representation, 32);
      cout << endl;
     
      cout << "Sign : " << r.Signe << (r.Signe ? " (Negatif)" : " (Positif)") << endl;
     
      cout << "Normalized Significand : ";
      AffichageBinaire(r.Mantisse, 23);
      cout << " (" << r.Mantisse << ") " << endl;
     
      cout << "Biased Exponent : ";
      AffichageBinaire(r.Exposant, 8);
      cout << " (" << r.Exposant << ") " << endl << endl;
     
      cout << "Exposant Reel : " << r.Exposant - 127<< endl;
     
      float Exposant = ((r.Exposant - 127.0 - 23) * (M_LN2 / M_LN10));
      int e = (int)Exposant;
      if (e < 0)
        e--;
      float s = Exposant - e;
      cout << "Exposant base 10 : " << Exposant << endl;
      cout << "Exposant Entier : " << e << endl;
      cout << "Exposant Reste : " << s << endl << endl;
     
      int Mantisse = (r.Mantisse + 0x000800000) * pow(10, s);
      cout << "Mantisse base 10 : " << Mantisse << endl << endl;
     
      getchar();
     
      return 0;
    }
    Et pour ne pas avoir à compiler voici la sortie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Nombre Reel : 0.487654
     
    Representation binaire : 00111110111110011010110111001001
    Sign : 0 (Positif)
    Normalized Significand : 11110011010110111001001 (7974345)
    Biased Exponent : 01111101 (125)
     
    Exposant Reel : 4294967294
    Exposant base 10 : -7.52575
    Exposant Entier : -8
    Exposant Reste : 0.47425
     
    Mantisse base 10 : 48765423
    On obtient 48765423 * 10^-8 soit 0.48765423. Les deux derniers chiffres différent, mais sont au delà de la précision du simple float, donc ce n'est pas grave. Ce serait tou de même bien d'achever ce calcul d'erreur ^^

    Dans les problèmes à noter :

    - Dans ma méthode je décris le problème comme si la Mantisse était entière, or la mantisse n'est que la partie binaire située dèrrière le 1. implicite, donc, on fait comme si elle était entière, en modifiant le biased exposant non pas de -127 mais de -127 - 23 (23 chiffres derrière la virgule

    - La convertion float - > Entier du C, ne donne pas l'entier directement inférieur au nombre, alors que c'est ainsi que je l'avais posé dans la définition, il en résultait une erreur de 1 dans l'exposant et un facteur de 2 dans la mantisse pour les nombre dont le biased exposant était inférieur à 127. Le -1 pour e négatif à été ajouté à cet effet. En assembleur il existe une fonction Round du fpu paramétrable, mais je ne sais pas du tout comment elle fonctionne (et ma documentation est très avare sur le sujet)

    - J'ai employé certaines instructions comme 10 exposant x qui ne sont pas effectuées par le fpu directement, l'opération est assez complexe, composée de puissance de deux, de log base 2 et de exponentielle base 2.


    Voilà, j'espère que ca pourra être utile.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Un grand merci de vos réponses, malgrés tout je ne suis pas parvenu a faire cette conversion, mais j'ai reussi à transformer le nombre dans le fpu en base 10 tout de meme ( mais pas en notation scientifique )

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    842
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 842
    Points : 696
    Points
    696
    Par défaut
    Si tu as toujours un problème, fais en nous part.

Discussions similaires

  1. Réponses: 2
    Dernier message: 03/12/2014, 14h33
  2. conversion notation scientifique
    Par Djahny dans le forum Langage
    Réponses: 1
    Dernier message: 04/08/2007, 00h10
  3. [TP] Nombre en notation scientifique
    Par barth.pas dans le forum Turbo Pascal
    Réponses: 8
    Dernier message: 30/08/2006, 20h27
  4. Conversion en double et notation scientifique
    Par bert24 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 23/09/2005, 13h26
  5. Notation scientifique
    Par Equus dans le forum Débuter
    Réponses: 4
    Dernier message: 03/02/2005, 14h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo