Für Anfänger bzw. Advanced Coders - Ein kleiner Buchtip ! {
-
@HumeSikkins: Du hast es geschrieben. Meine größte Schwäche ist meine Arroganz :D. Ich habe übrigens nicht genörgelt sondern "nur" neunmal-klug korrigiert. Aber das ist hier noch mehr OT als das ganze sinnlos.
PS: Du willst eine schöne Lösung? Ohne Vergleich oder mathematische Funktion geht es bestimmt nicht:
int f(int x) { return x / (int) sqrt(x * x); }
[ Dieser Beitrag wurde am 27.04.2003 um 12:35 Uhr von Mr. N editiert. ]
-
Klingt doch intressant der Schinken!
Aber wer hat schon 25EUR fuer sowas
Kleiner Tipp:
Also ab zu EBay! habs grad fuer 9EUR inkl. Versand sofortkauf eingesackt.
-
Original erstellt von Mr. N:
**```cpp
int f(int x) {
return x / (int) sqrt(x * x);
}]**
Schlecht, weil 0.
Bibliotheksaufrufe sind übrigens plöt:int f(int n) { char b[sizeof 2 * CHAR_BIT + 2]; int a[] = { 1, 0, -1 }; sprintf(b, "%d", n); return a[(!strncmp(b, "-", 1)) * 2 + (!strncmp(b, "0", 1))]; }
Haha, das will man nicht.
Es ginge auch mit Fließkommazahlen:
int f(int n) { double res = sin(n / (double)INT_MAX) * 1.9; double a = ceil(res); double b = floor(res); return a+b; }
Lösungen ohne Bibliothek sollten auch gehen:
+ über Lookuptabellen (mit Arrays ist das platzraubend; man wird also mit Integerbits rumspielen)
+ ausrollen (und approximieren) von den Standardfunktionen (bei ceil/floor/sin sollte man das hinbekommen)Mehr fällt mir gerade nicht ein.
[ Dieser Beitrag wurde am 27.04.2003 um 13:44 Uhr von Daniel E. editiert. ]
-
Folgender Code funktioniert:
int f(int x) {
return (int) round(x / (abs(x) + 1.0));
}
-
round?
-
Original erstellt von <J_Red>:
**Folgender Code funktioniert:int f(int x) {
return (int) round(x / (abs(x) + 1.0));
}**int f(int x) { return x/(abs(x)+!x); }
auch.
ich behaupte (um es maschinennäher auszudrücken): eine lösung enhält _mindestens_ 1 vergleichende instruktion (die auch ausgewertet wird) oder funktioniert mit gleitkomma-funktionen. mal schaun wie sich ceil implementieren lässt:int ceil(int x) { return x + Z; }
wobei Z=größte zahl kleiner null. -2.1 wäre dann: int(-2.1 + 0.99)=-1 ... nicht wirklich. ich wage also zu behaupten, dass die aufgabenstellung ohne (impliziten) vergleichsoperator nicht zu lösen ist.
-
klar geht das.
-
Original erstellt von volkard:
klar geht das.wie? (/me ist jetz im believe-until-impossible modus)
-
#include <iostream> using namespace std; int sgn(int x) { return (x>>31)-(-x>>31); } int main() { for(int i=-10;i<=10;++i) cout<<i<<' '<<sgn(i)<<endl; return 0; }
-
irgendwie hast du recht. ich könnte jetzt sagen, ich hätte das nur gesagt, weil ich wissen wollte, ob jemand die lösung findet, aber so ein schlechter verlierer bin ich auch wieder nich *g*.
-
Original erstellt von Mr. N:
irgendwie hast du recht. ich könnte jetzt sagen, ich hätte das nur gesagt, weil ich wissen wollte, ob jemand die lösung findet, aber so ein schlechter verlierer bin ich auch wieder nich *g*.andere frage:
kann man jede funktion von int auf int nur mit >>, <<, &, | und ~ ausdrücken?
edit: nehmen wir noch + und - dazu.[ Dieser Beitrag wurde am 27.04.2003 um 15:10 Uhr von volkard editiert. ]
-
Original erstellt von volkard:
**```cpp
int sgn(int x)
{
return (x>>31)-(-x>>31);
}Einmal mit INT_MIN und ohne fixierte Integerbreite, aber ohne Zweierkomplement bitte :->.
-
Original erstellt von Daniel E.:
Einmal mit INT_MIN und ohne fixierte Integerbreite, aber ohne Zweierkomplement bitte :->.hä? naja, ich hätte, wenn ich portabilität wollte sizeof(int)*8 genommen
-
Original erstellt von volkard:
[quote]Original erstellt von Mr. N:
[qb]irgendwie hast du recht. ich könnte jetzt sagen, ich hätte das nur gesagt, weil ich wissen wollte, ob jemand die lösung findet, aber so ein schlechter verlierer bin ich auch wieder nich *g*.andere frage:
kann man jede funktion von int auf int nur mit >>, <<, &, | und ~ ausdrücken?
edit: nehmen wir noch + und - dazu.[/QB][/QUOTE]wenn if und goto und variablen möglich sind, würde ich sagen ja. das ist aber auch nur eine vermutung (aber dadurch begründet, dass ein mikroprozessor auch nur verknüpfungen und speicher und takte hat).
bsp.:int mul(int x, int y) { while (--y) x += x; return x; }
bzw. als state-machine:
int mul(int x, int y) { int state = 0; for (;;) switch (state) { case 0: if (--y) state = 1; else state = 2; break; case 1: x += x; state = 0; break; case 2: return x; }
(ok, die state-machine ist ziemlich trivial. aber ich stell mir prozessoren als komplexe state-machines vor, also musste das sein)
-
Original erstellt von Mr. N:
*hä? naja, ich hätte, wenn ich portabilität wollte sizeof(int)8 genommenDamit beachtest Du die Größe eines Integers, nicht seinen Wertebereich. Ein Integer darf laut Norm Padding Bits enthalten (mir ist aber keine Umgebung bekannt, die das tut). Damit kann zwar das altbekannte 'sizeof(char) <= sizeof(int)' gelten, aber '(unsigned char)-1' ist trotzdem größer als '(unsigned)-1'; natürlich immer im Rahmen der, in C exakt spezifizierten, Minimalwertebereiche.
Ein Byte hat übrigens nicht per Definition 8, sondern CHAR_BIT, Bit. Damit schlägt deine "Lösung" wirklich ordentlich daneben.Volkards Lösung wäre schon okay gewesen, wenn sie den Fall für INT_MIN lösen würde (die restprobleme hätte ich tolleriert, da hier sowieso fast nur Leute mit Mainstreammaschinen lesen [nehme ich an]). INT_MIN ist üblicherweise betragsmäßig größer als INT_MAX -- daran scheitert auch die abs-Lösung. Eine Lösung, die nicht den gesamten Integerbereich umfasst ist wertlos.
[ Dieser Beitrag wurde am 27.04.2003 um 15:44 Uhr von Daniel E. editiert. ]
-
Hallo,
aber wie sieht das mit dem shiften und signed-Integern aus? Ich dachte immer, dass wäre dann nicht mehr portabel (implementation-defined?). Von wegen Füllen-mit-sign-bit-ja/nein.[ Dieser Beitrag wurde am 27.04.2003 um 15:51 Uhr von HumeSikkins editiert. ]
-
@Daniel: Nenne mir _1_ Maschine mit nicht 8 Bit. Und sizeof(int)*CHAR_BIT bzw. INT_BIT sollte reichen. Du bist noch arroganter als ich :p.
-
Original erstellt von Daniel E.:
Volkards Lösung wäre schon okay gewesen, wenn sie den Fall für INT_MIN lösen würde (die restprobleme hätte ich tolleriert, da hier sowieso fast nur Leute mit Mainstreammaschinen lesen [nehme ich an]).Mir ist scheiß-egal, was du tolerierst. Mrn toleriert meine Lösung. Die Lücke bei INT_MIN war von anfang an bekannt, ich hab sie auch im chat gesagt aber der einfachheit halber nicht gepostet. Klar kann man die auch noch wegmachen.
Eine Lösung, die nicht den gesamten Integerbereich umfasst ist wertlos.
Kommt auf die Verwendung an. Fast immer wird nicht der ganze Wertebereich gebraucht. So überwiegend sogar, daß ich bei deinem Gerede zunächst an Realitätsverlust denken muß. Besonders unterstützt durch Annahmen wie padding bits in integers und bytes, die nicht 8 bits groß sind.
-
Original erstellt von HumeSikkins:
Hallo,
aber wie sieht das mit dem shiften und signed-Integern aus? Ich dachte immer, dass wäre dann nicht mehr portabel (implementation-defined?). Von wegen Füllen-mit-sign-bit-ja/nein.Glaube kaum, dass der Code auf solche Maschinen je portiert werden sollte.
-
Oha. Bitte sagt mir, dass nicht ich mit meinem ersten Einwurf für die jetzt herschende schlechte Stimmung verantwortlich bin.
Für mich sind viele der Einwände von Daniel E. neu. Insofern empfinde ich sie weder als arrogant noch als sonst wie ärgerlich. Eher als extrem lehr- und hilfreich.