interpretați un număr negativ ca nesemnat cu BigInteger java

Este posibil să analizăm un număr negativ într-o valoare nesemnată cu BigInteger-ul lui java?

De exemplu, aș interpreta -1 ca FFFFFFFFFFFFFFFF .

Este posibil?

Mulțumiri

0
BigInteger are o lungime nelimitată. Pe care criteriu -1 ar fi interpretat ca FFFFFFFFFFFFFFFF în loc de, să zicem, FFFFFFFF sau FF?
adăugat autor leonbloy, sursa
de ce ai nevoie de BigInteger pentru asta? Long.toHexString (-1) = FFFFFFFFFFFFFFFF
adăugat autor MariuszS, sursa

7 răspunsuri

Ce ai făcut?

public static void main(String[] args) {

    BigInteger bg =  BigInteger.valueOf(-1);        
    System.out.println(Integer.toHexString(bg.intValue()));
}
0
adăugat
dar rezultatul este: ffffffff ;)
adăugat autor MariuszS, sursa

Dacă vă gândiți la completarea celor doi, trebuie să specificați o lungime a bitului de lucru. O lungă Java are 64 de biți, dar un BigInteger nu este limitat.

Ai putea face ceva ca acesta:

// Two's complement reference: 2^n . 
// In this case, 2^64 (so as to emulate a unsigned long)
private static final BigInteger TWO_COMPL_REF = BigInteger.ONE.shiftLeft(64);

public static BigInteger parseBigIntegerPositive(String num) {
    BigInteger b = new BigInteger(num);
    if (b.compareTo(BigInteger.ZERO) < 0)
        b = b.add(TWO_COMPL_REF);
    return b;
}

public static void main(String[] args) {
    System.out.println(parseBigIntegerPositive("-1").toString(16));
}

Dar acest lucru ar însemna implicit că lucrați cu BigIntegers în gama 0 - 2 ^ 64-1.

Sau, mai general:

public static BigInteger parseBigIntegerPositive(String num,int bitlen) {
    BigInteger b = new BigInteger(num);
    if (b.compareTo(BigInteger.ZERO) < 0)
        b = b.add(BigInteger.ONE.shiftLeft(bitlen));
    return b;
}

Pentru a face mai mult foofer, puteți adăuga câteva verificări, de ex

public static BigInteger parseBigIntegerPositive(String num, int bitlen) {
    if (bitlen < 1)
        throw new RuntimeException("Bad bit length:" + bitlen);
    BigInteger bref = BigInteger.ONE.shiftLeft(bitlen);
    BigInteger b = new BigInteger(num);
    if (b.compareTo(BigInteger.ZERO) < 0)
        b = b.add(bref);
    if (b.compareTo(bref) >= 0 || b.compareTo(BigInteger.ZERO) < 0 )
        throw new RuntimeException("Out of range: " + num);
    return b;
}
0
adăugat
Acest lucru pare a fi problematic în cazul meu. Încerc să citesc un cod nesignificat de 0xCCCCCCCC . BigInteger pare a fi bine, dar când invoc # toByteArray , primesc cinci octeți: CC CC CC CC 00 . Ai idee de ce?
adăugat autor Michael-O, sursa

Soluția simples este de la @Ahmet Karakaya, dar ar trebui fixată pentru numere mai mari:

BigInteger bg =  BigInteger.valueOf(-1);
System.out.println(Long.toHexString(bg.intValue()));

Result: ffffffffffffffff

sau pur și simplu:

System.out.println(Long.toHexString(-1))
0
adăugat

Un Liner (cu toate acestea, nu uitați să luați în considerare problemele legate de finalitate cu sursa, care pot fi gestionate folosind ByteBuffer.byteOrder):

new BigInteger(1, ByteBuffer.allocate(Long.SIZE/Byte.SIZE).putLong(Long.parseLong("-1")).array());
0
adăugat

Încercați să utilizați constructorul

public BigInteger(int signum, byte[] magnitude)

Primul parametru trebuie setat la 1 pentru a specifica că doriți să creați un număr pozitiv. Matricea de octeți este numărul pe care îl parcurgeți în ORDINEA BIG ENDIANĂ. Ar trebui interpretat ca un număr nesemnificat dacă setați primul parametru la 1. Singurul truc este să vă obțineți numărul într-o matrice octet, dar asta nu ar trebui să fie prea dificil.

EDIT: Se pare că trebuie să faci niște aritmetică manuală de biți aici. Dacă înțeleg corect problema dvs., trebuie să interpretați un șir ca lung și apoi să interpretați atât de mult nesemnatul și să îl stocați în clasa BigInteger. Aș face asta.

public BigInteger getValue(String numberString)
{
   Long longValue = Long.valueOf(numberString);
   byte [] numberAsArray = new byte[8];  
   for(int i = 0; i < 8; i++)
   {  
      numberAsArray[7 - i] = (byte)((longValue >>> (i * 8)) & 0xFF);
   }
   return new BigInteger(1, numberAsArray);
}  
0
adăugat
De fapt, obținerea numărului într-o matrice de octeți este punctul întreg. Mi sa dat un șir numeric și am cerut să îl interpretez ca pe un nesemnat.
adăugat autor One Two Three, sursa
Vei crea propriul meu răspuns ... dar toByteArray() este probabil ceea ce căutați.
adăugat autor NominSim, sursa
Bine, lasă-mă să mă gândesc la asta pentru o secundă. Vi se oferă un obiect String și doriți să îl convertiți la un BigInteger nesemnat? În acest caz, știți dacă obiectul dvs. String reprezintă un int sau un lung?
adăugat autor Akron, sursa

Puteți face întotdeauna manual completarea celor doi. Dacă numărul este mai mic decât 0, inversați toți biți și adăugați unul.

0
adăugat

Puteți utiliza acest utilitar pentru a converti la un întreg nesemnat. Deoarece BigIntegers au dimensiuni nelimitate, trebuie specificată o dimensiune pentru a determina cât de multă extensie a semnului trebuie păstrată în traducere:

public static BigInteger toPositive(BigInteger num, int sizeInBytes) {
    return num.andNot(BigInteger.valueOf(-1).shiftLeft(sizeInBytes * 8));
}
0
adăugat