1. Pag-ikot ng mga tunay na numero

Tulad ng napag-usapan na natin, kapag ang isang tunay na numero ay itinalaga sa isang intvariable, ito ay palaging nira-round down sa pinakamalapit na mas maliit na integer — ang fractional na bahagi ay itatapon lang.

Ngunit madaling isipin ang isang sitwasyon kapag ang isang fractional na numero ay kailangang bilugan sa pinakamalapit na integer sa alinmang direksyon o kahit na i-round up. Ano ang gagawin mo sa kasong ito?

Para dito at para sa maraming katulad na sitwasyon, ang Java ay may Mathklase, na mayroong round(), ceil(), at floor()mga pamamaraan.


Math.round()paraan

Ang Math.round()pamamaraan ay nagpapaikot ng isang numero sa pinakamalapit na integer:

long x = Math.round(real_number)

Ngunit mayroong isa pang nuance dito: ang pamamaraang ito ay nagbabalik ng isang longinteger (hindi isang int). Dahil maaaring napakalaki ng mga totoong numero, nagpasya ang mga tagalikha ng Java na gamitin ang pinakamalaking available na uri ng integer ng Java: long.

Alinsunod dito, kung nais ng isang programmer na italaga ang resulta sa isang intvariable, dapat niyang malinaw na ipahiwatig sa compiler na tinatanggap niya ang posibleng pagkawala ng data (sa kaganapan na ang resultang numero ay hindi magkasya sa isang inturi).

int x = (int) Math.round(real_number)

Mga halimbawa:

Pahayag Resulta
int x = (int) Math.round(4.1);
4
int x = (int) Math.round(4.5);
5
int x = (int) Math.round(4.9);
5

Math.ceil()paraan

Ang Math.ceil()pamamaraan ay nag-round ng isang numero hanggang sa isang integer. Narito ang mga halimbawa:

Pahayag Resulta
int x = (int) Math.ceil(4.1);
5
int x = (int) Math.ceil(4.5);
5
int x = (int) Math.ceil(4.9);
5

Math.floor()paraan

Ang Math.floor()pamamaraan ay nag-round ng isang numero pababa sa isang integer. Narito ang mga halimbawa:

Pahayag Resulta
int x = (int) Math.floor(4.1);
4
int x = (int) Math.floor(4.5);
4
int x = (int) Math.floor(4.9);
4

Siyempre, kapag ni-round up ang isang numero sa isang integer, mas madaling gumamit ng isang uri ng operator ng cast:(int)

Pahayag Resulta
int x = (int) 4.9
4

Kung nahihirapan kang tandaan ang mga pangalang ito, makakatulong ang isang maikling aralin sa Ingles:

  • Mathibig sabihin ay matematika
  • Roundibig sabihin bilog
  • Ceilingnangangahulugang kisame
  • Flooribig sabihin ay sahig

2. Paano nakabalangkas ang mga floating-point na numero

Ang doubleuri ay maaaring mag-imbak ng mga halaga sa hanay mula hanggang . Ang malaking hanay ng mga halaga (kumpara sa uri) ay ipinaliwanag sa pamamagitan ng katotohanan na ang uri (pati na rin ) ay may ganap na naiibang panloob na istraktura kaysa sa mga uri ng integer. Sa panloob, ine-encode ng uri ang halaga nito bilang dalawang numero: ang una ay tinatawag na mantissa , at ang pangalawa ay tinatawag na exponent .-1.7*10308+1.7*10308intdoublefloatdouble

Sabihin nating mayroon tayong numero 123456789at iimbak ito ng isang doublevariable. Kapag ginawa namin, ang numero ay mako-convert sa , at sa loob ang uri ay nag-iimbak ng dalawang numero — at . Ang significand ("makabuluhang bahagi ng numero" o mantissa) ay naka-highlight sa pula, habang ang exponent ay naka-highlight sa asul.1.23456789*108double234567898

Ginagawang posible ng diskarteng ito na mag-imbak ng parehong napakalaking numero at napakaliit. Ngunit dahil ang representasyon ng numero ay limitado sa 8 byte (64 bits) at ang ilan sa mga bit ay ginagamit upang iimbak ang exponent (pati na rin ang sign ng mantissa at ang sign ng exponent), ang maximum na mga digit na magagamit upang kumatawan sa mantissa ay 15 .

Ito ay isang napakasimpleng paglalarawan kung paano nakaayos ang mga tunay na numero.


3. Pagkawala ng katumpakan kapag nagtatrabaho sa mga tunay na numero

Kapag nagtatrabaho sa mga tunay na numero, laging tandaan na ang mga tunay na numero ay hindi eksakto . Maaaring palaging may mga rounding error at conversion error kapag nagko-convert mula sa decimal patungo sa binary. Bukod pa rito, ang pinakakaraniwang pinagmumulan ng error ay ang pagkawala ng katumpakan kapag nagdaragdag/nagbabawas ng mga numero sa iba't ibang sukat.

