Soru İmzalı bir tam sayıyı imzasız bir uzunluğa dönüştürmenin en iyi yolu?


Java'daki belirli hash işlevleri için değeri işaretsiz bir tam sayı olarak görmek güzel olurdu (örn. Diğer uygulamalarla karşılaştırmak için) ancak Java yalnızca imzalı türleri desteklemektedir. İmzalı bir dönüştürebiliriz int bir "imzasız" long gibi:

public static final int BITS_PER_BYTE = 8;
public static long getUnsignedInt(int x) {
  ByteBuffer buf = ByteBuffer.allocate(Long.SIZE / BITS_PER_BYTE);
  buf.putInt(Integer.SIZE / BITS_PER_BYTE, x);
  return buf.getLong(0);
}
getUnsignedInt(-1); // => 4294967295

Ancak, bu çözüm gerçekten yaptığımız şey için çok fazla gibi görünüyor. Aynı şeyi elde etmenin daha verimli bir yolu var mı?


44
2018-03-06 05:57


Menşei




Cevaplar:


Böyle bir şey mi?

int x = -1;
long y = x & 0x00000000ffffffffL;

Yoksa bir şey mi özlüyorum?

public static long getUnsignedInt(int x) {
    return x & 0x00000000ffffffffL;
}

81
2018-03-06 06:00



+1 sağa. Hayır, bir şey eksik olan bendim - kendimi genişleyen dönüşümlerle karıştırdım ve basit yaklaşımı gözden kaçırdım =) - maerics
Meh, olur. Özellikle C ++ 'da her şeyi yapmanın bazilyon yolları var. - Mysticial
misiniz x & 0xFFFFFFFFL Çalışmak mı? - Sebastian Hoffmann
@Paranaix Ben de işe yarayacak inanıyorum. Bu cevabı yazdığımdan beri bir süre geçti, bu yüzden çoğu kez C ++ ve tamsayı geliştirme kurallarının imzalanmış / imzasız türlerle daha karmaşık hale geldiğinden, sıfırlarla doldurulmamın nedeninin alışkanlıktan yoksun olduğunu düşünüyorum. - Mysticial
Teşekkürler, Murmur Hashes kullanarak bu konuya koştu. - Richard Clayton


Java 8'deki standart yol Integer.toUnsignedLong(someInt), eşdeğerdir @ Mysticial'ın cevabı.


25
2018-06-30 12:37





Guava sağlar UnsignedInts.toLong(int)... imzasız tam sayılarda çeşitli diğer yardımcı programların yanı sıra.


16
2018-03-06 06:37





Gibi bir işlevi kullanabilirsiniz

public static long getUnsignedInt(int x) {
    return x & (-1L >>> 32);
}

Ancak çoğu durumda bunu yapmanız gerekmez. Bunun yerine geçici çözümleri kullanabilirsiniz. Örneğin.

public static boolean unsignedEquals(int a, int b) {
    return a == b;
}

İmzasız değerleri kullanmak için daha fazla geçici çözüm örneği. İmzasız hizmet sınıfı


7
2018-03-06 08:27



GetUnsignedInt işleviniz çalışmıyor. Programımda test etmediğim için ciddi bir hata yaptım. : (( - user2707175
@ user2707175 değiştir >>> için >> ve işe yaramalı - Jeff Jones
getUnsignedInt, olduğu gibi çalışır. >>> doğru. >> işaret uzantısı neden olur, ve herhangi bir miktarda işaret uzantısı ile sağa kaydırılmış -1L her zaman hepsi ile bir değer elde edilir. - Macil


diğer çözüm.

public static long getUnsignedInt(int x) {
    if(x > 0) return x;
    long res = (long)(Math.pow(2, 32)) + x;
    return res;
}

2
2018-03-06 06:19



Math.pow her zaman çok pahalıdır ve hesaplanır. Kıyasla 1l << 32 hızlı ve sadece derleyici tarafından hesaplanır. (Ve uzun bir süre için döküm gerekmez. - Peter Lawrey
Bu dönüşüm çalışmasının nasıl olduğunu anlayamıyorum. - ManMohan Vyas
İnt 32 bit olduğundan ve temsil etmek için iki tamamlayıcısını kullanın. Wikipedia'daki iki tamamlayıcısını kontrol edebilirsiniz (en.wikipedia.org/wiki/Two's_complement) daha fazla detay almak - lmatt


Sadece 2 sentim burada, ama bence kullanmak iyi bir uygulama:

public static long getUnsignedInt(int x) { return x & (~0L); // ~ has precedence over & so no real need for brackets }

yerine:

x & 0xFFFFFFFFL;

Bu durumda, maskenin kaç tane F olduğunu endişeniz yoktur. Her zaman çalışır!


-2
2018-03-05 11:27



Bu tamamen yanlış. Int uzun bir süreye yükseltilir, ve sonra bunu hiçbir şey yapmayan 64'lü bir dizi ile maskeliyorsunuz. Aşağıdaki baskılar 4294967295 yerine -1: int i = -1; uzun j = i & (~ 0L); System.out.println (j) - PBJ
evet benim kötüyüm, 0xFFFFFFFFL ~ 0L ile karıştı. - okoopat


long abs(int num){
    return num < 0 ? num * -1 : num;
}

-4
2017-11-19 09:31



lütfen iki tamamlayıcıyı okuyun (en.wikipedia.org/wiki/Two%27s_complement) İmzalı numaraların genellikle nasıl temsil edildiğini açıklar. Bu sorunu çözmek için mutlak değer elde edemezsiniz (tadej.me/twos-complement-and-absolute-values). - Stepan Pogosyan