Vektoren vergleich in C
-
Andromeda schrieb:
Wutz schrieb:
Andromeda schrieb:
return (((amountv2-amountv1)<1)-1)|(amountv1!=amountv2);
Nonsens.
Bitoperatoren auf negative int loszulassen ist einfach nur dumm und ahnlungslos.Dann check mal diese hübsche Variante:
return ((amountv2-amountv1)<0) - ((amountv2-amountv1)>0);
Auch nicht besser. amount2v2-amountv1 oder amountv2-amountv1 kann immer noch überlaufen und UB bedingen.
-
camper schrieb:
Auch nicht besser. amount2v2-amountv1 oder amountv2-amountv1 kann immer noch überlaufen und UB bedingen.
Wie sollen die denn überlaufen?. Das sind beides nichtnegative Werte
-
DirkB schrieb:
camper schrieb:
Auch nicht besser. amount2v2-amountv1 oder amountv2-amountv1 kann immer noch überlaufen und UB bedingen.
Wie sollen die denn überlaufen?. Das sind beides nichtnegative Werte
Ah stimmt, hätte mehr als die letzte Seite lesen sollen.
Trotzdem witzig, dass über Mikrooptimierungen auf Assemblerebene diskutiert wird, anstatt erst mal auf das überflüssige Wurzelziehen zu verzichten.
-
camper schrieb:
Trotzdem witzig, dass über Mikrooptimierungen auf Assemblerebene diskutiert wird, ...
Gibt es da keine Signum-Funktion?
camper schrieb:
... anstatt erst mal auf das überflüssige Wurzelziehen zu verzichten.
Tja, erstmal die letzten Promille raus kitzeln, bevor wir dann die Prozente raus holen.
-
camper schrieb:
Trotzdem witzig, dass über Mikrooptimierungen auf Assemblerebene diskutiert wird, anstatt erst mal auf das überflüssige Wurzelziehen zu verzichten.
Jemand erwähnte, dass das if/elseif/else um den Rükgabewert zu kriegen, kürzer zu coden sei. Damit ging das los.
Aber du bringst mich auf eine Idee: anstatt die echte Länge des Vektors auszurechnen, müsste für einen Größenvergleich die Summe der Beträge der Komponenten ausreichend sein.
Also statt: echte_laenge = sqrt (a*a + b*b + c*c + ...)
richtwert = abs(a) + abs(b) + abs(c) + ...Oder?
-
Andromeda schrieb:
Also statt: echte_laenge = sqrt (a*a + b*b + c*c + ...)
richtwert = abs(a) + abs(b) + abs(c) + ...Nein, so einfach ist es dann doch nicht
Die Quadrate musst du noch bilden, aber auf die Wurzel kannst du verzichten.
Denn es gilt:
0 ≤ d < f <=> 0 ≤ sqrt(d) < sqrt(f)
-
Andromeda schrieb:
Jemand erwähnte, dass das if/elseif/else um den Rükgabewert zu kriegen, kürzer zu coden sei. Damit ging das los.
Nein, mir geht es primär um zwei Dinge:
- Lesbarkeit
- KürzeDann kommt Geschwindigkeit. Wenn du genug Erfahrung hast, kannst du alle drei kombinieren.
Dein Code ist weniger gut lesbar, er mag kürzer im Quellcode sein, generiert aber mehr Maschinencode. Geschwindigkeit habe ich nicht getestet.
Andromeda schrieb:
Also statt: echte_laenge = sqrt (a*a + b*b + c*c + ...)
richtwert = abs(a) + abs(b) + abs(c) + ...Oder?
Ist nicht äquivalent. Das
abs
sparen wir uns mal grad:richtwert_falsch_1 = 10 + 5 + 5; /*20*/ richtwert_falsch_2 = 20 + 0 + 0; /*20, würde also passen*/ richtwert_korrekt_1 = 10*10 + 5*5 + 5*5; /*150*/ richtwert_korrekt_2 = 20*20 + 0*0 + 0*0; /*400 - und plötzlich passt es nicht mehr*/
Glücklicherweise sind Multiplikationen meines Wissens nicht so teuer wie Divisionen.
-
Dirk, Dachschaden: Danke!
-
Kurze Anekdote:
Ein Programm lief sehr langsam, wenn man viele Variablen verwendete. perf hat mir als Verursacher die Funktion exp() angezeigt (über 40% der Gesamtlaufzeit).
Es wurde vielfach für einen double-vector der Länge n für alle i,j aus [0..n-1], i!=j jeweils
exp(v[i] - v[j])
berechnet. Berechnet man allerdingsexp(i)
für alle Elemente vor und macht dann eine Division statt der Subtraktion, wird der Code plötzlich wieder schnell... (in meinem Fall war n ~ 20)Also: gerade diese komplizierten Funktionen wie exp, sqrt, ln klug zu ersetzen oder gar ganz drauf zu verzichten, kann sich lohnen!
-
Wo wir grad so schön beim Thema sind ...
float Q_rsqrt( float number ) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( long * ) &y; // evil floating point bit level hacking i = 0x5f3759df - ( i >> 1 ); // what the fuck? y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed return y; }