Bonjour,
J'ai besoin d'une variable sur 64 bits non signé. Je voudrais savoir si c'est possible.
Les variables de type long sont signé. Est ce qu'il existe, comme ne C, d'avoir un unsigned long?
Merci
Bonjour,
J'ai besoin d'une variable sur 64 bits non signé. Je voudrais savoir si c'est possible.
Les variables de type long sont signé. Est ce qu'il existe, comme ne C, d'avoir un unsigned long?
Merci
Une petite recherche google :
http://darksleep.com/player/JavaAndUnsignedTypes.html
Une possibilité est de le stocker sous forme d'un byte[] de 8 bytes.
(Puis quand on y réfléchit, c'est la même chose qu'un short[] de 4 shorts, ou un int[] de 2 ints. Puis quand on y réfléchit, on peut utiliser directement un long, à condition de le parser et le formater soi-même pour faire comme s'il était non signé, et de ne pas utiliser les opérateurs de comparaison.)
Autre possibilité : BigInteger, qui peut représenter autant de bits qu'on veut. Problème : il faut gérer soi-même le fait qu'il ne doit pas dépasser 64 bits positifs, et qu'il ne doit pas être négatif.
la seule différence entre un 64 bits signé et un 64 bits non signé c'est le comportement de la comparaison et des opération division, multiplication. Ainsi que le casting (32 bits signé -> 64 bits signé ne donne pas le même résultat que 32 bits non signé -> 64 bits non signée pour la même série de bits).
Pour le reste c'est identique, donc la question est surtout, quel est le besoin sous-jacent?
Salut,
J'ai eu le même problème que tupac25: devoir utiliser un nombre qui dépasse la valeur max d'un Long...
Effectivement, difficile d'utiliser le type de taille supérieure au Long... J'ai donc utilisé le BigInteger, mais maintenant, j'ai un gros problème de perfo...
J'utilise entre autres la méthode shiftRight() à la place de l'opérateur >>.
Appelée des milliers de fois, la vitesse de génération de mes données (écriture dans un fichier, mais ça donne une idée) passe de quelques Mo toutes les 2/3 secondes, à une dizaine de Ko toutes les 10/20 secondes.
Cette baisse de perfo est-elle normale ? Y a-t-il un moyen de contourner/améliorer ça ?
Merci !
Hélas oui. Tu n'utilises plus des types de base et des opérateurs, tu utilises des instances d'objet et des appels de méthodes.
Utiliser les long normaux et faire comme s'ils n'étaient pas signés. L'addition et la soustraction fonctionnent pareil, le left-shift aussi.
Le right-shift c'est un peu plus compliqué, si le bit de poids fort était à 1 (nombre négatif,) il met à nouveau 1 à ce bit après décalage. Il faut donc le forcer à zéro.
rien à forcer, java fourni un opérateur de décalage à droit non signé, qui ne reproduit pas le bit de signe, c'est '>>>'.
Exemple:
Me sort bien des nombres positifs:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 long l=-1; /*FFFFFFFFFFFFFFFF*/ for (int i=0; i< 64; i++){ System.out.format("%X %d\n", l>>>i,l>>>i); }
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 FFFFFFFFFFFFFFFF -1 7FFFFFFFFFFFFFFF 9223372036854775807 3FFFFFFFFFFFFFFF 4611686018427387903 1FFFFFFFFFFFFFFF 2305843009213693951 FFFFFFFFFFFFFFF 1152921504606846975 7FFFFFFFFFFFFFF 576460752303423487 3FFFFFFFFFFFFFF 288230376151711743 1FFFFFFFFFFFFFF 144115188075855871 FFFFFFFFFFFFFF 72057594037927935 7FFFFFFFFFFFFF 36028797018963967 3FFFFFFFFFFFFF 18014398509481983 1FFFFFFFFFFFFF 9007199254740991 FFFFFFFFFFFFF 4503599627370495 7FFFFFFFFFFFF 2251799813685247 3FFFFFFFFFFFF 1125899906842623 1FFFFFFFFFFFF 562949953421311 FFFFFFFFFFFF 281474976710655 7FFFFFFFFFFF 140737488355327 3FFFFFFFFFFF 70368744177663 1FFFFFFFFFFF 35184372088831 FFFFFFFFFFF 17592186044415 7FFFFFFFFFF 8796093022207 3FFFFFFFFFF 4398046511103 1FFFFFFFFFF 2199023255551 FFFFFFFFFF 1099511627775 7FFFFFFFFF 549755813887 3FFFFFFFFF 274877906943 1FFFFFFFFF 137438953471 FFFFFFFFF 68719476735 7FFFFFFFF 34359738367 3FFFFFFFF 17179869183 1FFFFFFFF 8589934591 FFFFFFFF 4294967295 7FFFFFFF 2147483647 3FFFFFFF 1073741823 1FFFFFFF 536870911 FFFFFFF 268435455 7FFFFFF 134217727 3FFFFFF 67108863 1FFFFFF 33554431 FFFFFF 16777215 7FFFFF 8388607 3FFFFF 4194303 1FFFFF 2097151 FFFFF 1048575 7FFFF 524287 3FFFF 262143 1FFFF 131071 FFFF 65535 7FFF 32767 3FFF 16383 1FFF 8191 FFF 4095 7FF 2047 3FF 1023 1FF 511 FF 255 7F 127 3F 63 1F 31 F 15 7 7 3 3
OK. Je pense que cette solution m'intéresse parce que je ne peux pas avancer autrement.
Mais j'avoue que c'est un peu flou...
Par exemple j'ai :
La valeur en décimal de la chaîne "toto" dépasse la valeur max des long, et donc le parseLong plante.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 String toto = "FDE4676C25579879005FC43C"; long R1 = new Long(Long.parseLong(toto, 16));
Je ne vois pas comment faire comme s'il était non signé. C'est possible ?
Tiens, j'étais persuadé que c'était un shift circulaire. Merci pour l'info.
Ah, pardon, je pensais que tes nombres étaient non-signés mais restaient dans les 64 bits, comme pour tupac25.Envoyé par LinoaHeart
Non, là c'est mort, il vaut mieux se contenter de BigInteger. Ça pourrait être plus rapide en jouant directement avec des tableaux de byte ou de long et en les réutilisant autant que possible... Mais ça va faire du code compliqué et pas très robuste.
Sniffff
merci quand même![]()
Pour améliorer les performances, il faut la connaissance fonctionnelle : que représente le nombre en hexa ? Quels sont les traitements effectués dessus ?
Tu peux peut-être découper ton problème en sous problème plus petit et travailler avec des nombre plus petit. Mais c'est à toi d'analyser le fonctionnel![]()
surtout que le "parsing" n'est en général pas l'opération la plus critique, ce sont les calcul qu'on essaie de faire sur les long
Pour le parsing, tu peux y aller à la mano aussi :p
Je viens de voir que je me suis trompée en écrivant mon bout de code au-dessus :
C'est plutôt ça :Envoyé par LinoaHeart
Ça fait bien 64 bits... Désolée...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 String toto = "FDE4676C25579879"; long R1 = new Long(Long.parseLong(toto, 16));
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 /** * @param args the command line arguments */ public static void main(String[] args) { String toto = "FDE4676C25579879"; long R1 = new BigInteger(toto,16).longValue(); System.out.format("%X\n", R1); }
ok, merci
Je pense que c'est bon : j'ai donc gardé tous mes calculs tels quels, sauf le ">>" que j'ai remplacé par ">>>".
Merci encore !
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager