Vra

Waarom doen hierdie Java -kode

long a4 = 1L;
long a3 = 1;
long a2 = 100L * 1024 * 1024 * 1024;
long a1 = 100 * 1024 * 1024 * 1024;
System.out.println(a4);
System.out.println(a3);
System.out.println(a2);
System.out.println(a1);

As u loop, uitvoer

1
1
107374182400
0

in plaas van die verwagte

1
1
107374182400
107374182400

produksie?

Was dit nuttig?

Oplossing 2

107374182400 is presies 25 keer die volledige reeks van 'n heelgetal (2^32), wat beteken dat as u dit in 'n heelgetal probeer inpas, sal dit oorloop. En omdat dit presies 25 keer sou pas, eindig dit presies op 0 (dit is 'n toeval en ander groot vermenigvuldigings kan positief of negatief wees). En jy gebruik 'n heelgetal tot op die punt wat jy tot lank gewerp het

long a1 = 100 * 1024 * 1024 * 1024;

is gelykstaande aan

int temp = 100 * 1024 * 1024 * 1024;
long a1 = (long)temp;

As u 'n enkele lang in die uitdrukking plaas, word dit gedwing om lang wiskunde te gebruik en nie heelgetal wiskunde nie, wat die probleem verwyder

Ander wenke

 long a2 = 100L * 1024 * 1024 * 1024;

In hierdie operasie is egter ten minste een operand long. Die bewerking word dus met 64-bis-presisie uitgevoer, en die resultaat van die numeriese operateur is van tipe long. Die ander nie-lange operand word uitgebrei om te tik long per Numeriese promosie en die resultaatwaarde word na veranderlike gestoor a2.

 long a1 = 100 * 1024 * 1024 * 1024;

Die konstante uitdrukking van gewone heelgetal, die resultaat van die uitdrukking is as 'n tipe bereken int. Die berekende waarde het egter te groot om in 'n heelgetal te pas en dus oorvol te wees, wat tot gevolg het 0 en word gestoor aan a1 veranderlike.

Wysig: Soos gevra word in die volgende opmerking:

Waarom gaan dit nie negatief nie?

Want terwyl hy in heelgetal berekening Die tweede berekening is gelykstaande aan 25 * 2^32 waar ^ het die krag betekenis en 2^32 heelgetalwaarde is 0. Om egter te verduidelik waarom dit waarde is 0: In binêre:

 100 * 1024 * 1024 * 1024 == 25 * 2^32;

 Integer.MAX_VALUE =  2 ^ 31 -1 = 0 11111111 11111111 11111111 1111111
 Integer.MAX_VALUE + 1 = 2 ^ 31 = 1 00000000 00000000 00000000 0000000 

2 ^ 31 is 'n negatiewe heelgetal (-2147483648) soos die tekenstuk is 1 En vandaar 2 ^ 32 is net 'n vermenigvuldiging van 2 na 2 ^ 31: 'n linkerskof en die bordjie sal word 0 En daarom is die resultaat 0.

Kyk na die java language specification: 4.2.2: Integer operation vir besonderhede.

Dit kan wees dat die uitdrukking aan die regterkant van a1 word eers bereken as 'n int en later omgeskakel na long. As dit gelyk is 0 as 'n int Dit sal bly 0 as a long

Soos per die Dokumentasie van leksikale letterkundiges Daar word genoem dat,

Die tipe letterlike word soos volg bepaal:
- Die tipe heelgetal letterlike (§3.10.1) wat met L of L eindig, is lank (§4.2.1).
- Die tipe van enige ander heelgetal letterlik is int (§4.2.1).

So jou uitdrukking, 100 * 1024 * 1024 * 1024 word geëvalueer as int primitiewe datatipe omdat l of L word nie in enige numeriese waarde genoem nie. En die resultaat is 107374182400 dws in binêre 1 1001 0000 0000 0000 0000 0000 0000 0000 0000 en int is 32-bis so laag 32-bis word geneem soos genoem in Voorbeeld 4.2.2-1. Heelgetal bedrywighede wat lei tot 0

Dit word ook in dieselfde dokumentasie genoem, wat

As 'n heelgetaloperateur anders as 'n skofoperateur ten minste een operand van die tipe lank het, word die bewerking met 64-bis-presisie uitgevoer, en die resultaat van die numeriese operateur is van die tipe lank. As die ander operand nie lank is nie, word dit eers uitgebrei (§5.1.5) om lank te tik deur numeriese promosie

Dit beteken enige waarde in uitdrukking bevat l of L Dan al die int Waardes sal uitgebrei word tot 64 bis.

Redigeer In die opmerking Dit word ook gevra

Waarom gaan dit nie negatief nie?

Ek dink dit ook beantwoord bogenoemde vraag

long a4 = 1L; // geen probleem hierin nie

long a3 = 1; // hier aan die linkerkant word primitief as heelgetal beskou en ten tyde van die opdrag sal dit tot lank gegiet word, so weer is die resultaat soos verwag

long a2 = 100L * 1024 * 1024 * 1024; (Hier het u 100L gebruik, sodat ander tot lank gegiet sal word, so verwagte uitset)

long a1 = 100 * 1024 * 1024 * 1024; (Aangesien enige primitiewe syfer in Java as Int in Java beskou word, sal dit dit as heelgetalvermenigvuldiging beskou, sodat dit buite die bereik is en in 0 lei)

Hier is wat u gedoen het: u het opgedra 100 * 1024 * 1024 * 1024na 'n lang datatipe, maar jy het dit nie gesê nie 100 * 1024 * 1024 * 1024 is 'n lang waarde

Java -samesteller dink standaard dat dit 'n heelgetal is. Aangesien heelgetal nie soveel waarde kan hê nie, sal dit verkeerde resultaat toon. Hoop dit help!

rede is heelgetal oorloop
as uitset van 100 * 1024 * 1024 * 1024; is 'n heelgetal (int) nie long

en in long a2 = 100L * 1024 * 1024 * 1024; u spesifiseer dat een van die waarde is long (hier 100L) en vermenigvuldiging met daardie waarde lei tot long waarde wat korrek gestoor word in a2

In Java, as u int * int het, sal dit die uitset as 'n int bereken. Dit gee die resultaat net as 'n lang as u dit lank doen. In u geval het die 100 * 1024 * 1024 * 1024 die resultaat dat dit oorvloei.

Dus, die byvoeging van 'n "L" maak die operand lank, en die berekening stoor die waardes lank. En natuurlik kom daar geen oorloop voor nie en 'n korrekte resultaat kan uitgevoer word (dit wil sê A2).

Nommer 3 het gewerk omdat u 'n lang tipe wat 100L is, gespesifiseer het. Daarom is dit 'n lang vermenigvuldiging en kan dit geberg word. Aan die ander kant is nommer 4 'n heelgetalvermenigvuldiging met maksimum waarde 2^32-1, daarom het u 'n oorloop gekry en die gewaardeerde nul-standaard verskyn.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top