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?
-
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.
-
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).
-
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.
-
Offtopic: Diese automatische Vervollständigung finde ich schon recht beeindruckend ...
-
@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.^^
-
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?