Próbowałem znaleźć bardzo dziwne zachowanie w Javie. Mam formułę, która wymaga podwójnego, ale jest "gwarantowana", aby dać całkowitą odpowiedź - konkretnie, niepodpisaną 32-bitową liczbę całkowitą (która, niestety, Java nie działa dobrze). Niestety, moje odpowiedzi były czasami niepoprawne.Czy prymitywne rzuty Java typu "liczba całkowita" są "ograniczone" w MAX_INT odlewania?
końcu znalazłem problem, ale zachowanie jest nadal bardzo dziwne dla mnie: a double
odlewane bezpośrednio do int
wydaje się być ograniczona w MAX_INT
za podpisanym całkowitej, natomiast double
obsady do long
że to jest następnie rzutowany na int
daje mi oczekiwaną odpowiedź (-1; MAX INT z unsigned 32-bitowej liczby całkowitej reprezentowanej jako 32-bitowa liczba całkowita ze znakiem).
napisałem mały program testowy:
public static void main(String[] args) {
// This is the Max Int for a 32-bit unsigned integer
double maxUIntAsDouble = 4294967295.00;
long maxUintFromDoubleAsLong = (long)maxUIntAsDouble;
long maxUintFromDoubleAsInt = (int)maxUIntAsDouble;
int formulaTest = (int) (maxUintFromDoubleAsLong * 1.0);
int testFormulaeWithDoubleCast = (int)((long) (maxUintFromDoubleAsLong * 1.0));
// This is a more-or-less random "big number"
long longUnderTest = 4123456789L;
// Max int for a 32-bit unsigned integer
long longUnderTest2 = 4294967295L;
int intFromLong = (int) longUnderTest;
int intFromLong2 = (int) longUnderTest2;
System.out.println("Long is: " + longUnderTest);
System.out.println("Translated to Int is:" + intFromLong);
System.out.println("Long 2 is: " + longUnderTest2);
System.out.println("Translated to Int is:" + intFromLong2);
System.out.println("Max UInt as Double: " + maxUIntAsDouble);
System.out.println("Max UInt from Double to Long: " + maxUintFromDoubleAsLong);
System.out.println("Max UInt from Double to Int: " + maxUintFromDoubleAsInt);
System.out.println("Formula test: " + formulaTest);
System.out.println("Formula Test with Double Cast: " + testFormulaeWithDoubleCast);
}
Gdy ten mały program uzyskać:
Long is: 4123456789
Translated to Int is:-171510507
Long 2 is: 4294967295
Translated to Int is:-1
Max UInt as Double: 4.294967295E9
Max UInt from Double to Long: 4294967295
Max UInt from Double to Int: 2147483647
// MAX INT for an unsigned int
Formula test: 2147483647
// Binary: all 1s, which is what I expected
Formula Test with Double Cast: -1
Dolne dwie linie są te Próbuję zrozumieć. Podwójna obsada daje mi oczekiwaną wartość "-1"; ale prosta obsada daje mi MAX_INT dla 32-bitowej liczby całkowitej ze znakiem. Pochodzę z tła w C++, zrozumiałbym, gdyby dał mi "nieparzystą liczbę" zamiast oczekiwanego -1 (znanego też jako "naiwne rzucanie"), ale to mnie wprawiło w zakłopotanie.
Tak, na pytanie to: czy to „oczekuje” zachowania w Javie (np dowolny double
odlewane bezpośrednio do int
będzie „ograniczona” do MAX_INT
)? Czy rzutowanie to robi dla nieoczekiwanych typów? Spodziewam się, że będzie podobny na przykład do short
i byte
; ale jakie jest "oczekiwane zachowanie" podczas rzucania oversized-double do float?
Dzięki!
Wiedziałem o braku "unsigned" w java (jedna z rzeczy, która sprawia, że Java sprawia ból podczas pracy z bitowymi protokołami), ale większość z nich jest zupełnie nowa. Na pewno nie spodziewałbym się tego zachowania z "krótkiego" i "bajtowego". Dzięki. :RE –