Przeszukiwanie liczby long Java

Przeszukiwanie liczby long Java
FA
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 5 lat
  • Postów:44
0

Witam,
szukam najszybszego sposobu na przeszukiwaniu longa. Już tłumaczę o co mi chodzi
załóżmy, że mam liczbę: 0b000000000010000100000010000001000000000100010000000001000000000L
Potrzebuję znaleźć pozycje wszystkich jedynek występujących w liczbie. Czy jest do tego jakaś biblioteka lub szybszy sposób niż pętla i sprawdzanie pojedynczo każdego bitu?
Pozdrawiam

YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:2 dni
  • Postów:2370
0

A czego spodziewasz się na wyjściu algorytmu?

-- edited: w sensie struktury danych przechowującej wynik

edytowany 1x, ostatnio: yarel
AK
  • Rejestracja:prawie 7 lat
  • Ostatnio:około miesiąc
  • Postów:3561
1

Przesuwanie maski bitowej 0x8000...000, bitowe mnożenie i pętla może być dość szybkie na JVM, Po iluś przekręceniach się pętli zostanie mocno zoptymalizowane - ale POD WARUNKIEM że w pętli nie powołujesz obiektów.

Pokaż co wymyśliłeś do tej pory, również sposób skorzystania z wyniku


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 1x, ostatnio: AnyKtokolwiek
YA
Dokładnie, sposób w jaki chce korzystać z wyniku może zabić tę optymalizację na wyszukiwanie 1.
FA
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 5 lat
  • Postów:44
0

knightMoves jest tym moim longiem, w którym szukam jedynek
pieces to moje figury (aplikacja to szachy)

Kopiuj
for(int j = 0; j < pieces.length; j++) {
                if((knightMoves & (1L << j)) > 0) {
                    possibleMoves.add(j);
                }
            }
edytowany 3x, ostatnio: Fafkorn
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:3 minuty
  • Postów:4923
1

Wedle mojej wiedzy nie ma jakiegoś szybszego sposobu niz sprawdzenie wszystkich bitów. A po co Ci to? Przecież złożoność nie jest duża (64 bity). Przykładowy kod (na wyjściu jest lista, listę Możesz sobie przekonwertować do czego tam Chcesz):

Kopiuj
import java.util.ArrayList;
import java.util.List;

public class SearchLong {
    private static List<Long> positions_of_one(long number) {
        List<Long> ones = new ArrayList<>();
        int position = 1;

        while (number != 0) {
            if ((number & 1L) != 0) {
                ones.add(position);
            }
            position++;
            number = number >>> 1;
        }
        return ones;
    }
    public static void main(String [] args)
    {
        System.out.println(positions_of_one(7L)); // [1, 2, 3]
    }
}

edytowany 1x, ostatnio: lion137
vpiotr
position może być typu int.
lion137
Rzeczywiście, po co tam dałem long? Edycja.
CS
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 23 godziny
  • Postów:296
1

Najszybsze są metody najstarsze ;-) czyli lookup. Utwórz tablicę z liczbami jedynek dla kolejnych wartości np. bajtu lub słowa. Dzielisz longa na kolejne bajty, słowa, które dają Ci indeksy do komórek w lookup i w ośmiu albo czterech krokach masz liczbę jedynek.

jarekczek
  • Rejestracja:prawie 8 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Siemianowice Śląskie
  • Postów:500
0

Optymalne wyszukiwanie pierwszej jedynki jest dostępne z poziomu C. Wspiera to procesor. W Javie się nie da. Ale może wcześniej należało coś zoptymalizować, zanim dostałeś te "longi".


Przeważnie ignoruję niezarejestrowanych użytkowników.
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
1
jarekczek napisał(a):

Optymalne wyszukiwanie pierwszej jedynki jest dostępne z poziomu C. Wspiera to procesor. W Javie się nie da. Ale może wcześniej należało coś zoptymalizować, zanim dostałeś te "longi".

To nieprawda. Jeśli chodzi Ci o **bsr **i bsf to masz je w javie dostępne przez:
https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html#numberOfTrailingZeros-long-
https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html#numberOfLeadingZeros-long-


jeden i pół terabajta powinno wystarczyć każdemu
jarekczek
A to ciekawostka, że Java tak bardzo zbliża się do instrukcji procesora. W sumie dobrze, można programować ala real-time. W zasadzie AtomicInteger.incrementAndGet też jest z rodziny instrukcji procesora, czyli aż tak nie powinno to dziwić :)
jarekr000000
Java jest strasznie niskopoziomowa. Normalnie assembler z nieco wygodniejszą składnią :-) Można czasem sobie pooglądać co tworzy -XX:+PrintAssembly, tylko trzeba podegrać symbole (mnemoniki) (odpowiednia biblioteka .so lub .dll). Widać, że całkiem ostro korzysta z SIMD, rejestrów i instrukcji (czasem nieoptymalnie, ale korzysta :-) ). Z drugiej strony to oczywiście strata czasu - można zrozumiec czemu coś wolno działa czasem, ale zwykle trudno coś z tym zrobić( czyli może nie całkiem assembler).

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.