# String in int umwandeln



## JavaIsTheBest (15. Mrz 2016)

Hallo,
ich wollte eine Funktion programmieren, die einen String in einen int umwandelt.



Spoiler: StringToInt





```
public static int stringToInt(String s) {
        int result = 0;
        for (int i = 0; i < s.length(); i++) {
            result = result*10+s.charAt(i)-'0' ;            //??????
        }
        return result;
    }
```




Meine Fragen:
1) Wie komt man auf diese Zeile? result = result*10+s.charAt(i)-'0' ;
2) Warum funktioniert das hier nicht? result *=10+s.charAt(i)-'0' ;


----------



## kneitzel (15. Mrz 2016)

Also wie kommt man drauf?
Du gehst ja die Ziffern von links nach rechts durch. Dabei ist das bisherige Ergebnis immer mal 10 zu nehmen und dann um den Wert der Ziffer zu erweitern.
Der Wert der Ziffer ergibt sich über internen Wert. Die '0' ist halt nicht durch den Wert 0 gespeichert sondern durch einen anderen Wert. (Schau mal in Google nach Ascii Tabelle um ein Verständnis zu bekommen. Auch wenn das nicht ganz korrekt ist!) Aber da die Ziffern von '0' bis '9' hintereinander gespeichert sind, kann man den Wert von '0' einfach abziehen.

Die Operation mit *= geht nicht, da dies eine andere Priorisierung hat.
a *= b + c ist halt
a = a * (b + c)
und das ist etwas anderes als
a = a * b + c


----------



## InfectedBytes (15. Mrz 2016)

1) char speichert zeichen quasi als zahlen (siehe ASCII bzw. Unicode). Das Zeichen '0' wird z.B. durch die zahl 48 repräsentiert. Das Zeichen 'A' durch 65.
Ich vermute mal dich verwirrt s.charAt(i)-'0'. Dies sorgt einfach nur dafür, dass das entsprechende Zeichen in die passende Zahl umgewandelt wird. falls an Position i des Strings s nun das Zeichen '0' steht, wird '0'-'0' gerechnet, also eben 48-48, was genau 0 ist. Wenn nun '1'-'0' gerechnet wird kommt 1 raus etc.
2) Die rechte seite des Ausdrucks wird implizit geklammert.
result *=10+s.charAt(i)-'0' ;
ist also gleichbedeutend mit result = result * (10+s.charAt(i)-'0');

edit: 
zu langsam^^


----------



## JavaIsTheBest (16. Mrz 2016)

result = result*10+s.charAt(i)-'0'

Nehmen wir als Beispiel die Zahl "12". Im ASCII Code wäre das, eine 49 und 50
result=0*10+49-48=1 -> result=1
result=1*10+50-48=12

Warum muss ich ausgerechnet *10 und nicht z.B. *100 rechnen. Das verstehe ich noch nicht.


----------



## kneitzel (16. Mrz 2016)

weil Du doch Stelle für Stelle durchgehst und im Dezimalsystem haben wir jeweils den Faktor 10.

123 = ((1 * 10) + 2 ) * 10 + 3

die 2 steht ja für 20 also 2*10
die 1 steht für 100 also 1*10*10

hilft das, um die Logik dahinter zu sehen?


----------



## JavaIsTheBest (16. Mrz 2016)

Ja, hab es jetzt besser verstanden


----------



## Baldur (16. Mrz 2016)

Ich würde dir eventuell noch den Tip geben, nicht zu viel Code in eine Zeile zu packen, sondern die Rechnungen aufzuteilen und ggf Zwischenergebnisse abzuspeichern.


```
char aktuelle_ziffer = s.charAt(i);
int ziffer_wert = aktuelle_ziffer - '0';

result *= 10; // aktuelles Ergebnis um eine Zehnerstelle nach links schieben
result += ziffer_wert; // aktuelle Ziffer aufaddieren
```

Das ganze hat gegenüber der "kompakten" Variante eigentlich nur Vorteile:

Es ist besser lesbar
Man kann die Einzelschritte besser nachvollziehen und ggf. mit einem println ein Zwischenergebnis ausgeben

auch wenn du mal mit einem Debugger arbeitest, kannst du leichter die Zwischenergebnisse nachverfolgen und ggf leichter Fehler finden
du vermeidest Leichtsinnsfehler wie ein falsches Punkt-vor-Strich, Klammerfehler, o.ä.
Die kompakte Variante hat nur den "Vorteil" daß sie weniger Platz braucht, sonst nichts.
Das ist nichtmal schneller, wie manche gerne denken, da Compiler heutzutage sehr gut sind, solche Zwischenschritte automatisch zu optimieren, so daß letztendlich bei beiden Varianten der selbe Bytecode rauskommt.


----------



## Xyz1 (17. Mrz 2016)

Etwas kompliziert hätte ich es so geschrieben:

```
/**
     * @author DerWissende on 03/17/2016
     */
    public static void main(String[] args) {
        int integer = 0;
        String string = "123456789";
        int i = 0;
        for (char c : new StringBuilder(string).reverse().toString().toCharArray()) {
            integer += (c - '0') * (int) Math.pow(10, i++);
        }
        System.out.println("integer = " + integer);
    }
```

Da ist bestimmt noch verbesserungspotential. Oder einfach die Methoden von String/Integer nehmen.


----------



## Xyz1 (18. Mrz 2016)

Es läuft, Freunde, dank des Tipps eines Mods:

```
/**
     * @author DerWissende on 03/18/2016
     */
    public static void main(String[] args) {
        int integer = 0;
        String string = "2147483647";
        AtomicInteger ai = new AtomicInteger(1);
        for (char c : new StringBuilder(string).reverse().toString().toCharArray()) {
            integer += (c - '0') * ai.getAndSet(ai.get() * 10);
        }
        System.out.println(integer);
        System.out.println(Integer.MAX_VALUE);
    }
```

Für string kann jetzt irgendetwas eingesetzt werden - oder für string einen Parameter einführen.
Negative Werte sind natürlich noch mal einen Kniff schwieriger.
Das ist ein Geheimnis.


----------

