pow ersetzen
-
Hallo,
ich hab folgendes problem und zwar will ich die zwei stellen wo das Programm mit pow arbeitet ersetzen(sodass <math.h> nicht mehr aufgerufen werden muss), hab schon mehrere Sachen ausprobiert aber es will nie so richtig funktionieren.
Danke schonmal :xmas1:int main() { double i, j; int eingabe, temp, inp_okt, inp_du; string res_bin, res_okt; string zif_okt[8] = {"0","1","2","3","4","5","6","7"}; cout << "Dezimahl = ? "; cin >> eingabe; inp_okt = eingabe; inp_du = eingabe; // Potenzverfahren for(i=0; i<=16; i++) { j = pow(2,i); if(inp_du < j) break; } do { i--; if(i < 0) break; temp = pow(2,i); if(temp <= inp_du) { inp_du -= temp; res_bin+="1"; } else{res_bin+="0";} } while(1); // Restwertmethode do { temp = inp_okt%8; inp_okt /= 8; res_okt = zif_okt[temp] + res_okt; if(inp_okt == 0) break; }while(1); // Ergebnisausgabe cout << "Umrechnung einer ganzzahligen, positiven Dezimalzahl in" << endl; cout << "- eine Dualzahl nach der Potenzmethode : Dualzahl = " << res_bin << endl; cout << "- eine Oktalzahl nach der Restwertmethode : Oktalzahl = " << res_okt << endl; return 0; }
-
Was brauchst du denn? Simples quadrieren kannst du auch auch per DEFINE locker lösen.
#DEFINE pow2(a) (a*a)
Oder soll es 2^x sein?
#DEFINE pow2x(a) (1<<a)
wenn ich nicht irre.
-
hmm #define == bäää ...
implementier halt pow schnell selbst ...
-
Wenn die Art der zu berechnenden Potenzen bekannt ist, sind defines nicht nur schneller implementiert, sondern auch schneller ausgeführt.
Eigene Implementierungen von pow sind komplizierter als man denkt. Vor allem wenn der Exponent negativ oder/und ein double ist.
-
Wenn du aber mal genau nachguckst, handelt es sich bei ihm um einen unsigned char, der seinen Wertebereich abdeckt. (0 ... 16)
dein Bitshift:
unsigned int var(0u); // Multiplikation * var *= 32; var << 5; /* 2 ^ 5 = 32 */ // Division / var /= 32; var >> 5; /* 2 ^ 5 = 32 */In dem Fall wäre ein
temp = 1 << i;der Ersatz für:
temp = std::pow(2, i);Wobei das sogar Geschwindigkeitsvorteile bringen sollte. Ein Bitshift ist extrem schnell!
-
In C++ (und auch seit C99) gibt es inline - was gegenüber Makros typsichere und scope-berücksichtigende Implementierungen solcher Funktionen erlaubt. Makros haben seit diesem Feature eigentlich nur noch Nachteile.
-
Hatte mir den Code eigentlich nicht angeschaut. Ist in der aktuellen Form ja auch unleserlich. Wenn er aber nur 2^0 - 2^16 braucht, reicht Bitshift oder gar eine Lookuptable/-list.

-
Fellhuhn schrieb:
Wenn die Art der zu berechnenden Potenzen bekannt ist, sind defines nicht nur schneller implementiert, sondern auch schneller ausgeführt.
Makros für Funktionen sollte man immer vermeiden, zudem sollten inlines genauso schnell sein. und Falls du einen Grund haben willst ruf man dein Makro wie folgt auf:
#DEFINE pow2(a) (a*a) int main() { int x = 1; x = pow2(++x); // FEHLER: nicht etwa x = 4 wie man bei einer Funktion annimmt! // Oder x = pow2(1 + 1); //.... soll ich es weiter führen? }Niemals Makros als Funktionsersatz...
cu André
-
Reicht nicht schon das Standardbeispiel min/max zur Abschreckung?
#include <windows.h> #include <algorithm>Wer es nicht kennt: windows.h definiert min und max als Makros, algorithm als Funktionen in std.
-
#include <string> #include <iostream> int main() { std::cout << "Dezimahlzahl: " << std::flush; int inp_octal(0); int inp_dual(0); std::cin >> inp_dual; inp_octal = inp_dual; unsigned char i(0); for (; (i <= 16) && (j >= inp_du); ++i) j = 1 << i; std::string res_dual; do { --i; temp = 1 << i; if (temp <= inp_dual) { inp_dual -= temp; res_dual += "1"; } else { res_dual += "0"; } } while ((i - 1) >= 0); std::string res_octal; const char letter_octal[8] = {'0', '1', '2', '3', '4', '5', '6', '7'}; do { res_octal.insert(0, letter_octal[inp_octal % 8]); inp_octal /= 8; } while (inp_octal != 0); std::cout << "Umrechnung einer ganzzahligen, positiven Dezimalzahl in \n" << "- eine Dualzahl nach der Potenzmethode: Dualzahl = " << res_dual << "\n" << "- eine Oktalzahl nach der Restwertmethode: Oktalzahl = " << res_octal << std::endl; }... einmal aufgeräumt ... und diese Methode zum Umwandeln ist ja grausam ... guck dir mal std::setbase aus <iomanip> an und std::bitset aus <bitset> ...
Warum nimmst du für ein Zeichen eine Zeichenkette, für eine Ganzzahl einen double usw. alles performance wegschmeißen pur.
-
asc schrieb:
Niemals Makros als Funktionsersatz...
Wenn man etwas nicht einsetzen sollte, nur weil man damit Blödsinn machen kann, dürfte man gar nichts verwenden.
-
Fellhuhn schrieb:
Wenn man etwas nicht einsetzen sollte, nur weil man damit Blödsinn machen kann, dürfte man gar nichts verwenden.
Wenn ich aber die Wahl zwischen einer guten und einer schlechten Möglichkeit habe, ein Problem zu lösen, wieso sollte ich die schlechte bevorzugen? Rasierst Du Dich auch mit einer Axt, obwohl ein Rasierer vorhanden ist?

-
Weil es männlicher ist.

-
Fellhuhn schrieb:
asc schrieb:
Niemals Makros als Funktionsersatz...
Wenn man etwas nicht einsetzen sollte, nur weil man damit Blödsinn machen kann, dürfte man gar nichts verwenden.
Das hat nichts mit "Blödsinn machen" zu tun. Das ist einfach eine Frage der korrekten Funktion.
Makros sind eine stumpfe Textersetzung - ohne Rücksicht auf sprachliche Feinheiten wie Scope oder Parameter-Übergaben. Und dadurch mußt du sehr genau aufpassen, was du übergeben kannst.Um mal das Quadrieren als Beispiel zu nehmen - deinem
#define sqr(x) ((x)*(x))kannst du keine Ausdrücke mit Nebeneffekten übergeben und brauchbare Ergebniss erwarten - und ich kenne auch keine Makro-Alternative, um das hinzubekommen. Im Gegensatz dazu hattemplate<typename T> inline T sqr(T val) {return val*val;}die selbe Wirkung, aber keins der Probleme des Makros.
-
LordJaxom schrieb:
Reicht nicht schon das Standardbeispiel min/max zur Abschreckung?
Schlechtes Beispiel. min/max ist nun gerade einer der Fälle, wo ein Macro tatsächlich Vorteile hat. Siehe http://www.ddj.com/cpp/184403774
#include <windows.h> #include <algorithm>=>
#include <windows.h> #undef max #undef min #include <algorithm>Zugegeben, wenn man das nicht weiß, resultieren einige echt eklige Bugs.
-
hmm man soll
#define NOMINMAXnutzen, wobei dann wieder alle anderen Microsoft-Header streiken
Also ist nen bissel doof und am einfachsten wirklich durch #undef NACH allen Microsoft-Headern zu lösen ...
-
Ich kenne die Umgehungsmöglichkeit, wollte auch nur auf das Problem hinweisen. Und das Makro NOMINMAX gab es bestimmt nicht von Anfang an (
Bekämpfung der Symptome)
-
hmpf ich glaub ich hätte besser mal die aufgabenstellung mit gepostet:
Zahlenkonvertierung
Schreiben Sie ein C++-Programm, das positive, ganze Dezimalzahlen in die
entsprechenden Dualzahlen und Oktalzahlen umrechnet.
Hinweise, verbindlich:
- Die Umwandlung in Dualzahlen muss nach der Potenzenmethode, die
Umrechnung in Oktalzahlen nach der Restwertmethode erfolgen.
- Speichern Sie die Ergebnisse in Strings.
- Benutzen Sie einen String-Vektor, um die Ziffern des Oktalsystems zu speichern:
string oktalziffer[8]={"0","1","2","3","4","5","6","7"};
- Der Modulo-Operator % gibt den ganzzahligen Rest der Integer-Division zweier
Zahlen zurück:
11 % 4 = 3
- Die Integer-Division / schneidet die Nachkommastellen des Divisionsergebnisses
ab:
9 / 2 = 4
Testlauf (Eingaben unterstrichen):
Dezimalzahl = ? 255
Umrechnung einer ganzzahligen, positiven Dezimalzahl in
- eine Dualzahl nach der Potenzenmethode : Dualzahl = 11111111
- eine Oktalzahl nach der Restwertmethode: Oktalzahl = 377
Press any key to continue
-
Die Lösung wurde doch schon genannt (auch wenn sie in der anschließenden Diskussion über Makros vs. Inline-Funktionen untergegangen ist). Du brauchst dort nur Potenzen von 2 (
pow(2,i);und dazu reicht der Shift-Operator völlig aus:inline int exp2(int x) { return 1<<x; } ... int i,j;//Gleitkomma-Werte sind hierfür überflüssig ... for(i=0; i<=16; i++) { j = exp2(i);// j = pow(2,i); if(inp_du < j) break; } ...
-
ODer einfach auf die erste Seite auf meine Beiträge achten und mal die anderen gekonnt außer acht lassen ...