Zahlen innerhalb von Strings bearbeiten



  • Hallo Leute ! ich komme leider nicht mehr weiter mit meinem Problem was ich habe, vielleicht kann mir einer von euch ein paar Hinweise geben?

    ich muss zwei zahlen die in je 2 strings gespeichert sind addieren.

    string 1 = vorkommaZahl1
    string 2 = nachkommaZahl1
    string 3 = vorkommaZahl2
    string 4 =nachkommaZahl2

    Also zum beispiel:

    string aVorkomma= "87763" ; 
    string aNachkomma = "000023";
    string bVorkomma = "76344";
    string bNachkomma ="00345;
    

    Ich dachte zunächst ganz einfach in long umwandeln zusammenaddieren und fertig, jedoch fallen bei dir die führenden nullen von nachkomma natürlich weg. Dann kommt natürlich was ganz falsches raus. Das ist mein Problem.

    kann mir jemand helfen und erklären wie ich das angehen muss? eine stringfunktion gibt es nicht dafür nehme ich an? Ich hoffe ich konnte das einigermaßen verständlich rüberbringen. danke!!



  • Mit C++11 geht es so

    #include <string>
    #include <iostream>
    
    int main()
    {
     std::cout << std::stod( std::string("123") + "." + "0009") << '\n';
    }
    


  • manni66 schrieb:

    Mit C++11 geht es so

    #include <string>
    #include <iostream>
    
    int main()
    {
     std::cout << std::stod( std::string("123") + "." + "0009") << '\n';
    }
    

    Aber nicht bei der Anzahl an Nachkommastellen, und genau darum gehts.



  • llllll schrieb:

    manni66 schrieb:

    Mit C++11 geht es so

    #include <string>
    #include <iostream>
    
    int main()
    {
     std::cout << std::stod( std::string("123") + "." + "0009") << '\n';
    }
    

    Aber nicht bei der Anzahl an Nachkommastellen, und genau darum gehts.

    Versteh ich nicht...sieht doch gut aus...?!
    Was ist denn an der Variante auszusetzen?



  • Ich habe das gerade mal selber probiert umzusetzen. Der Code ist alles andere als optimal, aber sollte das Prinzip zumindest etwas verdeutlichen können. Und zwar werden beide Strings durch Auffüllen von Nullen auf die gleiche Länge gebracht und dann schriftlich addiert.

    #include <iostream>
    #include <sstream>
    #include <string>
    #include <cmath>
    
    using namespace std;
    
    int main()
    {
    	string aVorkomma= "87763" ;
    	string aNachkomma = "0927";
    	string aZahl = aVorkomma + "." + aNachkomma;
    
    	string bVorkomma = "76344";
    	string bNachkomma = "00549";
    	string bZahl = bVorkomma + "." + bNachkomma;
    
    	if (bNachkomma.length() != aNachkomma.length())
    	{
    		long diff = std::abs(static_cast<long>(bNachkomma.length() - aNachkomma.length()));
    
    		if (bNachkomma.length() < aNachkomma.length())
    		{
    			bNachkomma += std::string(diff, '0');
    		}
    		else
    		{
    			aNachkomma += std::string(diff, '0');
    		}
    	}
    
    	std::cout << "Nachkommastelle:\n";
    	std::cout << "  " << aNachkomma << std::endl;
    	std::cout << "+ " << bNachkomma << std::endl;
    
    	int rest = 0;
    
    	std::string result;
    
    	for (std::size_t i = aNachkomma.length() - 1; i > 0; --i)
    	{
    		int res = aNachkomma[i] - '0' + bNachkomma[i] - '0';
    
    		res += rest;
    
    		std::stringstream strRes;
    
    		strRes << res;
    
    		if (res >= 10)
    		{
    			rest = strRes.str()[0] - '0';
    		}
    		else
    		{
    			rest = 0;
    		}
    
    		result = strRes.str()[strRes.str().length() - 1] + result;
    	}
    
    	if (result.length() != aNachkomma.length())
    	{
    		result = std::string(std::abs(static_cast<long>(result.length() - aNachkomma.length())), '0') + result;
    	}
    
    	std::cout << "= " << result << std::endl;
    
    	std::cout << "\nVorkommastelle:\n";
    	std::cout << "  " << atol(aVorkomma.c_str()) << std::endl;
    	std::cout << "+ " << atol(bVorkomma.c_str())  << std::endl;
    	std::cout << "= " << atol(aVorkomma.c_str()) + atol(bVorkomma.c_str()) << std::endl;
    
    	std::cout << "\n" << atol(aVorkomma.c_str()) + atol(bVorkomma.c_str()) << "." << result << std::endl;
    
    	return 0;
    }
    

    Ich kanns nur wiederholen: Der Code ist grausam, aber das ist auch nur ein kleiner Testcode.



  • Furble Wurble schrieb:

    llllll schrieb:

    manni66 schrieb:

    Mit C++11 geht es so

    #include <string>
    #include <iostream>
    
    int main()
    {
     std::cout << std::stod( std::string("123") + "." + "0009") << '\n';
    }
    

    Aber nicht bei der Anzahl an Nachkommastellen, und genau darum gehts.

    Versteh ich nicht...sieht doch gut aus...?!
    Was ist denn an der Variante auszusetzen?

    Ich hatte es einfach so verstanden, dass der OP mit "unendlich" vielen Nachkommastellen und möglichst genau rechnen können möchte.
    Ansonsten geht es natürlich auch mit der Variante, wobei man natürlich vorher z.B. mit std::cout.precision(20) die Genauigkeit festlegen muss und mit den auftretenden Ungenauigkeiten leben muss.



  • manni66 schrieb:

    Mit C++11 geht es so

    #include <string>
    #include <iostream>
    
    int main()
    {
     std::cout << std::stod( std::string("123") + "." + "0009") << '\n';
    }
    

    👍 , und mit C++98/03 so

    std::istringstream stream("123" "." "0009"); // + <sstream>
    std::cout << *std::istream_iterator<double>(stream); // + <iterator>
    


  • Danke für die sehr hilfreichen Antworten! Hat mich weitergebracht ! 😉

    Jetzt ergibt sich nur noch ein Problem bei mir:

    Wenn ich z.B für die Strings sher große werte eingebe ( ich muss 18 stellen vor und 18 stellen nach dem Komma darstellen können) schneidet es es zahlen die größer als 19 Zeichen sind ab. Ich weiß das es es halt so ist in einem double. habe es mit einem long double versucht aber der scheint auch nur 8 Byte zu haben.

    Gibt es ne Möglichkeit einen größeren Datentyp für Fließkommas einzubinden?
    Wie kann ich es sonst machen??



  • Es gibt diverse bignum-Libraries die mit beliebig großen Zahlen rechnen können. Ein Komma brauchst du ja auch nicht, da du ja Festkommarithmetik betreibst und nur bei der Ausgabe das Komma einfügen musst.



  • Wie ich brauch das Komma nicht?? ich rechne ja damit zunächst meine summe aus. Das mit der Lib einbinden scheint keine einfache Sache zu sein ( bin noch ziemlich am anfang wie man sieht),habe GMP Lib gefunden aber ich hab kein Plan wie ich das installieren muss auf meinem windows rechner.

    Also ich hab mal eben ein Beispielcode geschrieben,vielleicht gibt es ja einen anderen Lösungsweg... Das eergebnis wird so leider verkürzt weil es ein double ist.

    #include <iostream>
    #include <sstream>
    #include <string>
    using namespace std ;
    
    int main(){
    
    string zahl1String = "123456789123456789.123456789123456789";
    string zahl2String = "12345678912345.12345";
    
    stringstream str1 , str2 ;
    long double zahl1Double;
    long double zahl2Double;
    
    str1<<zahl1String;
    str1>>zahl1Double;
    
    str2 << zahl2String;
    str2 >> zahl2Double;
    
    long double ergebnis = zahl2Double +zahl1Double ;
    cout.precision(20);
    cout<<ergebnis;
    
    }
    


  • Sone schrieb:

    ("123" "." "0009"); // + <sstream>[/code]

    Fehlt da nicht was?



  • Da fehlt jetzt kein +, falls du das meinst. Allerdings ist das Beispiel etwas witzlos, weil der OP ja sicher nicht String-Literale verwenden will ...
    Siehe
    http://codepad.org/QI3mlbO2
    Der Compiler setzt das Ding zur Compile-Zeit zu einem einzigen Stringliteral zusammen.



  • hmmmm bleibt mir wohl keine andere wahl als mit nullen aufzufüllen und dann zeichen für zeichen irgendwie auszurechnen? das beispielcode von gjgjgjggjjgj lässt sich leider nicht komplieren.

    wobei ist ganz schön kompliziert mit dem überlauf, und wenn eins der zeichen minus enthält oder beide... puh keine ahnung 😞 😞 😞 😞



  • funnyfun21 schrieb:

    hmmmm bleibt mir wohl keine andere wahl als mit nullen aufzufüllen und dann zeichen für zeichen irgendwie auszurechnen? das beispielcode von gjgjgjggjjgj lässt sich leider nicht komplieren.

    wobei ist ganz schön kompliziert mit dem überlauf, und wenn eins der zeichen minus enthält oder beide... puh keine ahnung 😞 😞 😞 😞

    Warum lässt der Code sich nicht kompilieren? Wenn du die Fehlermeldung oder was auch immer angibst, kann man dir eventuell sogar helfen.



  • Also hier nochmal der code was vorhin gepostet wurde und die fehlerausgabe die bei mir kommt. findet die mathe funktionen nicht und atol ... muss ich noch was anderes einbinden?

    #include <iostream>
    #include <sstream>
    #include <string>
    #include <cmath>
    
    using namespace std;
    
    int main()
    {
        string aVorkomma= "87763" ;
        string aNachkomma = "0927";
        string aZahl = aVorkomma + "." + aNachkomma;
    
        string bVorkomma = "76344";
        string bNachkomma = "00549";
        string bZahl = bVorkomma + "." + bNachkomma;
    
        if (bNachkomma.length() != aNachkomma.length())
        {
            long diff = std::abs(static_cast<long>(bNachkomma.length() - aNachkomma.length()));
    
            if (bNachkomma.length() < aNachkomma.length())
            {
                bNachkomma += std::string(diff, '0');
            }
            else
            {
                aNachkomma += std::string(diff, '0');
            }
        }
    
        std::cout << "Nachkommastelle:\n";
        std::cout << "  " << aNachkomma << std::endl;
        std::cout << "+ " << bNachkomma << std::endl;
    
        int rest = 0;
    
        std::string result;
    
        for (std::size_t i = aNachkomma.length() - 1; i > 0; --i)
        {
            int res = aNachkomma[i] - '0' + bNachkomma[i] - '0';
    
            res += rest;
    
            std::stringstream strRes;
    
            strRes << res;
    
            if (res >= 10)
            {
                rest = strRes.str()[0] - '0';
            }
            else
            {
                rest = 0;
            }
    
            result = strRes.str()[strRes.str().length() - 1] + result;
        }
    
        if (result.length() != aNachkomma.length())
        {
            result = std::string(std::abs(static_cast<long>(result.length() - aNachkomma.length())), '0') + result;
        }
    
        std::cout << "= " << result << std::endl;
    
        std::cout << "\nVorkommastelle:\n";
        std::cout << "  " << atol(aVorkomma.c_str()) << std::endl;
        std::cout << "+ " << atol(bVorkomma.c_str())  << std::endl;
        std::cout << "= " << atol(aVorkomma.c_str()) + atol(bVorkomma.c_str()) << std::endl;
    
        std::cout << "\n" << atol(aVorkomma.c_str()) + atol(bVorkomma.c_str()) << "." << result << std::endl;
    
        return 0;
    }
    
    Line 20 : error: call of overloaded 'abs(long int)' is ambigous
    Line 94 : note : canditates are : double std::abs(double)
         98 : float std:: abs(float)
         102: long double std:: abs(long double)
    
    Line 64 : error: call of overloaded 'abs(long int)' is ambigous
    Line 94 : note : canditates are : double std::abs(double)
         98 : float std:: abs(float)
         102: long double std:: abs(long double)
    
    Line 70 : error : 'atol' was not declared in this scope
    


  • hat sich erledigt, da hat cstdlib gefehlt....

    ich schaue mal ob ich was damit anfangen kann , danke und ich hoffe ich brauch nicht nochmal hilfe bei der blöden aufgabe 😉



  • Funktioniert leider nicht für Minuszahlen. 😞 😞 😞



  • funnyfun21 schrieb:

    Funktioniert leider nicht für Minuszahlen. 😞 😞 😞

    Natürlich nicht. Da bedarf es noch einiges mehr an Programmierung. Eine solche Klasse selber zu programmieren, die mit so großen Zahlen rechnen kann, macht nur Sinn, wenn man neugierig ist oder nur eine einzige spezielle Operation braucht. Denn als nächstes folgt ja dann noch Subtraktion, Multiplikation, Division, usw.

    Sollte das also wirklich von nöten sein, dann such dir eine fertige Bibliothek und nimm den Aufwand diese einzurichten, etc. eben in Kauf.



  • funnyfun21 schrieb:

    Wie ich brauch das Komma nicht??

    Du brauchst nur ein Komma, wenn du wirklich Fließkommazahlen hast. Das heißt das Komma fließt/wandert mal an die 3. Stelle, mal an die 7. usw.

    funnyfun21 schrieb:

    ich muss 18 stellen vor und 18 stellen nach dem Komma darstellen können

    Daraus habe ich geschlossen, dass das Komma bei jeder Zahl an 19. Stelle ist. Da es immer da ist brauchst du es nicht hin zu schreiben. Stell dir vor du willst 2 Stellen nach dem Komma haben und rechnest einfach in Prozent, schon hast du immer ganze Zahlen. Mit den 18 Stellen läufts genauso, nur dass du halt in Prozent^9 rechnest. Wie gesagt musst du natürlich bei der Ausgabe drauf achten da ein Komma an die richtige immer gleiche Stelle einzufügen.

    Gewonnen hast du damit, dass du deine Zahlen als große Integer darstellen kannst, und Bignum libs gibts viele, da findest du bestimmt eine die dir gefällt, vielleicht mit Anleitung zum installieren und benutzen.


Anmelden zum Antworten