Praktični vodič za decimalni format

1. Pregled

U ovom ćemo članku istražiti DecimalFormat razreda zajedno sa svojim praktičnim običajima.

Ovo je podrazred Format broja, koji omogućuje oblikovanje decimalnih brojeva ' Niz predstavljanje pomoću unaprijed definiranih obrazaca.

Također se može koristiti obrnuto, za raščlanjivanje žica u brojeve.

2. Kako to djeluje?

Da bismo formatirali broj, moramo definirati uzorak, koji je niz posebnih znakova potencijalno pomiješanih s tekstom.

Postoji 11 znakova s ​​posebnim uzorkom, ali najvažniji su:

  • 0 - ispisuje znamenku ako je navedena, 0 u suprotnom
  • # - ispisuje znamenku ako je navedena, ništa drugo
  • . - naznačite gdje staviti decimalni separator
  • , - naznačite gdje staviti odvajač za grupiranje

Kada se uzorak primijeni na broj, izvršavaju se njegova pravila oblikovanja, a rezultat se ispisuje prema DecimalFormatSymbol naših JVM-a Lokalno osim ako nije određeno Lokalno je navedeno.

Izlazi sljedećih primjera su iz JVM-a koji radi na engleskom jeziku Lokalno.

3. Osnovno oblikovanje

Pogledajmo sada koji se izlazi proizvode prilikom formatiranja istog broja sa sljedećim uzorcima.

3.1. Jednostavne decimale

dvostruki d = 1234567,89; assertThat (novi DecimalFormat ("#. ##"). format (d)). isEqualTo ("1234567.89"); assertThat (novi DecimalFormat ("0,00"). format (d)). isEqualTo ("1234567,89"); 

Kao što vidimo, cjelobrojni dio nikada se ne odbacuje, bez obzira je li uzorak manji od broja.

assertThat (novi DecimalFormat ("#########. ###"). format (d)) .isEqualTo ("1234567.89"); assertThat (novi DecimalFormat ("000000000.000"). format (d)) .isEqualTo ("001234567.890"); 

Ako je uzorak umjesto toga veći od broja, dodaju se nule, dok se hashovi ispuštaju, kako u cijelom broju tako i u decimalnim dijelovima.

3.2. Zaokruživanje

Ako decimalni dio uzorka ne može sadržavati cijelu preciznost ulaznog broja, on se zaokružuje.

Ovdje je dio .89 zaokružen na .90, a zatim je ispušteno 0:

assertThat (novi DecimalFormat ("#. #"). format (d)) .isEqualTo ("1234567.9"); 

Ovdje je .89 dio zaokružen na 1.00, zatim je ispušten .00 i zbrojeno 1 na 7:

assertThat (novi DecimalFormat ("#"). format (d)) .isEqualTo ("1234568"); 

Zadani način zaokruživanja je POL_EVEN, ali se može prilagoditi putem setRoundingMode metoda.

3.3. Grupiranje

Razdjelnik grupiranja koristi se za određivanje pod uzorka koji se automatski ponavlja:

assertThat (novi DecimalFormat ("#, ###. #"). format (d)) .isEqualTo ("1.234.567,9"); assertThat (novi DecimalFormat ("#, ###"). format (d)) .isEqualTo ("1,234,568"); 

3.4. Višestruki obrasci grupiranja

Neke zemlje imaju promjenjiv broj obrazaca grupiranja u svojim sustavima brojanja.

Indijski sustav numeriranja koristi format #, ##, ###. ##, u kojem samo prvi separator za grupiranje sadrži tri broja, dok svi ostali imaju dva broja.

To nije moguće postići pomoću DecimalFormat klase koja zadržava samo najnoviji obrazac s lijeva na desno i primjenjuje ga na cijeli broj, zanemarujući prethodne uzorke grupiranja.

Pokušaj upotrebe uzorka #, ##, ##, ##, ### rezultirao bi pregrupiranjem u #######, ### i završio bi preraspodjelom na #, ###, # ##, ###.

Da bismo postigli višestruko podudaranje uzoraka grupiranja, potrebno je napisati vlastiti Niz manipulacijskog koda ili alternativno isprobati Icu4J-ove DecimalFormat, što to dopušta.

3.5. Miješanje gudačkih literala

Moguće je miješati Niz literali unutar uzorka:

assertThat (novi DecimalFormat ("# broj") .format (d)) .isEqualTo ("Broj 1234568"); 

Također je moguće koristiti posebne znakove kao Niz doslovce, kroz bijeg:

assertThat (novi DecimalFormat ("The '#' # number") .format (d)) .isEqualTo ("The # 1234568 number"); 

