5
votes

Conversion implicite Java entre int et char

Je cherche une explication sur le comportement de Java lors de la gestion des scénarios suivants. Je comprends que la table ASCII est organisée de telle sorte que la valeur du caractère 5 soit cinq positions supérieure à 0 . Cela permet de faire des calculs sur le char sans convertir en un int comme vu dans le premier exemple.

Ce que je ne comprends pas, c'est pourquoi Java semble gérer de manière incohérente quand fournir une valeur d'une table ASCII et quand faire un calcul sur les caractères comme s'il s'agissait de nombres entiers.

int y = '5' - 0 + '1'

sortie x = 5;

int y = '5' - '0' + '1'

sortie x = 53;

Maintenant, pour quelques exemples, qui introduisent de la confusion.

int x = '0' + 1 - '5'

output x = -4 p >

int x = '5'

sortie 54

int x = '5' - '0';

sortie 102

Java semble faire une conversion de type implicite, mais comment Java peut-il déduire quelle représentation de l'int / char doit-il utiliser?


5 commentaires

Tout cela semble cohérent. Si vous traduisez le caractère en leurs codes, le calcul est logique.


La différence entre «0» et «5» est 5, mais «5» a une valeur numérique de 53. char est un type entier, mais il ne correspond pas à sa représentation de caractère.


Notez que dans tous ces exemples, les char sont convertis en int avant d'effectuer les opérations.


Vous devez savoir que char est une unité de code UTF-16 et non ASCII. Java n'utilise pas ASCII (de même pour JavaScript, .NET, VB4 / 5/6 / A / Script, SQL NCHAR NVARCHAR,…). UTF-16 est l'un des nombreux encodages de caractères pour le jeu de caractères Unicode .


Merci pour cela, les 128 premiers caractères d'Unicode sont identiques à ASCII.


5 Réponses :


5
votes

Il suffit d'écrire la conversion des caractères en code ASCII (sous vos instructions)

int x = '0' + 1 - '5'
        48  + 1 - 53 = -4 

int y = '5' - 0 + '1'
         53 - 0 + 49 = 102

int y = '5' - '0' + '1'
         53 - 48  + 49 = 54

Notez que c'est cohérent, chaque int reste int et chaque caractère converti en code ASCII


0 commentaires

1
votes

char '0' n'est pas égal à int 0 . La représentation binaire de char '0' occupe 16 bits:

0000 0000 0000 0000 0000 0000 0000 0000 

tandis que la représentation binaire de int 0 occupe 32 bits: p>

0000 0000 0011 0000

Lorsque vous additionnez un char et un int , le char sera promu en int en premier.

Par exemple. unicode de char 5 est 0035 code >, en binaire 0000 0000 0011 0101 , il sera promu int en insérant 16 zéros en tête, 0000 0000 0000 0000 0000 0000 0011 0101 , et l'int représente 53 en décimal.


4 commentaires

Voulez-vous dire que «0» n'est pas égal à 0, car char c = 0; c est zéro, mais char c = '0'; vous donne la valeur que vous réclamez .


Ils sont de types différents.


Quels sont les différents types? Vous pouvez avoir un caractère avec une valeur de zéro, ideone.com/s5DPpJ .


char c = '0' et int b = 0. Je veux dire.



1
votes

Cela peut sembler incohérent mais en réalité, ils sont cohérents.

int x = '5'

output x = 5; car derrière les codes ASCII sont, '5' = 53 et '0' = 48. D'où

int x = '5' - '0';

output x = 53;


0 commentaires

1
votes

Vous mélangez peut-être la représentation à partir de la valeur. Les valeurs ne changent jamais, donc lorsque vous effectuez de l'arithmatique, ce sera toujours que '5' == 53 et non 5. Pour l'affichage JLS sur la conversion d'une primitive en chaîne .

L'arithmétique entière est promue en int pour la plupart des calculs.

System.out.println('5' + '0');
>>> 101

System.out.println((char)('5' + '0'));
>>> e

Les deux résultats ont la même valeur numérique, mais l'un est affiché en tant que caractère car il a été converti en caractère.


0 commentaires

1
votes

Java semble effectuer une conversion de type implicite, mais comment Java peut-il déduire quelle représentation de l'int / char doit-il utiliser?

C'est en fait assez simple. char est l'un des types numériques en Java, voir 4.2.1. Types et valeurs intégrales :

Les valeurs des types intégraux sont des entiers dans les plages suivantes:

  • [...]
  • Pour char, de '\ u0000' à '\ uffff' inclus, c'est-à-dire de 0 à 65535

Toutes les opérations sur les types entiers sont effectuées avec une précision int - ou long -, voir 4.2.2. Opérations entières :

Si un opérateur entier autre qu'un opérateur de décalage a au moins un opérande de type long, alors l'opération est effectuée avec une précision de 64 bits, et le résultat de l'opérateur numérique est de type long. Si l'autre opérande n'est pas long, il est d'abord élargi ( §5.1.5 ) pour taper long par promotion numérique ( §5.6 ).

Sinon, l'opération est effectuée avec une précision de 32 bits et le résultat de l'opérateur numérique est de type int. Si l'un des opérandes n'est pas un int, il est d'abord élargi pour taper int par promotion numérique.

Notez la dernière phrase: elle définit la conversion à appliquer, elle est appelée "promotion numérique".


0 commentaires