Division macht Probleme

NicoHatProbleme2

Bekanntes Mitglied
Ich habe letztens eine Taschenrechner-ähnliche Funktion geschaffen, die es mir erlaubt, einen String zu einem double zu machen.
Doch mir ist aufgefallen, dass bei der Division immer nicht-gewollte Kommastellen im e-2 Bereich erstellt werden.
Ich habe sogar mal BigDecimal benutzt, was aber irgendwie nichts gebracht hat... Nur die Division macht Probleme, der Rest macht alles gut. 8/2 = 4.02, 8*0.5 = 4.
Woran liegt das? (Ich habe sogar mal einfach statt
Java:
part = "" + new BigDecimal(c[j-1]).divide(new BigDecimal(c[j+1])).doubleValue();
Java:
part = "" + new BigDecimal(8).divide(new BigDecimal(8)).doubleValue();
ausprobiert, was auch nichts bringt.
Java:
package Tools;

import java.math.BigDecimal;

public class Functions {
   
    public static double returnResult(String s) {
        s = "(" + s + ")";
      
        char[] c = s.toCharArray();
        int[] brPos = new int[c.length];
        int bracket = 0;
        int brackets = 0;

        //get pos of brackets
        for(int i = 0; i < c.length; i++) {
            switch(c[i]) {
            case '(': brPos[i] = 2 + bracket+10; bracket+=10; brackets++; break;
            case ')': brPos[i] = 1 + bracket; bracket-=10; brackets++; break;
            default: brPos[i] = 0; break;
            }
        }
        //System.out.println();
        boolean parsesBr = true;
        String[] res = new String[brackets/2];
        String part = "";
        int amountOBrs = 0;
        for(int i = c.length-1; i >= 0; i--) {
            if(brPos[i] %10 == 2) {
                part = "";
                //String of brackets
                parsesBr = true;
                int br = brPos[i];
                for(int j = i+1; parsesBr; j++) {
                    //System.out.println(part);
                    if(brPos[j]+1 == br) parsesBr = false;
                    else part += c[j];
                }
                res[amountOBrs] = part;
                amountOBrs++;
            }
        }
      
        return Double.valueOf(calcBracket(res));
    }
    private static String calcBracket(String[] s) {
        String[] c;
        String part = "";
        String replace = "";
        String bracketsReplace = "";
        int check = 0;
        for(int i = 0; i < s.length; i++) {
            bracketsReplace = s[i];
            c = toStringArray(s[i]);
            //System.out.println("restart");
            //System.out.println();
            //Loop till everything is calculated
            Loop:
            while(true) {
                check = 0;
                c = toStringArray(s[i]);
                for(int j = 0; j < c.length; j++) {
                    switch(c[j]) {
                    case "^": {
                        part = "" + (Math.pow(Double.parseDouble("" + c[j-1]) , Double.parseDouble("" + c[j+1])));
                        replace = "" + c[j-1] + c[j] + c[j+1];
                        s[i] = s[i].replace(replace, part);
                        //System.out.println("^replace: " + replace + ", " + part + " " + s[i]);
                        check++;
                        break;
                      
                    }
                    case "%": {
                        part = "" + Double.parseDouble("" + c[j-1]) / 100;
                        replace = "" + c[j-1] + c[j];
                        s[i] = s[i].replace(replace, part);
                        //System.out.println("%replace: " + replace + " " + part + " " + s[i]);
                        check++;
                        break;
                    }
                    }
                }
                if(check == 0) break Loop;
            }
            //System.out.println();
            //Loop till everything is calculated
            Loop:
            while(true) {
                check = 0;
                c = toStringArray(s[i]);
                for(int j = 0; j < c.length; j++) {
                    switch(c[j]) {
                    case "*": {
                        part = "" + new BigDecimal(c[j-1]).multiply(new BigDecimal(c[j+1])).doubleValue();
                        replace = "" + c[j-1] + c[j] + c[j+1];
                        s[i] = s[i].replace(replace, part);
                        //System.out.println("*replace: " + replace + ", " + part + " '" + s[i] + "'");
                        check++;
                        break;
                    }
                    case "/": {
                        //Hier ist wohl irgendwas falsch
                        part = "" + new BigDecimal(c[j-1]).divide(new BigDecimal(c[j+1])).doubleValue();
                        replace = "" + c[j-1] + c[j];
                        s[i] = s[i].replace(replace, part);
                        //System.out.println("/replace: " + replace + " " + part + " " + s[i]);
                        check++;
                        break;
                    }
                    }
                }
                if(check == 0) break Loop;
            }
            //Loop till everything is calculated
            Loop:
            while(true) {
                check = 0;
                c = toStringArray(s[i]);
                for(int j = 0; j < c.length; j++) {
                    switch(c[j]) {
                    case "+": {
                        part = "" + (Double.parseDouble("" + c[j-1]) + Double.parseDouble("" + c[j+1]));
                        replace = "" + c[j-1] + c[j] + c[j+1];
                        s[i] = s[i].replace(replace, part);
                        //System.out.println("+replace: " + replace + ", " + part + " '" + s[i] + "'");
                        check++;
                        break;
                        }
                    case "-": {
                        part = "" + (Double.parseDouble("" + c[j-1]) - Double.parseDouble("" + c[j+1]));
                        replace = "" + c[j-1] + c[j] +c[j+1];
                        s[i] = s[i].replace(replace, part);
                        //System.out.println("-replace: " + replace + " " + part + " " + s[i]);
                        check++;
                        break;
                    }
                    }
                }
                if(check == 0) break Loop;
            }
            //replace the String in the other Brackets
            for(int j = 0; j < s.length; j++) {
                if(j != i) {
                    //System.out.println("BrReplace: " + s[j] + ", " + bracketsReplace + ", " + s[i]);
                    s[j] = s[j].replace("(" + bracketsReplace + ")", s[i]);
                    //System.out.println(s[j]);
                }
            }
        }
        //System.out.println(s[s.length-1]);
        return s[s.length-1];
    }
    public static String[] toStringArray(String s) {
        //System.out.println(s);
        char[] c = s.toCharArray();
        String[] ar = new String[c.length];
        int j = 0;
        int k = 0;
        for(int i = 0; j < c.length; j++) {
            //System.out.println(j + ":" + i);
            if(i < c.length) ar[i] = "";
            while(j < c.length && (Character.isDigit(c[j]) | c[j] == '.')) {
                ar[i] += c[j];
                j++;
                //System.out.println(ar[i]);
              
            }
            i++;
            if(i < c.length) ar[i] = "";
            if(j < c.length && !Character.isDigit(c[j]) /**&& c[i] != '(' && c[i] != ')'**/) {
                ar[i] += c[j];
                //System.out.println(ar[i]);
                i++;
            }
            k = i;
            //System.out.println(i);
          
        }
        String[] res = new String[k];
        for(int i = 0; i < k; i++) {
            res[i] = ar[i];
            //System.out.println("a:" + ar[i]);
        }
        return res;
    }

}
 
Zuletzt bearbeitet:

httpdigest

Top Contributor
Also keine Fließkommaberechnung der Welt macht aus 8/4 = 4.02.
Kann es sein, dass deine ganze Stringkonkatenation in deinem "Parser" (in Anführungszeichen) zuerst korrekt 8/2 = 4.0 ausrechnet und du das dann stringkonkatenierst mit einer 2 irgendwo danach?
Ich würde deinen komplett "Parser" wegschmeißen und nochmal neu bauen. Da steigt man ja komplett überhaupt nicht durch.
Schau dir mal bitte das Thema "recusive descent parser" an. Ein arithmetischer Ausdruck kann sehr einfach rekursiv geparsed werden.
 

httpdigest

Top Contributor
Sehr schön. Dann kannst du das ja jetzt alles in die Tonne treten und nochmal vernünftig von Vorne anfangen. Ohne komische Arrays und Schleifen und ohne String-Replacements. :)
 

