Dodatnia negacja w Javie

0

Witam!
Jestem nowy na tym forum, i chciałbym zapytać, jak zrobić, żeby po operacji negacji, czyli np. ~10 (binarnie: 1010) wynik nie wynosił -11 tylko 5, 10 = binarnie 1010 a po negacji 0101 czyli 5.
Z góry dziękuję za pomoc.

2

Java nie wspiera liczb bez znaku (unsigned). Jeżeli chcesz znegować pojedyńczy bajt to możesz to zrobić np. tak:

int n = 0xF0;
n = 0xFF & (~n);

Jeżeli zależy Ci tylko na wyniku końcowym to metoda: https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#toUnsignedString-int-
potraktuje inta jak liczbę bez znaku przy konwersji do Stringa.

3
Tomasz1092 napisał(a):

Witam!

Jestem nowy na tym forum, i chciałbym zapytać, jak zrobić, żeby po operacji negacji, czyli np. ~10 (binarnie: 1010) wynik nie wynosił -11 tylko 5, 10 = binarnie 1010 a po negacji 0101 czyli 5.
Z góry dziękuję za pomoc.

Hej, ale w żaden sposób negacja 10 to nie będzie 5 -- bo taka negacja zawsze jest do rozmiaru słowa -- a rozmiaru słowa == 4 bity w dzisiejszych kompach nie uświadczysz...

Negacja 1010 to negacja 00001010 (jeśli bierzemy bajt) a to jest 11110101 a to nie jest 5 (bez znaku czy ze znakiem).

1
byte a = 10;
byte b = (byte)(a ^ (byte)0x0F);
System.out.println(b);

Wynik: 5

https://ideone.com/o5OLYw

1
vpiotr napisał(a):
> byte a = 10;
> byte b = (byte)(a ^ (byte)0x0F);
> System.out.println(b);
> ```
> 
> Wynik: 5
> 
> https://ideone.com/o5OLYw

No oczywiście, że tak -- ale wciąż trzeba wiedzieć o ile bitów chodzi OPowi -- u Ciebie zawsze jest 4, ale coś mi się widzi, że chodzi o co innego. Być może @Tomasz1092 chce, żeby negacja 10 to było 5, a negacja 5 to było 2... Taka dziwna negacja, która nie jest swoją funkcją odwrotną, ale pewien sens ma (bierzemy zawsze minimalną liczbę bitów). Ciekawe, że taka negacja jest funkcją malejącą dla wartości dodatnich... :)
1

Mały hint: Integer.numberOfLeadingZeros i - odejmowanko, potega i można poskładać z czym zrobić and.

2

Uwaga w kwestii formalnej: negacją liczby 10 jest -10.

Wracając do bitowych operacji, wiki podaje takie matematyczne rozwinięcie
screenshot-20210419170728.png

̶P̶r̶z̶e̶c̶i̶e̶ż̶ ̶t̶o̶ ̶j̶e̶s̶t̶ ̶r̶ó̶w̶n̶e̶ ̶̶̶x̶-̶1̶̶̶,̶ ̶a̶l̶b̶o̶ ̶j̶a̶ ̶m̶a̶m̶ ̶j̶a̶k̶i̶e̶ś̶ ̶z̶a̶ć̶m̶i̶e̶n̶i̶e̶ ̶u̶m̶y̶s̶ł̶u̶ ̶(̶?̶)̶

UPDATE:

Bazując więc na wiki i przy jej zastrzeżeniach, matematyczne rozwiązanie bez uciekania się do haków związanych z reprezentacją liczby, to będzie tak:

Math.pow(2,Math.floor(Math.log(x)/Math.log(2))+1)-1-x
6

@PanamaJoe:
dobrze kombinujesz, ale te nawiasy oznaczają "floor" - dlatego nie skróci się tak prosto logarytm.
https://pl.wikipedia.org/wiki/Pod%C5%82oga_i_sufit

2

Za każdym razem gdy do operacji bitowych jakiś programista używa Math.* gdzieś na świecie przekręca się jeden bit.

Dorzucam jeszcze wersję opartą o API Integera z elastyczną liczbą bitów (ograniczoną z góry wybranym typem):

int reverseBits(int value) {
  return value ^ ((Integer.highestOneBit(value) << 1) - 1);
}

https://ideone.com/u7ZlIv

1 użytkowników online, w tym zalogowanych: 0, gości: 1