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 :

comment obtenir les mêmes valeurs Random en VBA et Java ?


Sujet :

Java

  1. #1
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut comment obtenir les mêmes valeurs Random en VBA et Java ?
    Bonjour,
    J'ai de grosses macros VBA qui utilisent la méthode Rnd()
    Je dois transcrire ce code en Java, j'utilise là java.util.Random
    Maintenant je voudrais vérifier que mon portage de code est ok et bien sûr les nombres aléatoires m'en empêchent a priori.
    Je me demandais comment je pouvais m'arranger pour que les valeurs aléatoires soient les mêmes en VBA et en Java ?
    Est-ce que je peux mettre un seed? Pointer vers une fonction Random commune (via une librairie tierce? via le système d'exploitation commun? ...) ? Autre moyen ?
    Merci pour votre retour,
    Cordialement,

  2. #2
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Pour un cas comme ca, j'utiliserais une ou plusieurs listes en dur (créées par Random par exemple) pour les 2 et je vérifierais que j'obtiens bien le meme résultat. L'idéal étant que les listes soient de tailles différentes (et bouclées).

    Ecrire ca dans un fichier me parait plutot pas mal.

  3. #3
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2

  4. #4
    Membre confirmé Avatar de Kazh Du
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2011
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 152
    Points : 561
    Points
    561
    Par défaut
    Rien ne te garantit que le Java et le VBA te retourne la même série de nombres générés aléatoirement même avec la même seed. Difficile de dire si ces 2 langages utilisent le même algorithme de génération de chiffres.

    Je pense (sans être expert dans le domaine) qu'il faudrait mieux passer par JUnit (pour faire de bô tests bien comme il faut) et mocker la génération de nombres aléatoires pour n'avoir que liste de nombres connus et surs, via Mockito par exemple.

  5. #5
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut
    J'avais effectivement pensé à passer par une liste de chiffre en dur mais le problème est que je devrais modifier de manière significative le code d'origine et je ne serai donc pas certain d'avoir le fonctionnement attendu. Alors que si je ne touche qu'à l'appel de Rnd() dans ce cas, c'est beaucoup plus proche de la réalité du code.
    Quand au fait que même avec un seed on ne pourrait pas garantir la même série de chiffre en VBA et en Java c'est tout là ma question justement d'arriver à trouver un moyen qui garantisse cela, en impactant le moins possible le code.

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Il n'est pas normal que ton code dépende la série aléatoire :
    1. pourquoi est-elle aléatoire dans ce cas ? si le code est adapté à une série de nombres aléatoires pour être prévisible, autant qu'il soit prévisible directement
    2. rien ne garantit que la fonction de génération VBA ne soit pas modifiée à l'avenir, pour diverses raisons. Ton programme ne pourrait ne plus fonctionner alors, mêm en VBA.

  7. #7
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Je vais essayer d'adapter ce code en Java.
    Petite question cependant, comment transcrire 0x43fd43fdL en Java ? Je vois que c'est un Long avec le L final mais 0x fait référence a de l'hexa il me semble, du coup sais-tu quelle est l'équivalence en Java s'il te plaît ?

  8. #8
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par jmclej Voir le message
    Petite question cependant, comment transcrire 0x43fd43fdL en Java ? Je vois que c'est un Long avec le L final mais 0x fait référence a de l'hexa il me semble, du coup sais-tu quelle est l'équivalence en Java s'il te plaît ?
    0x43fd43fdL

  9. #9
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Il n'est pas normal que ton code dépende la série aléatoire :
    D'après ce que j'ai compris, il a porté du code de VBA vers Java. Maintenant, il veut verifier s'il n'a pas fait d'erreur. Pour ca, il veut tester avec les memes entrées s'il obtient la meme sortie. Ca me parait pas idiot comme idée.

  10. #10
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par hwoarang Voir le message
    Ca me parait pas idiot comme idée.
    Oui, oui, bien sûr. Ce n'est pas par rapport aux tests que je disais ça. C'est le fait que le programme VBA ne fonctionnerait pas avec une séquence aléatoire quelconque qui est étrange pour moi.

  11. #11
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    0x43fd43fdL
    trop facile... merci ;-)
    J'ai porté le code en Java et ça donne ça :
    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
    //0x50000L = 327680
    		//0x43fd43fdL = 1140671485
    		//0xc39ec3L = 12820163
    		//0xffffffL = 2^24 - 1 = 16777215
     
    		//unsigned long       rndVal;
    		//rndVal = 0x50000L;
    		BigInteger rndVal = BigInteger.valueOf(327680);
     
    		int i;
    		float rndFloat;
     
    		for (i = 0; i < 10; i++) {
    			//rndVal = (rndVal * 0x43fd43fdL + 0xc39ec3L) & 0xffffffL;
    			rndVal = ((rndVal.multiply(BigInteger.valueOf(1140671485))).add(BigInteger.valueOf(12820163))).and(BigInteger.valueOf(16777215));
    			//rndFloat = (float)rndVal / (float)16777216.0;
    			rndFloat = rndVal.floatValue() / (float)16777216.0;
    			//printf("Value is %.15f\n", rndFloat);
    			System.out.println("Value is " + rndFloat);
    		}
    		System.out.println();

  12. #12
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut
    Citation Envoyé par hwoarang Voir le message
    D'après ce que j'ai compris, il a porté du code de VBA vers Java. Maintenant, il veut verifier s'il n'a pas fait d'erreur. Pour ca, il veut tester avec les memes entrées s'il obtient la meme sortie. Ca me parait pas idiot comme idée.
    Voilà exactement, tu as su dire sûrement plus clairement que moi mon intention :-)

  13. #13
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Oui, oui, bien sûr. Ce n'est pas par rapport aux tests que je disais ça. C'est le fait que le programme VBA ne fonctionnerait pas avec une séquence aléatoire quelconque qui est étrange pour moi.
    Je n'ai pas dit ça (ou mal exprimé en voulant être trop précis et du coup confus, c'est pas impossible... :-) ). Le programme fonctionne avec n'importe quelle séquence de chiffre bien entendu, j'ai juste besoin de la même séquence en VBA et en Java afin de vérifier que l'on obtient les même résultats globaux au final.
    Et maintenant j'arrive bien à générer la même séquence de chiffre en transposant le code de la page vers laquelle tu m'as pointé, merci beaucoup!

  14. #14
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par jmclej Voir le message
    trop facile... merci ;-)
    J'ai porté le code en Java et ça donne ça :
    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
    //0x50000L = 327680
    		//0x43fd43fdL = 1140671485
    		//0xc39ec3L = 12820163
    		//0xffffffL = 2^24 - 1 = 16777215
     
    		//unsigned long       rndVal;
    		//rndVal = 0x50000L;
    		BigInteger rndVal = BigInteger.valueOf(327680);
     
    		int i;
    		float rndFloat;
     
    		for (i = 0; i < 10; i++) {
    			//rndVal = (rndVal * 0x43fd43fdL + 0xc39ec3L) & 0xffffffL;
    			rndVal = ((rndVal.multiply(BigInteger.valueOf(1140671485))).add(BigInteger.valueOf(12820163))).and(BigInteger.valueOf(16777215));
    			//rndFloat = (float)rndVal / (float)16777216.0;
    			rndFloat = rndVal.floatValue() / (float)16777216.0;
    			//printf("Value is %.15f\n", rndFloat);
    			System.out.println("Value is " + rndFloat);
    		}
    		System.out.println();
    On doit pouvoir se passer des BigInteger je pense :
    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
    public class RandomVB {
     
    	public static void main(String[] args) {
    		RandomVB random= new RandomVB();
    		for(int i=0; i<10; i++) {
    			System.out.println("Value is " + random.nextFloat());
    		} 
    	}
     
    	private final static long a = 0x43fd43fdL;
    	private final static long c = 0xc39ec3L;
    	private final static long mod = 2<<24-1;
    	private final static float div = 2<<24;
    	private long seed;
     
    	public RandomVB() {
    		this(0x50000L);
    	}
     
    	public RandomVB(long seed) {
    		this.seed = seed; 
    	}
     
    	public float nextFloat() {
     
    		seed = ((seed * a + c) % mod);  
    		return (seed<<1) / div;
     
    	}
     
    	public int nextInt() {
    		return nextInt(Integer.MAX_VALUE);
    	}
     
    	public int nextInt(int value) {
    		return (int)(nextFloat()*value);
    	}
     
    	public long nextLong() {
    		return nextLong(Long.MAX_VALUE);
    	}
     
    	public long nextLong(long value) {
    		return (long)(nextFloat()*value);
    	} 
     
    }

  15. #15
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    415
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 415
    Points : 138
    Points
    138
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    On doit pouvoir se passer des BigInteger je pense :
    Effectivement, je viens d'essayer d'implémenter ta solution et sur les 100 1ers Randoms on a bien la même chose en tout cas.
    Après pour être honnête je ne maîtrise pas suffisamment les impacts de ces aspects de tailles long, unsigned long, biginteger, décalage à gauche, décalage à droite des bits, etc... donc j'ai cherché à coller au plus proche du code fourni par Microsoft. Et j'ai trouvé que l'équivalent de "Unsigned Long" était BigInteger (on peut faire différemment apparemment à partir de Java 1.8 mais je suis en 1.7 en ce qui me concerne). J'ai cru comprendre que Long peut stocker des chiffres inférieurs à Unsigned Long et je me dit que cela à un impact lorsqu'il s'agit de générer des chiffres aléatoires comme dans mon cas.
    Quel est le "problème" en fait avec BigInteger?

Discussions similaires

  1. Réponses: 7
    Dernier message: 09/07/2011, 23h06
  2. Réponses: 1
    Dernier message: 27/08/2008, 21h34
  3. 2 variables qui pointent vers les mêmes valeurs: comment l'éviter?
    Par skystef dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 03/04/2008, 11h51
  4. Réponses: 5
    Dernier message: 19/07/2005, 21h54
  5. Comment obtenir les Handles des boutons systèmes de Windows ?
    Par Desraux dans le forum API, COM et SDKs
    Réponses: 6
    Dernier message: 22/12/2004, 22h20

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