Robert Zenz

Top Contributor
Also wenn du zum Beispiel "8/8" zerlegen willst, dann schlage ich zwei Schritte vor: Zuerst zerlegst du den Ausdruck in einzelne Teile (Tokens), dann hast du drei Teile "8", "/" und "8". Aus dieser Liste an einzelnen Teilen kannst du dann deine Rechnung aufbauen.
 

NicoHatProbleme2

Bekanntes Mitglied
hab ich ja sozusagen... habe halt nur ein Array gemacht, um so was, wie 228.76 einfacher aufzurufen. Auch habe ich Klammern hinzugefügt, was alles etwas schwieriger macht
 

httpdigest

Top Contributor
Ich empfehle dir nochmals, den Parser rekursiv aufzubauen. Hier mal ein Beispiel mit korrekter Klammerung und Bindungen der Operatoren, was ich eben mal from scratch gebaut hab:
Java:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Parser {
  private static final Pattern number = Pattern.compile("^-?\\d+(\\.\\d+)?"); // <- to recognized numbers more easily
  private final String s;
  private int pos;
  public Parser(String input) {
    this.s = input;
  }
  private void advance(int n) {
    pos += n;
  }
  private void ws() {
    while (pos < s.length() && Character.isWhitespace(s.charAt(pos)))
      advance(1);
  }
  private double number() {
    Matcher m = number.matcher(s.substring(pos));
    if (m.find()) {
      advance(m.end());
      return Double.parseDouble(m.group());
    } else {
      throw new IllegalStateException("expecting number at " + pos);
    }
  }
  private double primitive() {
    ws();
    char c = s.charAt(pos);
    if (c == '(') {
      advance(1); // <- consume open parenthesis
      double v = expression();
      advance(1); // <- consume close parenthesis
      return v;
    }
    return number();
  }
  private double additive() {
    double ret = multiplicative();
    ws();
    while (pos < s.length()) {
      char c = s.charAt(pos);
      if (c == '+') {
        advance(1); // <- consume the + character
        ret += multiplicative();
      } else if (c == '-') {
        advance(1); // <- consume the - character
        ret -= multiplicative();
      } else {
        break;
      }
      ws();
    }
    return ret;
  }
  private double multiplicative() {
    double ret = primitive();
    ws();
    while (pos < s.length()) {
      char c = s.charAt(pos);
      if (c == '*') {
        advance(1); // <- consume the * character
        ret *= primitive();
      } else if (c == '/') {
        advance(1); // <- consume the / character
        ret /= primitive();
      } else {
        break;
      }
      ws();
    }
    return ret;
  }
  public double expression() {
    return additive();
  }

  // Test
  public static void main(String[] args) {
    System.out.println(new Parser(" ( (  4 +  2 ) - 3 ) + 2 * -2 ").expression());
  }
}
 