Ang huling katotohanang ito ay medyo nakakagulat para sa mga baguhang programmer.

Kung ibawas natin sa , makukuha natin .1/109109109

Pagbabawas ng mga numero sa iba't ibang mga sukat Paliwanag
 1000000000.000000000;
-         0.000000001;
 1000000000.000000000;
Ang pangalawang numero ay napakaliit , na magiging sanhi ng kabuluhan nito (naka-highlight sa kulay abo) ay hindi papansinin. Ang 15 makabuluhang digit ay naka-highlight sa orange.

Ano ang masasabi natin, ang programming ay hindi katulad ng matematika.


4. Pitfall kapag inihambing ang mga tunay na numero

Ang isa pang panganib ay naghihintay para sa mga programmer kapag inihambing nila ang mga tunay na numero. Lumilitaw ito kapag nagtatrabaho sa mga tunay na numero, dahil ang mga round-off na error ay maaaring maipon. Ang resulta ay mayroong mga sitwasyon kung saan ang mga tunay na numero ay inaasahang magiging pantay, ngunit hindi. O vice versa: ang mga numero ay inaasahang magkakaiba, ngunit sila ay pantay.

Halimbawa:

Pahayag Paliwanag
double a = 1000000000.0;
double b = 0.000000001;
double c = a - b;
Ang halaga ng variable a ay magiging 1000000000.0
Ang halaga ng variable c ay magiging 1000000000.0
(ang bilang sa b variable ay masyadong maliit)

Sa halimbawa sa itaas, aat chindi dapat maging pantay, ngunit sila ay.

O kumuha tayo ng isa pang halimbawa:

Pahayag Paliwanag
double a = 1.00000000000000001;
double b = 1.00000000000000002;
Ang halaga ng variable a ay magiging 1.0
Ang halaga ng variable b ay magiging1.0

5. Isang kawili-wiling katotohanan tungkol sastrictfp

Ang Java ay may espesyal strictfpna keyword ( strict f loating p oint ), na hindi matatagpuan sa ibang mga programming language. At alam mo ba kung bakit kailangan mo ito? Pinalala nito ang katumpakan ng mga operasyon na may mga floating-point na numero. Narito ang kuwento kung paano ito naging:

Mga tagalikha ng Java:
Gusto talaga naming maging sobrang sikat ang Java at magpatakbo ng mga Java program sa pinakamaraming device hangga't maaari. Kaya't tiniyak namin na ang detalye para sa Java machine ay nagsasabi na ang lahat ng mga programa ay dapat tumakbo sa parehong paraan sa lahat ng mga uri ng mga aparato!
Mga gumagawa ng mga processor ng Intel:
Hoy, lahat! Pinahusay namin ang aming mga processor, at ngayon ang lahat ng totoong numero ay kinakatawan gamit ang 10-bytes sa halip na 8-bytes sa loob ng aming mga processor. Ang mas maraming byte ay nangangahulugan ng mas makabuluhang mga digit. Anong ibig sabihin niyan? Tama iyan! Ngayon ang iyong mga siyentipikong kalkulasyon ay magiging mas tumpak!
Mga siyentipiko at lahat ng kasangkot sa ultra-tumpak na mga kalkulasyon:
Malamig! Magaling. Napakahusay na balita!
Mga tagalikha ng Java:
Hindi-hindi-hindi, kayo! Sinabi na namin sa iyo na ang lahat ng mga Java program ay dapat tumakbo nang pareho sa lahat ng mga device . Sapilitan naming idi-disable ang kakayahang gumamit ng 10-byte na totoong numero sa loob ng mga processor ng Intel.
Ngayon maayos na ulit ang lahat! Huwag mo kaming pasalamatan.
Mga siyentipiko at lahat ng kasangkot sa ultra-tumpak na mga kalkulasyon:
Nabaliw ka na ba? Mabilis na ibalik ang lahat sa dati!
Mga tagalikha ng Java:
Guys, ito ay para sa iyong kapakanan! Isipin lang: lahat ng Java program ay tumatakbo sa parehong paraan sa lahat ng device . Astig yan!
Mga siyentipiko at lahat ng kasangkot sa ultra-tumpak na mga kalkulasyon:
Hindi. Ito ay hindi cool sa lahat. Mabilis na ibalik ang lahat sa kung ano ito! O alam mo ba kung saan namin ilalagay ang iyong Java?
Mga tagalikha ng Java:
Hmm. Bakit hindi mo sinabi agad? Syempre, ibabalik natin.
Ibinalik namin ang iyong kakayahang gamitin ang lahat ng feature ng pinakabagong mga processor.
Siyanga pala... Espesyal din naming idinagdag ang strictfpkeyword sa wika. Kung isusulat mo ito bago ang pangalan ng isang function, ang lahat ng mga operasyong kinasasangkutan ng mga tunay na numero sa loob ng function na iyon ay magiging pantay na masama sa lahat ng device !