Zahlensysteme in andere umwandeln mit Komma



  • Die Zahlen sind mit Horner-Schema in Dezimalzahlen umzuwandeln. Hab das erstmal so versucht:
    a) Geg: 0.371 index:8 ges: index:10 ->0.486 index:10, vorgegangen nach dem Komma mit hoch minus 1 usw.
    b) geg: 0.FFFF index:16, ges: index:10-> bin analog zu a vorgegangen aber die brüche werden so klein im Nenner, hab das gefühl das was nicht stimmt
    c) geg: -ABD.DE index:16 -> ges; index:10-> -2749.867188 index:10 spuckt mir mein TR aus.

    Mein Problem: es fühlt ich falsch an^^. Gefragt ist ja das Horner Schema und das haben wir mit Tabelle gemacht. Allerdings soll dieses ja den Vorgang vereinfachen/beschleunigen. Aber mit den Brüchen zu arbeiten find ich nicht beschleunigend.

    Wie geht man mit dem Horner-Schema ab dem Komma hier vor? Also mit welcher festen Zahl wird da multipliziert?

    LG und Danke im Voraus.



  • Du kannst das Horner Schema auch einfach für die Nachkommastellen verwenden.

    Letztes Beispiel:
    ABD => 10*(16 ^ 2)+11*(16 ^ 1)+13*(16 ^ 0) = 2749
    .DE = DE / 100 => (13*(16 ^ 1)+14*(16 ^ 0))/(16 ^ 2) = 222/(16 ^ 2) = 0.8671875



  • @Martin-Richter Ah, danke. c) habe ich gut verstanden. Muss bei 0.FFFF die Geschichte mit 15*16 etc durchgespielt werden? Kann man das nicht vereinfachen? Hab da 0+15/16+15/256+15/4096+15/65536 zusammen. Das kanns doch nicht sein oder etwa doch?


  • Mod

    Warum nicht? Streng nach Schema ist das schon richtig. Wenn du clever bist, kannst du natürlich sehen, dass das (16^4 -1)/16^4 ist (also 65535/65536), weil du weißt, dass das 1.0000 wird, wenn du 0.0001 (hexadezimal) hinzu zählst. Aber das ist ja schon eine ziemliche Ausnahme, dass man das leicht ablesen kann.


  • Gesperrt

    Das müsste es doch sein:

    #include <iostream>
    #include <string>
    
    void horner_scheme(std::string hexString) {
        bool isNegative = false;
        if (hexString[0] == '-') {
            isNegative = true;
            hexString = hexString.substr(1);
        }
        int indexOfPoint = hexString.find('.');
        std::string integerPart = hexString.substr(0, indexOfPoint);
        std::string fractionPart = hexString.substr(indexOfPoint + 1);
        long int first = 0;
        long int second = 0;
        for (int i = 0; i < integerPart.length(); i++) {
            if (integerPart[i] >= '0' && integerPart[i] <= '9'){
                first = first * 16 + (integerPart[i] - '0');
            } else if (integerPart[i] >= 'A' && integerPart[i] <= 'F'){
                first = first * 16 + (integerPart[i] - 'A' + 10);
            } else {
                std::cout << "invalid input" << std::endl;
                return;
            }
        }
        for (int i = 0; i < fractionPart.length(); i++) {
            if (fractionPart[i] >= '0' && fractionPart[i] <= '9'){
                second = second * 16 + (fractionPart[i] - '0');
            } else if (fractionPart[i] >= 'A' && fractionPart[i] <= 'F'){
                second = second * 16 + (fractionPart[i] - 'A' + 10);
            } else {
                std::cout << "invalid input" << std::endl;
                return;
            }
        }
        if (isNegative) {
            first = -first;
        }
        std::cout << first << "." << second << std::endl;
    }
    
    int main(int argc, char const *argv[])
    {
        horner_scheme("12345.67"); // => 74565.103
        horner_scheme("ABD.DE"); // => 2749.222
        horner_scheme("FF.FF"); // => 255.255
        horner_scheme("-12345.67"); // => -74565.103
        return 0;
    }
    

    (Es geht bestimmt auch kürzer, aber es soll ja das Vorgehen mit Stift und Papier verdeutlichen).


  • Gesperrt

    Ups, vergessen 😞 :

        if (indexOfPoint == std::string::npos) {
            std::cout << "invalid input" << std::endl;
            return;
        }
    

    Gut wäre es auch, diese Methode zu splitten und noch mal das Körner-Schema zu extrahieren.


  • Gesperrt

    Offtopic: Diese automatische Vervollständigung finde ich schon recht beeindruckend ...

    https://postimg.cc/5jBwLG35


  • Gesperrt

    @meuterei sagte in Zahlensysteme in andere umwandeln mit Komma:

    if (isNegative) {
        first = -first;
    }
    

    Man muss da noch einmal 1 abziehen, oder?



  • @SeppJ Danke für den Zuspruch und generell die schnelle Antwort hier im Forum, mega. Also das ist schon stark aber darauf wäre ich jetzt, ehrlicherweise, nicht gekommen. Also irgendwie schwappt es rüber, irgendwie aber auch nicht.^^


  • Gesperrt

    Eine neue Version:

    #include <iostream>
    #include <string>
    #include <math.h>
    
    bool is_valid_hex_string(std::string hexString)
    {
        for (int i = 0; i < hexString.length(); i++)
        {
            if (!((hexString[i] >= '0' && hexString[i] <= '9') || (hexString[i] >= 'A' && hexString[i] <= 'F')))
            {
                return false;
            }
        }
        return true;
    }
    
    long int horner_scheme_1(std::string hexString)
    {
        long int result = 0;
        for (int i = 0; i < hexString.length(); i++)
        {
            if (hexString[i] >= '0' && hexString[i] <= '9')
            {
                result = result * 16 + (hexString[i] - '0');
            }
            else if (hexString[i] >= 'A' && hexString[i] <= 'F')
            {
                result = result * 16 + (hexString[i] - 'A' + 10);
            }
            else
            {
                std::cout << "invalid input" << std::endl;
                return -1;
            }
        }
        std::cout << result << std::endl;
        return result;
    }
    
    double horner_scheme(std::string hexString)
    {
        bool isNegative = false;
        if (hexString[0] == '-')
        {
            isNegative = true;
            hexString = hexString.substr(1);
        }
        int indexOfPoint = hexString.find('.');
        if (indexOfPoint == std::string::npos || !is_valid_hex_string(hexString.substr(0, indexOfPoint)) || !is_valid_hex_string(hexString.substr(indexOfPoint + 1)))
        {
            std::cout << "invalid input" << std::endl;
            return -1;
        }
        long int integerPart = horner_scheme_1(hexString.substr(0, indexOfPoint));
        long int fractionPart = horner_scheme_1(hexString.substr(indexOfPoint + 1));
        if (isNegative)
        {
            integerPart = -integerPart;
        }
        std::cout << integerPart << "." << fractionPart << std::endl;
        return integerPart + fractionPart / pow(10, round(log10(fractionPart + 1) + 1));
    }
    
    int main(int argc, char const *argv[])
    {
        std::cout << horner_scheme("12345.67") << std::endl; // => 74565.103
        std::cout << horner_scheme("ABD.DE") << std::endl;   // => 2749.222
        std::cout << horner_scheme("AB0D.DE") << std::endl;  // => 43789.222
        std::cout << horner_scheme("-F.0") << std::endl;     // => -15.0
        return 0;
    }
    

    Leider ist return integerPart + fractionPart / pow(10, round(log10(fractionPart + 1) + 1)); aus einem mir noch unbekannten Grund ungenau ...

    Beispielweise ist die vorletzte Ausgabe:

    43789
    222
    43789.222
    43789.2
    

    obwohl es ja eigentlich .222 sein sollte. Kann mir jemand vielleicht einen Tipp geben?


Anmelden zum Antworten