JavaRush /Блоги Java /Random-TG /BigDecimal дар Java

BigDecimal дар Java

Дар гурӯҳ нашр шудааст
Салом! Дар лекцияи имруза мо дар бораи ракамхои калон сухан меронем. Не, дар бораи ХАКИКАТ КАЛОН. Пештар , мо ҷадвали диапазони арзишҳоро барои намудҳои ибтидоии додаҳо на як маротиба дидаем. Чунин ба назар мерасад:
Навъи ибтидоӣ Андоза дар хотира Диапазони арзишҳо
byte 8 бит -128 ба 127
кӯтоҳ 16 бит ба -32768 то 32767
char 16 бит аз 0 то 65536
int 32 бит аз -2147483648 то 2147483647
дароз 64 бит аз -9223372036854775808 то 9223372036854775807
шино кардан 32 бит аз (2 ба қудрат -149) то ((2-2 ба қудрат -23)*2 ба қудрат 127)
дучанд 64 бит аз (-2 ба дараҷаи 63) ба ((2 ба дараҷаи 63) - 1)
булӣ 8 (вақте ки дар массивҳо истифода мешаванд), 32 (вақте ки дар массивҳо истифода намешаванд) рост ё дурӯғ
Агар мо дар бораи ададҳои бутун сухан ронем, навъи пуриқтидори маълумот long , ва вақте ки мо дар бораи рақамҳои нуқтаи шинокунанда сухан меронем, дучандон аст . Аммо чӣ мешавад, агар рақаме, ки ба мо лозим аст, он қадар калон аст, ки ҳатто ба дарозии он мувофиқат намекунад ? Доираи арзишҳои имконпазири Long хеле калон аст, аммо ба ҳар ҳол бо андозаи муайян маҳдуд аст - 64 бит. Агар шумораи хеле калони мо 100 бит вазн дошта бошад, мо чӣ кор карда метавонем? Хушбахтона, ба шумо лозим нест, ки чизе ихтироъ кунед. Дар Java барои чунин ҳолатҳо ду синфи махсус сохта шудаанд - BigInteger (барои ададҳои бутун) ва BigDecimal (барои рақамҳои шинокунандаи нуқта). Хусусияти онҳо чист? Пеш аз ҳама, онҳо аз ҷиҳати назариявӣ андозаи ҳадди аксар надоранд. Аз ҷиҳати назариявӣ, зеро компютерҳои дорои хотираи беохир вуҷуд надоранд. Ва агар шумо дар барнома ададеро созед, ки аз андозаи хотираи компютер калонтар бошад, албатта, барнома кор намекунад. Аммо чунин ҳолатҳо аз эҳтимол дур нест. Аз ин рӯ, мо метавонем бигӯем, ки андозаи рақамҳо амалан номаҳдуд BigIntegerаст . BigDecimalИн синфҳо барои чӣ истифода мешаванд? Пеш аз ҳама, барои ҳисобҳо бо талаботи хеле баланд дақиқ. Масалан, программахое хастанд, ки хаёти инсон дар онхо аз дурустии хисобхо вобаста аст (программа барои самолёту ракетахо ё асбобхои тиббй). Аз ин рӯ, агар ҳатто нуқтаи даҳии 150 нақши муҳим дошта бошад, BigDecimalин беҳтарин интихоб аст. Илова бар ин, аксар вақт ин an objectҳо дар ҷаҳони молия истифода мешаванд, ки дар он дурустии ҳисобҳо то арзишҳои хурдтарин низ хеле муҳим аст. Бо an objectҳо чӣ гуна кор кардан лозим аст BigIntegerва BigDecimalдар бораи онҳо чиро дар хотир бояд дошт? Объектҳои ин синфҳо чунин сохта мешаванд:
public class Main {

   public static void main(String[] args) {

       BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
       System.out.println(integer);

       BigDecimal decimal = new BigDecimal("123.444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444");
       System.out.println(decimal);
   }
}
Гузаронидани сатр ҳамчун параметр танҳо яке аз конструкторҳои имконпазир аст. Дар ин ҷо мо сатрҳоро истифода мебарем, зеро рақамҳои мо аз қиматҳои максималӣ зиёданд longва double, ва гӯё мо бояд ба компилятор маҳз кадом рақамро гирифтан мехоҳем фаҳмонем :) Танҳо рақами 11111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111 ба созанда 11111111111111111111111111111111111111111111111 1111 кор намекунад: Java кӯшиш хоҳад кард Рақами интиқолшударо ба яке аз намудҳои ибтидоии додаҳо "мувофиқ" кунед, аммо он ба ҳеҷ кадоми онҳо мувофиқат намекунад. Аз ин рӯ, истифодаи сатр барои интиқоли рақами дилхоҳ як варианти хуб аст. Ҳарду синфҳо метавонанд ба таври худкор аз сатрҳои гузашта арзишҳои ададӣ гиранд. Нуктаи дигари муҳиме, ки ҳангоми кор бо синфҳои шумораи зиёд дар хотир бояд дошт, ин аст, ки an objectҳои онҳо тағирнопазиранд ( Immutable) . Шумо аллакай бо принсипи тағирнопазирӣ тавассути мисоли синфҳо Stringва синфҳои печонидашуда барои ибтидоӣ (Integer, Long ва дигарон) хуб шиносед.
import java.math.BigInteger;

