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*10308intdoublefloatdouble
Да кажем, че имаме числото 123456789и го съхраняваме като doubleпроменлива. Когато го направим, числото се преобразува в , а вътрешно типът съхранява две числа — и . Значимото ("значимата част от числото" or мантисата) е подчертано в червено, докато показателят е подчертано в синьо.1.23456789*108double234567898
Този подход позволява да се съхраняват Howто много големи числа, така и много малки. Но тъй като представянето на числото е ограничено до 8 byteа (64 бита) и някои от битовете се използват за съхраняване на експонентата (Howто и знака на мантисата и знака на експонентата), максималните налични цифри за представяне на мантисата е 15 .
Това е много опростено описание на това How са структурирани реалните числа.
3. Загуба на точност при работа с реални числа
Когато работите с реални числа, винаги имайте предвид, че реалните числа не са точни . Винаги може да има грешки при закръгляване и грешки при преобразуване при преобразуване от десетична в двоична система. Освен това, най-често срещаният източник на грешка е загубата на точност при добавяне/изваждане на числа в коренно различни мащаби.
Последният факт е малко умопомрачителен за начинаещите програмисти.
Ако извадим от , получаваме .1/109109109
| Изваждане на числа в коренно различни мащаби | Обяснение |
|---|---|
|
Второто число е изключително малко , което ще доведе до пренебрегване на неговия значим (маркиран в сиво). 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