httpdigest

Top Contributor

httpdigest

Top Contributor
Hier ist was mit ^ und % und parsed äquivalent zu Google.
Z.B. ist " 5 * 100% + - 3 ^ 2% * (-2.5 + 3 ^ - 2*4 )" == 7.10122..
Java:
import java.util.function.BiFunction;
import java.util.function.DoubleSupplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Parser {
  private static final Pattern number = Pattern.compile("^\\d+(\\.\\d+)?"); // <- to recognize numbers more easily
  private final String s;
  private int pos;
  public Parser(String input) {
    this.s = input;
  }
  private void ws() {
    while (pos < s.length() && Character.isWhitespace(s.charAt(pos)))
      pos += 1;
  }
  private double number() {
    Matcher m = number.matcher(s.substring(pos));
    if (m.find())
      return consumeAnd(m.end(), () -> Double.parseDouble(m.group()));
    throw new IllegalStateException("expecting number at " + pos);
  }
  private double primary() {
    ws();
    if (s.charAt(pos) == '(') {
      double v = consumeAnd(1, this::expression);
      pos += 1; // <- consume close parenthesis
      return v;
    }
    return number();
  }
  private double exponential() {
    double ret = primary();
    ws();
    if (pos < s.length() && s.charAt(pos) == '^')
      return consumeAnd(1, () -> Math.pow(ret, unary()));
    return ret;
  }
  private double unary() {
    ws();
    if (s.charAt(pos) == '-')
      return -consumeAnd(1, this::unary);
    return percent(exponential());
  }
  private double percent(double v) {
    return fold(v, (acc, c) -> {
      if (c == '%')
        return consumeAnd(1, () -> acc / 100.0);
      return null;
    });
  }
  private double consumeAnd(int n, DoubleSupplier f) {
    pos += n;
    return f.getAsDouble();
  }
  private double fold(double ret, BiFunction<Double, Character, Double> f) {
    ws();
    while (pos < s.length()) {
      Double d = f.apply(ret, s.charAt(pos));
      if (d == null)
        break;
      ret = d;
      ws();
    }
    return ret;
  }
  private double multiplicative() {
    return fold(unary(), (acc, c) -> switch (c) {
      case '*' -> acc * consumeAnd(1, this::unary);
      case '/' -> acc / consumeAnd(1, this::unary);
      default -> null;
    });
  }
  private double additive() {
    return fold(multiplicative(), (acc, c) -> switch (c) {
      case '+' -> acc + consumeAnd(1, this::multiplicative);
      case '-' -> acc - consumeAnd(1, this::multiplicative);
      default -> null;
    });
  }
  public double expression() {
    return additive();
  }

  // Test
  public static void main(String[] args) {
    System.out.println(new Parser(" 5 * 100% + - 3 ^ 2% * (-2.5 + 3 ^ - 2*4 ) ").expression());
  }
}
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
Drachenbauer Division mit Int funktioniert nicht Allgemeine Java-Themen 3
F Float Division - Nachkommastelle bei 0 ausblenden Allgemeine Java-Themen 2
W Division mit float und double Allgemeine Java-Themen 2
berserkerdq2 Jemand einen Tipp wie man ein Javafx-Hintergrund "dynamisch" macht Allgemeine Java-Themen 3
berserkerdq2 IJVM, ich tue auf meinen Stack 100 und 120 rein, danach subtrahiere ich, macht die Maschine 100-120 oder 120-100? Allgemeine Java-Themen 8
OnDemand Anzeigen was eine Applikation macht Allgemeine Java-Themen 1
H Swing HashMap zu Tabelle macht mir Probleme Allgemeine Java-Themen 4
M 4 Gewinnt KI macht nicht, was sie soll.. Allgemeine Java-Themen 1
P Eclipse Projekt anlegen macht Problem Allgemeine Java-Themen 1
WetWer Was bedeutet/macht ein Exit-Code Allgemeine Java-Themen 1
O OOP Wie macht man das am besten OO? Allgemeine Java-Themen 8
Thallius Macht das Sinn? Allgemeine Java-Themen 30
F Java Native/Shared Library (.so) laden macht Probleme Allgemeine Java-Themen 3
X Was macht folgender Code!? Allgemeine Java-Themen 6
J Doppelte Buchstaben löschen - letztes Wort macht er nicht Allgemeine Java-Themen 2
J if else Anweisung macht nicht was es soll. Wieso? Allgemeine Java-Themen 10
M Google App Engine macht Probleme Allgemeine Java-Themen 4
GilbertGrape Warum macht man "if(true)" Allgemeine Java-Themen 18
C Klassen Was macht diese Java-Mathe-Klasse? Allgemeine Java-Themen 2
S Erste Schritte Exception beendet Schleife nicht - Methode macht trotz throw weiter? Allgemeine Java-Themen 9
S Javadoc 3d einbinden macht probleme Allgemeine Java-Themen 10
B Unix-Timestamp > Date macht Probleme. Allgemeine Java-Themen 3
T Ausdruck mit pdfBox macht Probleme Allgemeine Java-Themen 2
B jar File macht probleme wegen einer Methode! Allgemeine Java-Themen 5
alderwaran jaxb xsd schema, min/maxoccurs macht was? Allgemeine Java-Themen 7
S AWT StringBuffer macht nicht, was ich erwarte Allgemeine Java-Themen 2
E Timer class macht einfach garnichts :/ Allgemeine Java-Themen 6
N Vokabelprogramm - Wer macht mit? Allgemeine Java-Themen 58
S Anschauen was der Compiler macht..? Allgemeine Java-Themen 5
bj99 ImageIO.write() macht Probleme Allgemeine Java-Themen 7
I Was macht static { ... } ? Allgemeine Java-Themen 8
N Für welche Art von Berechnungen macht JCUDA Sinn? Allgemeine Java-Themen 12
P JMF macht mich verrückt Allgemeine Java-Themen 3
R PDF Formular mit JPod ausfüllen macht Probleme Allgemeine Java-Themen 4
G Wie kriegt Klasse2 die Info, was Klassse1 gerade "macht Allgemeine Java-Themen 7
Escorter was macht createHorizontalGlue() Allgemeine Java-Themen 2
T Serialisierung: Wie macht RMI das so schnell? Allgemeine Java-Themen 14
J Was macht dieser Code? Allgemeine Java-Themen 13
S Was macht der Java-Verifier? Allgemeine Java-Themen 4
T Problem, warum macht der das so(finde kein titel.) Allgemeine Java-Themen 3
I Irre Website-Wie macht man sowas? Allgemeine Java-Themen 6
U if Abfrage macht etwas falsch Allgemeine Java-Themen 2
G javadoc macht probleme Allgemeine Java-Themen 2
A equals() macht nicht, was es soll Allgemeine Java-Themen 4
B Vergleichen von arrays macht Probleme Allgemeine Java-Themen 2
M JBoss macht Probleme Allgemeine Java-Themen 6
P Wie macht Sun Gewinn mit Java? Allgemeine Java-Themen 3
Maximum '.' in String ersetzen macht Schwierigkeiten Allgemeine Java-Themen 2
T Klassen samt Methoden aus Jar-Archiv laden macht Problem Allgemeine Java-Themen 9
C Probleme beim Erstellen eines runnable-jar files Allgemeine Java-Themen 1
S Umstellung von File auf Path - Probleme mit Stream Allgemeine Java-Themen 5
C Probleme mit javax.mail.Session Allgemeine Java-Themen 8
M tomcat probleme Allgemeine Java-Themen 1
B Java Reflection Probleme beim wehcselseitigen Referenzieren zweier Klassen/Objekte Allgemeine Java-Themen 14
MarvinsDepression Probleme mit relativem Dateipfad Allgemeine Java-Themen 1
G Geotools Probleme nach PC-Wechsel Allgemeine Java-Themen 6
nibe1501 GUI Probleme Allgemeine Java-Themen 16
C Probleme mit dem WindowBuilder Allgemeine Java-Themen 3
P Selenium . Probleme ein Iron Icon Element anzusprechen Allgemeine Java-Themen 2
B Compiler-Fehler Probleme beim Kompilieren mit Jsoup Allgemeine Java-Themen 8
K VisualVM Profiling Remote Probleme Allgemeine Java-Themen 1
O Leerzeichen und Umlaute im Pfad einer Java Applikation machen Probleme Allgemeine Java-Themen 13
M Probleme bei Eclipse wenn ich entpacke Allgemeine Java-Themen 15
D Regex Probleme Allgemeine Java-Themen 2
M Probleme jar datei. Allgemeine Java-Themen 2
L Vererbung Verständnis Probleme Vererbung Allgemeine Java-Themen 2
Dann07 Probleme mit OpenAL Allgemeine Java-Themen 0
V Threads Probleme beim Aufrufen von Methoden einer anderen Klasse (Threads) Allgemeine Java-Themen 14
V Compiler-Fehler Online Compiler Probleme Allgemeine Java-Themen 4
M Probleme mit Negamax-Algorithmus Allgemeine Java-Themen 29
M Probleme mit BigDecimal Allgemeine Java-Themen 1
T Probleme mit NumberFormat Allgemeine Java-Themen 5
J Probleme exe-Start mit Task Scheduler Allgemeine Java-Themen 1
B Input/Output Probleme beim Ausführen von Shell-Befehlen mit Java Allgemeine Java-Themen 28
J Probleme beim einbinden von Zip4j library Allgemeine Java-Themen 6
F Variablen Palindromzahl (Probleme mit Methode) Allgemeine Java-Themen 9
K Data Konverter - Probleme mit Byte[] Kodierung Allgemeine Java-Themen 3
T Probleme mit dem Pfad zum Propertie file Allgemeine Java-Themen 7
Neoline Interpreter-Fehler Probleme mit Arrays.toString Allgemeine Java-Themen 7
F SQLite mit Java / Probleme beim INSERT Befehl Allgemeine Java-Themen 4
J Erste Schritte Probleme mit der Hauptklasse Allgemeine Java-Themen 14
J Tetris Probleme bei Klassen Allgemeine Java-Themen 14
J MinMax VierGewinnt Probleme Allgemeine Java-Themen 22
J Probleme mit CodeCoverage und Lombok Equals Allgemeine Java-Themen 1
S Eclipse Probleme beim Implementieren / Ausführen von jUnit 5-Test Suites Allgemeine Java-Themen 14
R Snake Probleme Allgemeine Java-Themen 2
A Probleme beim Verstehen einer Aufgabenstellung Allgemeine Java-Themen 11
RalleYTN 3D Objekt Translation basierend auf Rotation (Probleme mit Z Rotation) Allgemeine Java-Themen 0
Bluedaishi Druck Probleme mit PDF dateien Allgemeine Java-Themen 4
G Ant Probleme bei einer Installation die Apache ant+ivy verwendet Allgemeine Java-Themen 14
E TableView Probleme Allgemeine Java-Themen 7
perlenfischer1984 Probleme beim Mocken Allgemeine Java-Themen 6
S Kaffemaschine Programmierung Probleme Allgemeine Java-Themen 2
K Threads Runtime und Process Probleme Allgemeine Java-Themen 3
S Probleme mit unterschiedlichen Java-Versionen (Mac OS X 10.11) Allgemeine Java-Themen 0
S Event Handling keyPressed()-Probleme Allgemeine Java-Themen 2
VfL_Freak Große und seltsame Probleme nach Java-Update auf V1.8.0_91 Allgemeine Java-Themen 3
P Probleme mit Grafik (Java) Allgemeine Java-Themen 6
R probleme beim starten von jar unter linux Allgemeine Java-Themen 2
H Probleme mit DAY_OF_WEEK Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben