2011-07-16 7 views
5

Czy istnieje bezpośredni sposób, aby zmienić liczbę ujemną na dodatnią za pomocą operacji bitowych w Actionscript 3? Wydaje mi się, że przeczytałem gdzieś, że jest to możliwe i szybsze niż użycie Math.abs() lub pomnożenie przez -1. Czy jestem w błędzie i to był sen po całym dniu nauki o bajtach i operacjach bitowych?Czy mogę zamienić liczbę ujemną na dodatnią przy operacjach bitowych w Actionscript 3?

co widziałem było to, że prawie bitowe NOT załatwia sprawę:

// outputs: 449 
trace(~(-450)); 

Jeśli ktoś znaleźć na to pytanie i jest zainteresowany - w 5 milionów iteracji ~(x) + 1 wynosi 50% szybciej niż Math.abs(x).

+0

abs nie jest tym samym, by nie + 1, unsigns ABS, NIE + 1 neguje . Jeśli więc przekażesz liczbę dodatnią, uzyskasz inne wyniki. – ekerner

Odpowiedz

12

Trzeba dodać jeden po zażyciu negacji bitowej. To jest właściwość two's complement number system. Nie jest on powiązany z Actionscript (poza domniemaną różnicą wydajności).

Więc (~(-450)+1) daje 450
i (~(450)+1) daje -450.

Jak wspomniano w komentarzach, odpowiedź ta została napisana w odpowiedzi na pytanie, w celu rozwiązania drobnego problemu w pytającym pytaniu. Ta odpowiedź nie jest potwierdzeniem tej techniki dla ogólnego zastosowania w programowaniu.

+0

Dziękuję za link, nie wiedziałem o takiej rzeczy z "dodatkowym numerem dwa" – Rihards

+0

@ rwong po prostu ciekawy, czy BitWise lepsza wydajność niż "liczba = (liczba <0? -numbe r: number); "w tym przypadku negującym –

+1

Ostrożnie, najmniejsza liczba całkowita w systemie nie może być tak pozytywna, +1 spowoduje przepełnienie liczby całkowitej. –

9

Użyj reguła, która mówi

~(x) = (-x)-1 
+0

To pewnie oczywiste, że prosta algebra doprowadza cię do formuły, którą chciałeś, a mianowicie '-x = ~ x + 1', ale dobrą rzeczą do dodania jest to, że ta sztuczka działa tylko dla liczb całkowitych i dla najmniejszej możliwej liczby całkowitej, nazwijmy ją 'z', w rzeczywistości odzyskasz' z', ponieważ sposób w jaki liczba całkowita jest reprezentowana w tak zwanym "dwójkowym uzupełnieniu"."Więc upewnij się, że robisz to tylko dla liczb całkowitych w zakresie." –

+0

jest BitWise lepszą wydajnością niż "number = (number <0? -liczba: number);" w tym przypadku negowania? –

+0

Wyrażenie "number = (number < 0? -liczba: liczba) 'oblicza wartość bezwzględną, podczas gdy' liczba = ~ liczba + 1 'neguje wartość.Jest to dwie różne operacje.Jeśli chodzi o wydajność, zależy to od sposobu kompilacji dwóch wyrażeń. taki, jaki masz, może prowadzić do [prognozowania gałęzi nie powiedzie się] (http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array) i tam są super ładne optymalizacje kompilatora, aby go ominąć, ale dlaczego porównać? Są to dwie różne operacje: –

4

Jeśli dwa uzupełnieniem jest używany (zwykle bywa), negacja jest uzupełnienie następnie dodać 1:

-x == ~x + 1 

Czy to szybciej zależy od optymalizacji preform kompilatora. W razie wątpliwości przetestuj.

+0

+1 za sugestię testową i uwagę na temat tego, w jaki sposób jest to zależne. –

1

Negacja to operator sam dla siebie, operator unitarny -. Używanie tego jest tak samo szybkie jak używanie operacji bitowych i oszczędza wiele pisania.

negativeX = -positiveX; // is the same as (~positiveX) + 1 

Nie dokonuje się mnożenia.

Jeśli potrzebna jest szybkość, a użytkownik nie wie, czy liczba jest ujemna, czy dodatnia, operator trójskładnikowy ?: jest szybszy niż wprowadzenie obciążenia związanego z wezwaniem funkcji z dnia Math.abs().

positiveX = unknownX < 0 ? -unknownX : unknownX; 
-2

Spróbuj tego:

var number:Number = 10; 
//Makes a number 
trace(number) 
//Tells you the number BEFORE converting 
number = number - number * 2; 
//Converts number 
// Takes number times 2 and subtracts it from original number 
trace(number); 
//Tells you the number AFTER converting 

w końcu, wszystko czego potrzebujesz to:

var number:Number = 10; 
number = number - number * 2; 
Powiązane problemy