public class Main {

   public static void main(String[] args) {

       BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
       System.out.println(integer);

       integer.add(BigInteger.valueOf(33333333));
       System.out.println(integer);

   }
}
Натиҷаи консол:

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Шумораи мо, чунон ки шумо интизор будед, тағир наёфтааст. Барои бомуваффақият анҷом додани амалиёти илова, шумо бояд an objectи нав эҷод кунед ва натиҷаи иловаро ба он таъин кунед.
import java.math.BigInteger;

public class Main {

   public static void main(String[] args) {

       BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
       System.out.println(integer);

       BigInteger result = integer.add(BigInteger.valueOf(33333333));
       System.out.println(result);

   }
}
Натиҷаи консол:

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Ҳоло ҳама чиз тавре ки лозим аст, кор мекунад :) Воқеан, оё шумо пай бурдед, ки амалиёти иловакунӣ чӣ гуна ғайриоддӣ менамояд?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Ин як нуктаи муҳими дигар аст. Синфҳои шумораи зиёд дар амалиёти худ операторҳои +-*/-ро истифода намебаранд, балки ба ҷои он маҷмӯи усулҳоро пешниҳод мекунанд. Биёед ба усулҳои асосӣ назар андозем (шумо метавонед, чун ҳамеша, рӯйхати пурраи усулҳоро дар ҳуҷҷатҳои Oracle пайдо кунед: ин ҷо ва ин ҷо ).
  1. усулҳои иҷрои амалҳои арифметикӣ: add() , subtract(), multiply(), divide(). Барои амалҳои ҷамъ, тарҳ, зарб ва тақсим мутаносибан истифода мешавад.

  2. doubleValue(), intValue(), floatValue()ва longValue()гайра. - Барои табдил додани адади калон ба навъи ибтидоии Java истифода мешавад. Ҳангоми истифодаи онҳо эҳтиёт шавед ва фарқияти иқтидорро дар хотир доред!

    import java.math.BigInteger;
    
    public class Main {
    
       public static void main(String[] args) {
    
           BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
    
           long result = integer.longValue();
           System.out.println(result);
    
       }
    }

    Натиҷаи консол:

    
    8198552921648689607
  3. min()ва max()- ба шумо имкон медиҳад, ки арзиши ҳадди ақал ва максималии ду адади калони гузаштаро пайдо кунед.
    Лутфан таваҷҷӯҳ намоед: усулҳо статикӣ нестанд!

    import java.math.BigInteger;
    
    public class Main {
    
       public static void main(String[] args) {
    
           BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
           BigInteger integer2 = new BigInteger("222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222");
    
           System.out.println(integer.max(integer2));
    
       }
    }

    Натиҷаи консол:

    
    222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222

Назорати яклухткунии BigDecimal

