0
votes

Pourquoi ai-je des résultats mathématiques erronés lorsque j'utilise une classe de scanner et des délimiteurs pour obtenir un double en Java?

J'écris un programme dans lequel je dois obtenir une entrée utilisateur, enregistrée sous forme de double. L'utilisateur doit pouvoir le mettre en utilisant à la fois ',' et '.' comme délimiteur - comme ils le souhaitent. J'ai essayé d'utiliser useDelimiter qui ne fonctionne que partiellement - il accepte en effet les deux valeurs (par exemple 4,5 et 4,5) mais lorsque j'utilise plus tard la valeur entrée dans une équation mathématique, j'obtiens de mauvais résultats - il semble arrondir l'entrée de l'utilisateur à l'entier le plus proche et en tant qu'effet que j'entre, 4 ou 4,5 ou 4,5 ou 4,8 etc., j'obtiens le même résultat, qui n'est en fait vrai que pour 4. Quelqu'un sait-il pourquoi cela ne fonctionne pas ?

  double protectiveResistor=0;                //must be a double, required by my teacher
  double voltage= 5;    
  System.out.println("Please provide the resistance.");
        Scanner sc= new Scanner(System.in);
        sc.useDelimiter("(\\p{javaWhitespace}|\\.|,)");

        try
        {
            protectiveResistor=sc.nextDouble();
        }
        catch(InputMismatchException exception)
        {
            System.out.println("Wrong input!");
            System.exit(1);
        }

        if (protectiveResistor<0){
            System.err.println("Wrong input!");
            System.exit(1);
        }
        
        double current = (double)voltage/protectiveResistor;
        double power = (double)current*current*protectiveResistor;

Merci!


1 commentaires

Msitake - J'espère que cette réponse a résolu votre problème. Si oui, vous pouvez aider la communauté en la marquant comme acceptée (cliquez sur la grande coche ✓ à gauche de la réponse). Une réponse acceptée aide les futurs visiteurs à utiliser la solution en toute confiance. Vous pouvez également vérifier ceci pour en savoir plus. N'hésitez pas à y commenter en cas de doute / problème. Remarque: vous ne pouvez accepter qu'une seule réponse pour une question. Cependant, une fois que vous avez plus de 15 points de réputation, vous pouvez voter autant de réponses que vous le souhaitez.


3 Réponses :


1
votes

La méthode useDelimiter sert à indiquer au Scanner quel caractère séparera les nombres les uns des autres. Ce n'est pas pour spécifier quel caractère sera le point décimal. Donc, avec votre code, si l'utilisateur entre 4.5 ou 4,5 , le Scanner verra cela comme deux entrées séparées, 4 et 5 .

Malheureusement, le Scanner n'a pas la possibilité de vous permettre de spécifier deux caractères différents comme séparateurs décimaux. La seule chose que vous pouvez vraiment faire est de scanner les deux nombres séparément, puis de les joindre en un nombre décimal par la suite. Vous voudrez les analyser en tant que valeurs de String , afin de ne pas perdre de zéros après la virgule décimale.


0 commentaires

1
votes

Ce que fait useDelimiter () est de diviser l'entrée sur le délimiteur spécifié. Par exemple, si vous avez l'entrée de 4,5 , le code suivant imprimera "4".

Scanner sc= new Scanner(System.in);
sc.useDelimiter("(\\p{javaWhitespace}|\\.|,)");

try
{
    String firstPart = "0";
    String secondPart = "0";
    if (sc.hasNext()) {
        firstPart = sc.next();
    }
    if (sc.hasNext()) {
        secondPart = sc.next();
    }
    protectiveResistor = Double.parseDouble(firstPart + "." + secondPart)
}
// Rest of your code here

Si vous souhaitez également imprimer la deuxième partie, après le ',', vous devez ajouter une autre ligne pour obtenir la valeur suivante, qui dans cet exemple afficherait "4 5":

Scanner sc= new Scanner(System.in);
sc.useDelimiter(",");
System.out.println(sc.next())
System.out.println(sc.next())

Dans votre code, vous pouvez le faire comme ceci:

Scanner sc= new Scanner(System.in);
sc.useDelimiter(",");
System.out.println(sc.next())

Ce que fait ce code est de diviser l'entrée sur un espace blanc, '.' et ','. Pour une valeur à virgule flottante, vous attendez une partie avant la virgule décimale et une après. Par conséquent, vous vous attendez à ce que le scanner ait divisé l'entrée en deux parties. Ces deux parties sont affectées à deux variables, firstPart et secondPart . Dans la dernière étape, les deux parties sont réunies avec le '.' comme point décimal, comme prévu par Java et analysé dans une variable de type Double.


2 commentaires

Merci pour le commentaire, j'ai mis à jour ma réponse pour utiliser next () au lieu de nextDouble () ce qui devrait résoudre ce problème


Ça a l'air beaucoup mieux maintenant.



0
votes

Un moyen simple de le faire peut être de remplacer la virgule par un point.

Démo:

Enter a number: 12,34
12.34

Un exemple d'exécution:

Enter a number: 12.34
12.34

Un autre exemple d'exécution:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter a number: ");
        double x = Double.parseDouble(sc.next().replace(',', '.'));
        System.out.println(x);
    }
}


0 commentaires