4. Lokalizirano formatiranje

Mnoge zemlje ne koriste engleske simbole, a zarez koriste kao decimalni separator, a točku kao separator za grupiranje.

Pokretanje uzorka #, ###. ## na JVM-u s talijanskim jezikom Lokalno, na primjer, dalo bi 1.234.567,89.

Iako bi ovo u nekim slučajevima mogla biti korisna i18n značajka, u drugima bismo možda htjeli provesti određeni format, neovisan o JVM-u.

Evo kako to možemo učiniti:

assertThat (novi DecimalFormat ("#, ###. ##", novi DecimalFormatSymbols (Locale.ENGLISH)). format (d)) .isEqualTo ("1.234.567,89"); assertThat (novi DecimalFormat ("#, ###. ##", novi DecimalFormatSymbols (Locale.ITALIAN)). format (d)) .isEqualTo ("1.234.567,89"); 

Ako je Lokalno nas zanima nije među onima koje pokriva DecimalFormatSymbols konstruktor, možemo ga odrediti pomoću getInstance metoda:

Locale customLocale = novi Locale ("it", "IT"); assertThat (novi DecimalFormat ("#, ###. ##", DecimalFormatSymbols.getInstance (customLocale)). format (d)) .isEqualTo ("1.234.567,89");

5. Znanstvene bilješke

Znanstveni zapis predstavlja proizvod Mantisse i eksponent deset. Broj 1234567,89 može se predstaviti i kao 12,3456789 * 10 ^ 5 (točka je pomaknuta za 5 položaja).

5.1. E-Notacija

Moguće je izraziti broj u Znanstvenom zapisu pomoću E znak uzorka koji predstavlja eksponent deset:

assertThat (novi DecimalFormat ("00. ####### E0"). format (d)) .isEqualTo ("12.3456789E5"); assertThat (novi DecimalFormat ("000.000000E0"). format (d)) .isEqualTo ("123.456789E4"); 

Morali bismo imati na umu da je broj znakova nakon eksponenta relevantan, pa ako moramo izraziti 10 ^ 12, trebamo E00 a ne E0.

5.2. Inženjerska notacija

Uobičajeno je koristiti određeni oblik Znanstvene notacije nazvan Inženjerska notacija, koji prilagođava rezultate kako bi se iskazali kao višestruki od tri, na primjer kada se koriste mjerne jedinice poput Kilo (10 ^ 3), Mega (10 ^ 6), Giga ( 10 ^ 9) i tako dalje.

Ovu vrstu zapisa možemo provesti podešavanjem maksimalnog broja cjelobrojnih znamenki (znakova izraženih s # i s lijeve strane decimalnog separatora) tako da je veći od minimalnog broja (onaj izražen s 0) i veći od 1.

To prisiljava eksponent da bude višekratnik maksimalnog broja, pa za ovaj slučaj upotrebe želimo da maksimalni broj bude tri:

assertThat (novi DecimalFormat ("## 0. ###### E0") .format (d)). isEqualTo ("1.23456789E6"); assertThat (novi DecimalFormat ("###. 000000E0") .format (d)). isEqualTo ("1.23456789E6"); 

6. Raščlanjivanje

Pogledajmo kako je moguće raščlaniti a Niz u a Broj metodom raščlanjivanja:

assertThat (new DecimalFormat ("", new DecimalFormatSymbols (Locale.ENGLISH)) .parse ("1234567.89")) .isEqualTo (1234567.89); assertThat (new DecimalFormat ("", new DecimalFormatSymbols (Locale.ITALIAN)) .parse ("1.234.567,89")) .isEqualTo (1234567.89);

Budući da vraćena vrijednost nije zaključena prisutnošću decimalnog separatora, možemo koristiti metode poput .doubleValue (), .longValue () vraćenih Broj objekt nametnuti određeni primitiv u izlazu.

Također možemo dobiti i BigDecimal kako slijedi:

NumberFormat nf = novi DecimalFormat ("", novi DecimalFormatSymbols (Locale.ENGLISH)); ((DecimalFormat) nf) .setParseBigDecimal (true); assertThat (nf.parse ("1234567.89")) .isEqualTo (BigDecimal.valueOf (1234567.89)); 

7. Sigurnost navoja

DecimalFormat nije zaštićen niti, stoga bismo trebali obratiti posebnu pozornost prilikom dijeljenja iste instance između niti.

8. Zaključak

Vidjeli smo glavne običaje DecimalFormat razreda, zajedno sa svojim prednostima i nedostacima.

Kao i uvijek, puni izvorni kod dostupan je na Githubu.