12
votes

Conversion de la chaîne binaire 32 bits avec integer.parseint échoue

Pourquoi cette partie du code échoue-t-elle:

Integer.parseInt("11000000000000000000000000000000",2);

Exception in thread "main" java.lang.NumberFormatException: For input string: "11000000000000000000000000000000"


1 commentaires

La réponse acceptée ici n'est pas correcte. La même question avec des réponses correctes peut être trouvée ici: Java, long.Parse Binary String


4 Réponses :


17
votes

Votre code échoue car il essaie d'analyser un numéro qui nécessiterait 33 bits pour stocker en tant qu'oeur entier signé.

Un int est une valeur de 32 bits dans la représentation du complément de deux, où le premier bit indiquera le signe du nombre et que le 31 restant bient la valeur du numéro. (-Sish.) Java prend uniquement en charge les entiers signés et parseint () et les amis ne sont pas censés analyser les modèles de bits de complément de deux - et donc interpréter le 1 ou (éventuellement implicite) 0 à la 32ème position de droite comme panneau. Ils sont destinés à soutenir l'analyse d'une reprémentatation lisible par l'homme, qui est un optionnel - (ou + ) pour le panneau, suivi de la valeur absolue d'un numéro. < / p>

Dans ce contexte, c'est une fausse intuition qui vous amène à attendre du comportement que vous décrivez: Si vous analysez autre base à part la base 2 (ou peut-être l'autre puissance de deux couramment utilisée. Bases), vous attendez-vous au premier chiffre de l'entrée pour affecter le panneau? Évidemment, vous ne voudriez pas; Ayant, disons, parseint ("2147483648") retour -2147483648 par design serait des niveaux de php de fou.

Les bases de la puissance de deux boîtes de spécialisation se sent également impair. Mieux vaut avoir une approche distincte de la manipulation des motifs de bits, par exemple celui de cette réponse .


9 commentaires

Je viens de relire les Javadocs pour Integer.parseint () encore une fois, et je ne vois rien dire "cela n'utilise pas de chiffres négatifs" (en fait, il dit "signé INT"), ou au moins explicitement ", ce ne pas analyser les modèles de bits ". En fait, comme décrit dans les Javadocs, on pourrait affirmer qu'une chaîne de 55 0 devait analyser à 0. Je considère le comportement d'un bug. Mais ne ressemble pas à l'oracle ou à OpenJDK le réparera. Voyez-vous quelque chose dans les Javadocs pour contredire cela?


@ user949300 parseint analysera des nombres binaires négatifs, si vous les transmettez en tant que "-10010110". Il analysera également une chaîne de 55 zéros, car il s'agit d'une valeur valide pour un int . Un nombre de 32 bits sans zéros de premier plan n'est pas une valeur valide int , et c'est donc rejeté.


@ user949300 Qu'est-ce que je veux dire par "ne pas analyser les modèles de bits" est que `integer.parseint (str, 2)" analyse est un nombre écrit à la base 2. Il n'utilise pas une représentation binaire complémentaire de deux 32- Bit Integer. Je ne considère pas cela un bug, je considère simplement cela quelque chose que la méthode n'est pas destinée à analyser les représentations textuelles "humaines" de nombres dans des bases arbitraires.


@Interdial hmm, je n'ai pas pensé que 55 Zeros travaillaient. Merci d'avoir testé! Je pense que c'est étrange que 55 0 ans fonctionne et 32 ​​1 ne le font pas, mais c'est comme ça.


Java représente les entiers dans 2's-complément , pas de la signature.


Pour soutenir ce que l'Oli Charlesworth vient de dire, examinez cette question: Java, longue .Parse String Binary


@Olicharlesworth Droite, j'ai reformulé la réponse.


@jlordo soutenant son commentaire par un autre commentaire de son dicton dit que cette réponse est fausse, juste ailleurs? Je pensais que cela ne fonctionne que dans les arts libéraux et le punditrie;)


@Millimoose: La question d'hier nous a apporté ici, et après avoir vu des commentaires d'Oli, je pensais qu'il serait juste de lier à la nouvelle question. N'était pas signifié comme une infraction et mon -1 est maintenant un +1;)



4
votes

Selon le docs , la valeur max d'un entier est 2 ^ 31-1 . Qui, en binaire, est:

11111111111111111111111111111

En d'autres termes, 31 1 's dans une rangée.


0 commentaires

0
votes

Même si votre chaîne, "11 ..... beaucoup de zéros" est une représentation binaire légale d'un entier négatif, integer.parseint () échoue sur elle. Je considère cela un bug.

Ajout d'un peu de légèreté, car sur relire ce post, il semble trop pédant, je comprends que Oracle ne plaisant probablement pas beaucoup si je pense que c'est un bug ou non. : -)

Vous pouvez essayer: xxx

vous devriez voir

3221225472 -> -1073741824

Vous devez parfois le faire avec des couleurs en fonction de la façon dont ils sont stockés en tant que texte.

BTW, une chose exacte peut arriver si vous analysez une représentation hexagonale et Vous analysez un nombre négatif comme "88888888". Vous devez utiliser long.parelong () puis convertir.


1 commentaires

Ce n'est pas un bug. Javadoc déclare que si vous voulez un entier négatif de parseint () , vous devez avoir un ASCII moins - au début de la chaîne. Demandez à cette question: Java, longue.Parse Binary String



2
votes

Ceci est parce que pour Integer.parseint "1100000000000000000000000000000000" n'est pas une représentation complémentaire de deux -1073741824, mais une valeur positive 3221225472 qui ne s'intègre pas dans la plage de valeurs INT -2147483648 à 2147483647. Mais nous pouvons analyser la représentation de la chaîne binaire de deux BigInteger: xxx

ceci donne attendu -1073741824 résultat


0 commentaires