1. Закръгляване на реални числа
Както вече обсъдихме, когато реално число е присвоено на променлива int
, то винаги се закръгля надолу до най-близкото по-малко цяло число — дробната част просто се изхвърля.
Но е лесно да си представим ситуация, когато дробно число трябва да бъде закръглено до най-близкото цяло число в която и да е посока or дори закръглено нагоре. Какво правите в този случай?
За тази и за много подобни ситуации Java има Math
клас, който има методите round()
, ceil()
и floor()
.
Math.round()
метод
Методът Math.round()
закръгля число до най-близкото цяло число:
long x = Math.round(real_number)
Но тук има още един нюанс: този метод връща цяло long
число (а не int
). Тъй като реалните числа могат да бъдат много големи, създателите на Java решиха да използват най-големия наличен целочислен тип на Java: long
.
Съответно, ако програмист иска да присвои резултата на променлива int
, тогава той трябва изрично да посочи на компилатора, че приема възможната загуба на данни (в случай, че полученото число не се вписва в тип int
).
int x = (int) Math.round(real_number)
Примери:
Изявление | Резултат |
---|---|
|
|
|
|
|
|
Math.ceil()
метод
Методът Math.ceil()
закръгля число до цяло число. Ето примери:
Изявление | Резултат |
---|---|
|
|
|
|
|
|
Math.floor()
метод
Методът Math.floor()
закръгля число надолу до цяло число. Ето примери:
Изявление | Резултат |
---|---|
|
|
|
|
|
|
Разбира се, когато закръгляте число надолу до цяло число, е по-лесно просто да използвате оператор за преобразуване на типа:(int)
Изявление | Резултат |
---|---|
|
|
Ако ви е трудно да запомните тези имена, кратък урок по английски ще ви помогне:
Math
означава математикаRound
означава кръглоCeiling
означава таванFloor
означава под
2. Как са структурирани числата с плаваща запетая
Типът double
може да съхранява стойности в диапазона от до . Този огромен диапазон от стойности (в сравнение с типа) се обяснява с факта, че типът (Howто и ) има напълно различна вътрешна структура от целочислените типове. Вътрешно типът codeира стойността си като две числа: първото се нарича мантиса , а второто се нарича експонента .-1.7*10308
+1.7*10308
int
double
float
double
Да кажем, че имаме числото 123456789
и го съхраняваме като double
променлива. Когато го направим, числото се преобразува в , а вътрешно типът съхранява две числа — и . Значимото ("значимата част от числото" or мантисата) е подчертано в червено, докато показателят е подчертано в синьо.1.23456789*108
double
23456789
8
Този подход позволява да се съхраняват Howто много големи числа, така и много малки. Но тъй като представянето на числото е ограничено до 8 byteа (64 бита) и някои от битовете се използват за съхраняване на експонентата (Howто и знака на мантисата и знака на експонентата), максималните налични цифри за представяне на мантисата е 15 .
Това е много опростено описание на това How са структурирани реалните числа.
3. Загуба на точност при работа с реални числа
Когато работите с реални числа, винаги имайте предвид, че реалните числа не са точни . Винаги може да има грешки при закръгляване и грешки при преобразуване при преобразуване от десетична в двоична система. Освен това, най-често срещаният източник на грешка е загубата на точност при добавяне/изваждане на числа в коренно различни мащаби.
Последният факт е малко умопомрачителен за начинаещите програмисти.
Ако извадим от , получаваме .1/109
109
109
Изваждане на числа в коренно различни мащаби | Обяснение |
---|---|
|
Второто число е изключително малко , което ще доведе до пренебрегване на неговия значим (маркиран в сиво). 15- те значещи цифри са подчертани в оранжево. |
Какво да кажем, програмирането не е същото като математиката.
4. Клопка при сравняване на реални числа
Друга опасност дебне програмистите, когато сравняват реални числа. Възниква при работа с реални числа, защото могат да се натрупат грешки при закръгляне. Резултатът е, че има ситуации, когато реалните числа се очаква да бъдат равни, но не са. Или обратното: числата се очаква да са различни, но са равни.
Пример:
Изявление | Обяснение |
---|---|
|
Стойността на променливата a ще бъде 1000000000.0 Стойността на променливата c ще бъде 1000000000.0 (числото в b променливата е прекалено малко) |
В горния пример a
и c
не трябва да са равни, но са.
Или нека вземем друг пример:
Изявление | Обяснение |
---|---|
|
Стойността на променливата a ще бъде 1.0 Стойността на променливата b ще бъде1.0 |
5. Интересен факт заstrictfp
Java има специална strictfp
ключова дума ( strict f loating p point ), която не се среща в други езици за програмиране. И знаете ли защо ви трябва? Влошава точността на операциите с числа с плаваща запетая . Ето историята How се появи:
GO TO FULL VERSION