Ин мавзӯъ дар як бахши алоҳида ҷой дода шудааст, зеро яклухт кардани рақамҳои калон ва танзими он кори оддӣ нест. Шумо метавонед шумораи ҷойҳои даҳиро барои адад BigDecimalбо истифода аз setScale(). Масалан, мо мехоҳем дақиқии рақами 111.5555555555 -ро ба се адади даҳӣ муқаррар кунем. Аммо мо наметавонем, ки рақами 3-ро ҳамчун далел ба усул гузаронем setScale()ва бо ҳамин мушкor худро ҳал кунем. Тавре ки дар боло зикр гардид, BigDecimalин рақамҳо барои ҳисобҳо бо дақиқии зиёд мебошанд. Дар шакли ҳозираи худ шумораи мо 10 адад дорад. Мо мехоҳем, ки 7-тои онҳоро партофта, танҳо 3-тоашро гузорем. Аз ин рӯ, ба ғайр аз рақами 3, мо бояд ҳолати яклухткуниро ҳамчун параметр гузаронем . Дар маҷмӯъ 8 ҳолати мудавваркунӣ вуҷуд дорад BigDecimal. Хеле зиёд! Аммо агар ба шумо лозим аст, ки воқеан дурустии ҳисобҳоро дар барнома дуруст кунед, шумо ҳама чизеро, ки барои ин лозим аст, доред. Ҳамин тавр, дар ин ҷо 8 намуди мудавваркунӣ мавҷуданд BigDecimal:
  1. ROUND_CEILING- ҷамъоварӣ кардан

    111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
  2. ROUND_DOWN- партофтани разряд

    111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
  3. ROUND_FLOOR- яклухткунӣ

    111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555

  4. ROUND_HALF_UP— яклухткунӣ агар адади пас аз нуқтаи даҳӣ >= ,5 бошад

    0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6
    0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
  5. ROUND_HALF_DOWN— яклухткунӣ агар адади пас аз нуқтаи даҳӣ > .5 бошад

    0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5
    0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
  6. ROUND_HALF_EVEN— яклухткунӣ аз адади чапи нуқтаи даҳӣ вобаста хоҳад буд. Агар рақами чап ҷуфт бошад, яклухткунӣ ба поён анҷом дода мешавад. Агар адади чапи нуқтаи даҳӣ тоқ бошад, он яклухт карда мешавад.

    2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2

    Шумораи дар тарафи чапи нуқтаи даҳӣ - 2 - ҷуфт аст. Яклухткунӣ ба поён ба амал меояд. Азбаски ба мо 0 адад даҳӣ лозим аст, натиҷа 2 хоҳад буд.

    3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4

    Шумораи дар тарафи чапи нуқтаи даҳӣ - 3 - тоқ аст. Даврагиркунӣ ба боло сурат мегирад. Азбаски ба мо 0 адад адад лозим аст, натиҷа 4 хоҳад буд.

  7. ROUND_UNNECCESSARY— дар ҳолатҳое истифода мешавад, ки режими яклухткунӣ бояд ба ягон усул гузаронида шавад, аммо рақам ба яклухт ниёз надорад. Агар шумо кӯшиш кунед, ки рақамро ҳангоми танзими ҳолати ROUND_UNNECCESSARY давр занед, ArithmeticException партофта мешавад.

    3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
  8. ROUND_UP- ҷамъоварӣ кардан.

    111.5551 -> setScale(3, ROUND_UP) -> 111.556

Муқоисаи рақамҳои калон

Ин савол низ муҳим аст. Шумо аллакай дар хотир доред, ки ин усул барои муқоисаи an objectҳо дар Java истифода мешавад equals(). Он ё аз ҷониби худи забон таъмин карда мешавад (дар ҳолати синфҳои дарунсохташудаи Java) ё аз ҷониби барномасоз бекор карда мешавад. Аммо дар мавриди an objectҳои синфӣ, BigDecimalистифодаи усул equals()барои муқоиса тавсия дода намешавад. Сабаби ин дар он аст, ки BigDecimal.equals()усули ду рақам танҳо дар сурате ҳақиқӣ бармегардад , агар ду адад арзиш ва миқёси якхела дошта бошанд : Биёед рафтори усулҳои equals()y Doubleва yро муқоиса кунем BigDecimal:
import java.math.BigDecimal;

public class Main {

   public static void main(String[] args) {

       Double a = 1.5;
       Double b = 1.50;

       System.out.println(a.equals(b));

       BigDecimal x = new BigDecimal("1.5");
       BigDecimal y = new BigDecimal("1.50");

       System.out.println(x.equals(y));

   }
}
Натиҷаи консол:

true
false
Тавре ки шумо мебинед, рақамҳои 1,5 ва 1,50 дар ҳолати c BigDecimalнобаробар баромаданд! Ин маҳз аз сабаби хусусиятҳои метод equals()дар синф рӯй дод BigDecimal. Барои муқоисаи дурусти ин ду, BigDecimalбеҳтар аст, ки усули зеринро истифода баред compareTo():
import java.math.BigDecimal;

public class Main {

   public static void main(String[] args) {

       BigDecimal x = new BigDecimal("1.5");
       BigDecimal y = new BigDecimal("1.50");

       System.out.println(x.compareTo(y));

   }
}
Натиҷаи консол:

0
Усули compareTo()0 баргашт, ки маънои баробар ба 1,5 ва 1,50 аст. Ин натиҷаест, ки мо ба он умед баста будем! :) Ин дарси имрӯзаи моро ба анҷом мерасонад. Вақти он расидааст, ки ба вазифаҳо баргардем! :)
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION