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

Java Discussion :

récupérer valeur d'un double dans 2 float


Sujet :

Java

  1. #1
    Membre éclairé Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Par défaut récupérer valeur d'un double dans 2 float
    Bonjour,
    j'ai un :
    double x;
    je récupère sa première moitié dans un float :
    float a = (float)x;
    je cherche à récupéer la 2ème moitié, je fais comment ??

    Merci bcp

  2. #2
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 698
    Par défaut
    J'ai du mal à comprendre l'idée que tu as derrière la tête. Pouquoi veux tu séparrer un Double en deux float?
    Ça ne me parait compliqué et sans intérêt.

  3. #3
    Membre éclairé Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Par défaut
    le double il est codé sur 8 octets le float est sur 4, j'ai besoin de mettre chaque 4 octets du double à part

  4. #4
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 698
    Par défaut
    C'est d'ailleurs impossible de le faire de manière exacte en effet:
    les floats ont 23 bits pour la mantisse, 8 bits pour l'exposant et 1 bit pour le signe alors que les doubles ont 52 bits pour la mantisse, 11 bits pour l'exposant, 1 bit pour le signe.

    Dont même avec 2 float, tu ne pourras pas stoker toute la mantisse.

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    long xL = Double.doubleToLongBits(x);
     
    int xI1 = (int)xL;
    int xI2 = (int)(xL >> 32);
     
    float y1 = Float.intBitsToFloat(xI1);
    float y2 = Float.intBitsToFloat(xI2);

    Mais comme on a déjà dit, faire du C++ en Java, ça ne vas pas super bien...

  6. #6
    Membre éclairé Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Par défaut
    en C++ c'est possible en utilisant un pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
            double x;
            float a, b;
            float *ip;
    	ip = (float)&x;
    	a = (*ip);
    	++ip;
    	b = (*ip);
    mais en java ????

  7. #7
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 698
    Par défaut
    Si c'est juste séparer en plusieurs parties sans te soucier de la valeur il est plus simple de passer par doubleToLongBits() qui te retournera un long. Tu peux ainsi découper le découper facilement en morceaux avec un masque et des décalages binaire.

    Tu peux ensuite reconstruire le double avec longBitsToDouble()

  8. #8
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 698
    Par défaut
    En suivant ton exemple, ca donnerait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            double x;
            long l = Double.doubleToLongBits(x);
            int a =  ( l >> 32) & 0xFFFFFFFF;
            int b = l & 0xFFFFFFFF;
    Je pense que tu peux garder le résultat dans des int car comme les float ils font 32 bit. De toute façon les valeurs de tels flottants n'auraient absolument aucun sens.
    Mais si tu tiens tout de même à avoir du float, tu peux utiliser Float.intBitsToFloat()

  9. #9
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par psycho_xn Voir le message
    en C++ c'est possible en utilisant un pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
            double x;
            float a, b;
            float *ip;
    	ip = (float)&x;
    	a = (*ip);
    	++ip;
    	b = (*ip);
    mais en java ????
    Même en c++, ce code est erroné. Le choix des type a et b est erroné et ils ne stockeront jamais, dans ce cas, un float qui aura du sens par rapport à x. De plus, rien dans les spécification c++ ne te dit que le float est la moitié (en taille bits) d'un double. Tout ce que dit la spécification C++ c'est que taille(float)<=taille(double)<=taille(long double).
    Si ce code fonctionne chez toi, c'est jsute parce que tu as la chance d'utiliser un compilateur/une architecture utilisant une taille de float deux fois inférieure à la taille d'un double.
    Rien ne sert d'essayer de transcrire du C++ en java et encore moins du C++ erroné. La solution de uther d'ailleurs est la plus propre pour récupérer et manipuler les bits d'un double.

  10. #10
    Membre éclairé Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Par défaut
    Citation Envoyé par Uther Voir le message
    En suivant ton exemple, ca donnerait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            double x;
            long l = Double.doubleToLongBits(x);
            int a =  ( l >> 32) & 0xFFFFFFFF;
            int b = l & 0xFFFFFFFF;
    j'ai pas bien compris la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     int a =  ( l >> 32) & 0xFFFFFFFF;
    est-ce que ceci récupère les 32 bits dans le int et & 0xFFFFFFFF c pourquoi faire ??

  11. #11
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 698
    Par défaut
    le >> déplace tous les bits du nombre de 32 positions vers la droite(comme en C). Ainsi les 4 octets de poids vont remplacer les octets de poids faible.

    Le "& 0xFFFFFFFF" était pour effacer les 4 octets de poids fort mais en y réfléchissant, c'est inutile vu que la conversion du long(8 octets) en int(4 octets), les fait automatiquement disparaitre.

    Le code proposé par dingoth est donc en effet plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    long xL = Double.doubleToLongBits(x);
     
    int xI1 = (int)xL;
    int xI2 = (int)(xL >> 32);

  12. #12
    Membre éclairé Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Par défaut
    Citation Envoyé par dingoth Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    long xL = Double.doubleToLongBits(x);
     
    int xI1 = (int)xL;
    int xI2 = (int)(xL >> 32);
     
    float y1 = Float.intBitsToFloat(xI1);
    float y2 = Float.intBitsToFloat(xI2);

    Mais comme on a déjà dit, faire du C++ en Java, ça ne vas pas super bien...
    j'ai essayé ce code et ça marche, sauf que il y a une perte de précision dans le résultat

    au lieu de me donner la résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    272008320221930670000000.000000
    ça me génère
    est ce que c'est du à la première conversion en Long ???????

  13. #13
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 698
    Par défaut
    Normalement avec ce code, il ne devrait pas y avoir de perte de précision. Es-tu sur que ce n'est pas ta fonction d'affichage fait un d'arrondi?

  14. #14
    Membre éclairé Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Par défaut
    Citation Envoyé par Uther Voir le message
    Normalement avec ce code, il ne devrait pas y avoir de perte de précision. Es-tu sur que ce n'est pas ta fonction d'affichage fait un d'arrondi?
    j'ai mis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println("y1=  "+y1)
    pour l'affichage

  15. #15
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 698
    Par défaut
    Tu as du faire une erreur en réassambant les deux parties. Je n'ai pas pas d'écart avec ce code:
    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
        public static void main(String[] args) {
            double x=272008320221930670000000.000000;
     
            //séparation
            long l = Double.doubleToLongBits(x);
            int a =  (int)( l >> 32);
            int b = (int) l ;
     
            //recolage
            long l2 = ((long)a<<32)|(b&0xFFFFFFFFL);
            double y=Double.longBitsToDouble(l2);
     
            System.out.println("x -> " + x);
            System.out.println("y -> " + y);
     
        }

  16. #16
    Membre éclairé Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Par défaut
    finalement je pense que c'est uniquement du à l'affichage.
    Merci beaucoup pour l'aide.
    Maintenant quand j'essais avec un Integer et short
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Integer x = 214748364;
     
            short w1 = x.shortValue();
            short w2 = (short)(x >> 16);
    la w2 donne la bonne valeur contrairement au w1, une idée ???

  17. #17
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par psycho_xn Voir le message

    la w2 donne la bonne valeur contrairement au w1, une idée ???

    Citation Envoyé par javadoc
    shortValue

    public short shortValue()

    Returns the value of this Integer as a short.

    Overrides:
    shortValue in class Number

    Returns:
    the numeric value represented by this object after conversion to type short.
    en claire ton code est l'équivalent de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Integer x = 214748364;
    short w1 = (short)x;
    short w2 = (short)(x >> 16);
    Il me semble donc normal qu'ils retournent des valeurs différentes.

  18. #18
    Membre éclairé Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    en claire ton code est l'équivalent de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Integer x = 214748364;
    short w1 = (short)x;
    short w2 = (short)(x >> 16);
    Il me semble donc normal qu'ils retournent des valeurs différentes.
    Je pense qu'on s'est mal compris. moi je cherche à récupérer les 2 premiers octets d'un int dans un short, et les 2 derniers dans un autre short, la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    short w2 = (short)(x >> 16)
    me récupère bel et bien les 2 derniers octets, mais ne me donne pas le bon résultat des 2 premiers octets

  19. #19
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 698
    Par défaut
    Le code que tu as posté est correct. Le problème doit venir de la façon dont tu utilises w1 et w2.

    Je penses en effet que tu as un problème de copnversion. Il faut savoir qu'en Java, les type de taille inférieure à int sont automatiquement convertis en int quand on fait des opération avec. Et comme tous les nombre sont signés, la convertion peut surprendre:
    • w2 vaut 0xcccc. C'est un nombre négatif(isupérieu ou égal à 0x8000) et il est donc converti en 0xffffcccc.
    • w1 vaut 0xccc. C'est un nombre positif(inférieur à 0x8000) et il est convertie en 0x00000ccc

    Ceci expliquerait pourquoi tu ne vois pas de problème avec w1.
    Si tu veux une conversion en entier sans tenir compte du signe utilises (w1 & 0xFFFF) et (w2 & 0xFFFF).

  20. #20
    Membre éclairé Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Par défaut
    Citation Envoyé par Uther Voir le message
    Le code que tu as posté est correct. Le problème doit venir de la façon dont tu utilises w1 et w2.

    Je penses en effet que tu as un problème de copnversion. Il faut savoir qu'en Java, les type de taille inférieure à int sont automatiquement convertis en int quand on fait des opération avec. Et comme tous les nombre sont signés, la convertion peut surprendre:
    • w2 vaut 0xcccc. C'est un nombre négatif(isupérieu ou égal à 0x8000) et il est donc converti en 0xffffcccc.
    • w1 vaut 0xccc. C'est un nombre positif(inférieur à 0x8000) et il est convertie en 0x00000ccc

    Ceci expliquerait pourquoi tu ne vois pas de problème avec w1.
    Si tu veux une conversion en entier sans tenir compte du signe utilises (w1 & 0xFFFF) et (w2 & 0xFFFF).
    je suis un peu perdu avec les 0x... mais j'ai compris ton idée.
    donc pour corriger mon code et faire la conversion en ignorant le signe je met :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int x = 2147483646;
     
            short w1 = (short)(x & 0xFFFF);
            short w2 = (short)(x >> 16);
    ??? je me trompe surement car il n'y a rien eu de changé dans mon résultat

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. récupérer valeur "alert" pour utilisation dans un script php
    Par mauyebo dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 24/08/2008, 17h22
  2. récupérer valeur champ libre formulaire dans un état
    Par stagolee dans le forum VBA Access
    Réponses: 1
    Dernier message: 10/01/2008, 13h18
  3. Réponses: 10
    Dernier message: 20/06/2007, 18h02
  4. [c#]récupérer valeur d'un TextBox dans un Repeater
    Par Filippo dans le forum ASP.NET
    Réponses: 1
    Dernier message: 20/03/2007, 10h48
  5. [MySQL] récupérer valeur d'une variable dans une autre table
    Par Tee shot dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 15/03/2007, 22h07

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