Сколько вмещает int
Перейти к содержимому

Сколько вмещает int

  • автор:

Java/Типы данных

В Java есть 8 примитивных типов, которые делят на 4 группы, вот они:

  1. Целые числа — byte, short, int, long
  2. Числа с плавающей точкой (иначе вещественные) — float, double
  3. Логический — boolean
  4. Символьный — char

Целочисленные типы [ править ]

Целочисленные типы различаются между собой только диапазонами возможных значений, например, для хранения номера элемента в таблице Менделеева пока хватит переменной типа byte.

Тип Размер (бит) Диапазон
byte 8 бит от -128 до 127
short 16 бит от -32768 до 32767
char 16 бит беззнаковое целое число, представляющее собой символ UTF-16 (буквы и цифры)
int 32 бит от -2147483648 до 2147483647
long 64 бит от -9223372036854775808L до 9223372036854775807L

Пример использования целочисленных типов:

public class IntegralTypes  public static void main(String[] args)  byte b = 216; // Вот тут будет ошибка, т.к. у нас диапазон от -128 до 127! short s = 1123; int i = 64536; long l = 2147483648L; // Постфикс l или L обозначает литералы типа long System.out.println(i); System.out.println(b); System.out.println(s); System.out.println(l); > > 

Символы тоже относят к целочисленным типам из-за особенностей представления в памяти и традиций.

public class Characters  public static void main(String[] args)  char a = 'a', b, c = 'c'; b = (char) ((a + c) / 2); // Можно складывать, вычитать, делить и умножать // Но из-за особенностей арифметики Java результат приходится приводить к типу char явно System.out.println(b); // Выведет символ 'b' > > 

Типы с плавающей точкой [ править ]

Тип Размер (бит) Диапазон
float 32 от 1.4e-45f до 3.4e+38f
double 64 от 4.9e-324 до 1.7e+308
public class FloatingPointTypes  public static void main(String[] args)  double a, b = 4.12; a = 22.1 + b; float pi = 3.14f; // При использовании типа float требуется указывать суффикс f или F // так как без них типом литерала будет считаться double float anotherPi = (float) 3.14; // Можно привести явно double c = 27; double d = pi * c; System.out.println(d); > > 

Логический тип [ править ]

Тип Размер (бит) Значение
boolean 8 (в массивах), 32 (не в массивах используется int) true (истина) или false (ложь)

В стандартной реализации Sun JVM и Oracle HotSpot JVM тип boolean занимает 4 байта (32 бита), как и тип int. Однако, в определенных версиях JVM имеются реализации, где в массиве boolean каждое значение занимает по 1-му байту.

Ссылочные [ править ]

Ссылочные типы — это все остальные типы: классы, перечисления и интерфейсы, например, объявленные в стандартной библиотеке Java, а также массивы.

Строки [ править ]

Строки это объекты класса String, они очень распространены, поэтому в некоторых случаях обрабатываются отлично от всех остальных объектов. Строковые литералы записываются в двойных кавычках.

public class Strings  public static void main(String[] args)  String a = "Hello", b = "World"; System.out.println(a + " " + b); // Здесь + означает объединение (конкатенацию) строк // Пробел не вставляется автоматически // Строки конкатенируются слева направо, надо помнить это когда соединяешь строку и примитив String c = 2 + 2 + ""; // "4" String d = "" + 2 + 2; // "22" d = "" + (2 + 2); // а теперь d тоже "4" String foo = "a string"; String bar = "a string"; // bar будет указывать на тот же объект что и foo String baz = new String("a string"); // Чтобы гарантированно создать новую строку надо вызвать конструктор System.out.println("foo == bar ? " + (foo == bar)); // == сравнивает ссылки на объекты System.out.println("foo равен bar ? " + (foo.equals(bar))); // Метод equals служит для проверки двух объектов на равенство System.out.println("foo == baz ? " + (foo == baz)); System.out.println("foo равен baz ? " + (foo.equals(baz))); > > 

Эта программа выведет:
Hello World
foo == bar ? true
foo равен bar ? true
foo == baz ? false
foo равен baz ? true

Обертки [ править ]

Если требуется создать ссылку на один из примитивных типов данных, необходимо использовать соответствующий класс-обертку. Также в таких классах есть некоторые полезные методы и константы, например минимальное значение типа int можно узнать использовав константу Integer.MIN_VALUE. Оборачивание примитива в объект называется упаковкой (boxing), а обратный процесс распаковкой (unboxing).

Тип Класс-обертка
byte Byte
short Short
int Integer
long Long
char Character
float Float
double Double
boolean Boolean
int i; Integer boxed; // Обычное создание объекта boxed = new Integer(i); // Фабричный метод boxed = Integer.valueOf(i); // Автоматическая упаковка, компилятор просто вставит вызов Integer.valueOf boxed = i; 

Рекомендуется использовать valueOf, он может быть быстрее и использовать меньше памяти потому что применяет кэширование, а конструктор всегда создает новый объект.

Получить примитив из объекта-обертки можно методом Value.

Integer boxed; int i; // Явная распаковка i = boxed.intValue(); // Автоматическая распаковка i = boxed; 

Сколько вмещает int

Целые числа ( int ) могут быть указаны в десятичной (основание 10), шестнадцатеричной (основание 16), восьмеричной (основание 8) или двоичной (основание 2) системе счисления. Для задания отрицательных целых ( int ) используется оператор отрицания

Для записи в восьмеричной системе счисления, необходимо поставить перед числом 0 (ноль). Начиная с PHP 8.1.0, восьмеричной нотации также может предшествовать 0o или 0O . Для записи в шестнадцатеричной системе счисления, необходимо поставить перед числом 0x . Для записи в двоичной системе счисления, необходимо поставить перед числом 0b

Начиная с PHP 7.4.0, целочисленные литералы могут содержать подчёркивания ( _ ) между цифрами для лучшей читаемости литералов. Эти подчёркивания удаляются сканером PHP.

Пример #1 Целые числа

$a = 1234 ; // десятичное число
$a = 0123 ; // восьмеричное число (эквивалентно 83 в десятичной системе)
$a = 0o123 ; // восьмеричное число (начиная с PHP 8.1.0)
$a = 0x1A ; // шестнадцатеричное число (эквивалентно 26 в десятичной системе)
$a = 0b11111111 ; // двоичное число (эквивалентно 255 в десятичной системе)
$a = 1_234_567 ; // десятичное число (с PHP 7.4.0)
?>

Формально, структура целых чисел int принята в PHP 8.1.0 (ранее не допускались восьмеричные префиксы 0o или 0O , а до PHP 7.4.0 не допускалось подчёркивание):

десятичные : [1-9][0-9]*(_[0-9]+)* | 0 шестнадцатеричные : 0[xX][0-9a-fA-F]+(_[0-9a-fA-F]+)* восьмеричные : 0[oO]?[0-7]+(_[0-7]+)* двоичные : 0[bB][01]+(_[01]+)* целые : десятичные | шестнадцатеричные | восьмеричные | двоичные

Размер типа int зависит от платформы, хотя, как правило, максимальное значение примерно равно 2 миллиардам (это 32-битное знаковое). 64-битные платформы обычно имеют максимальное значение около 9E18. PHP не поддерживает беззнаковые целые числа ( int ). Размер int может быть определён с помощью константы PHP_INT_SIZE , максимальное значение — с помощью константы PHP_INT_MAX , а с помощью константы PHP_INT_MIN можно определить минимальное значение.

Переполнение целых чисел

Если PHP обнаружил, что число превышает размер типа int , он будет интерпретировать его в качестве float . Аналогично, если результат операции лежит за границами типа int , он будет преобразован в float .

Пример #2 Переполнение целых на 32-битных системах

$large_number = 2147483647 ;
var_dump ( $large_number ); // int(2147483647)

$large_number = 2147483648 ;
var_dump ( $large_number ); // float(2147483648)

$million = 1000000 ;
$large_number = 50000 * $million ;
var_dump ( $large_number ); // float(50000000000)
?>

Пример #3 Переполнение целых на 64-битных системах

$large_number = 9223372036854775807 ;
var_dump ( $large_number ); // int(9223372036854775807)

$large_number = 9223372036854775808 ;
var_dump ( $large_number ); // float(9.2233720368548E+18)

$million = 1000000 ;
$large_number = 50000000000000 * $million ;
var_dump ( $large_number ); // float(5.0E+19)
?>

В PHP нет оператора деления целых чисел ( int ), для этого используйте функцию intdiv() >. Результатом 1/2 будет float 0.5 . Если привести значение к int , оно будет округлено вниз, то есть будет отброшена дробная часть числа. Для большего контроля над округлением используйте функцию round() .

var_dump ( 25 / 7 ); // float(3.5714285714286)
var_dump ((int) ( 25 / 7 )); // int(3)
var_dump ( round ( 25 / 7 )); // float(4)
?>

Преобразование в целое

Для явного преобразования в int , используйте приведение (int) или (integer) . Однако, в большинстве случаев, в приведении типа нет необходимости, так как значение будет автоматически преобразовано, если оператор, функция или управляющая структура требует аргумент типа int . Значение также может быть преобразовано в int с помощью функции intval() .

Если resource преобразуется в int , то результатом будет уникальный номер ресурса, привязанный к resource во время исполнения PHP программы.

Из булевого типа

false преобразуется в 0 (ноль), а true — в 1 (единицу).

Из чисел с плавающей точкой

При преобразовании из float в int , число будет округлено в сторону нуля. Начиная с PHP 8.1.0, при неявном преобразовании неинтегрального числа с плавающей точкой ( float ) в целое число ( int ), которое теряет точность, выдаётся уведомление об устаревании.

function foo ( $value ): int return $value ;
>

var_dump ( foo ( 8.1 )); // «Deprecated: Implicit conversion from float 8.1 to int loses precision» начиная с PHP 8.1.0
var_dump ( foo ( 8.1 )); // 8 до PHP 8.1.0
var_dump ( foo ( 8.0 )); // 8 в обоих случаях

var_dump ((int) 8.1 ); // 8 в обоих случаях
var_dump ( intval ( 8.1 )); // 8 в обоих случаях
?>

Если число с плавающей точкой превышает размеры int (обычно +/- 2.15e+9 = 2^31 на 32-битных системах и +/- 9.22e+18 = 2^63 на 64-битных системах, результат будет неопределённым, так как float не имеет достаточной точности, чтобы вернуть верный результат в виде целого числа ( int ). В этом случае не будет выведено ни предупреждения, ни даже замечания!

Замечание:

Значения NaN и Infinity при приведении к int становятся равными нулю, вместо неопределённого значения в зависимости от платформы.

Внимание

Никогда не приводите неизвестную дробь к int , так как это иногда может дать неожиданные результаты.

echo (int) ( ( 0.1 + 0.7 ) * 10 ); // выводит 7!
?>

Из строк

Если строка содержит число или ведущую числовую последовательность, тогда она будет преобразована в соответствующее целое число, в противном случае она преобразуется в ноль ( 0 ).

Из NULL

Значение null всегда преобразуется в ноль ( 0 ).

Из других типов

Предостережение

Для других типов поведение преобразования в int не определено. Не полагайтесь на любое наблюдаемое поведение, так как оно может измениться без предупреждения.

User Contributed Notes 19 notes

10 years ago

A leading zero in a numeric literal means «this is octal». But don’t be confused: a leading zero in a string does not. Thus:
$x = 0123; // 83
$y = «0123» + 0 // 123

16 years ago

Here are some tricks to convert from a «dotted» IP address to a LONG int, and backwards. This is very useful because accessing an IP addy in a database table is very much faster if it’s stored as a BIGINT rather than in characters.

IP to BIGINT:
$ipArr = explode ( ‘.’ , $_SERVER [ ‘REMOTE_ADDR’ ]);
$ip = $ipArr [ 0 ] * 0x1000000
+ $ipArr [ 1 ] * 0x10000
+ $ipArr [ 2 ] * 0x100
+ $ipArr [ 3 ]
;
?>

IP as BIGINT read from db back to dotted form:

Keep in mind, PHP integer operators are INTEGER — not long. Also, since there is no integer divide in PHP, we save a couple of S-L-O-W floor ()’s by doing bitshifts. We must use floor(/) for $ipArr[0] because though $ipVal is stored as a long value, $ipVal >> 24 will operate on a truncated, integer value of $ipVal! $ipVint is, however, a nice integer, so
we can enjoy the bitshifts.

$ipVal = $row [ ‘client_IP’ ];
$ipArr = array( 0 =>
floor ( $ipVal / 0x1000000 ) );
$ipVint = $ipVal -( $ipArr [ 0 ]* 0x1000000 ); // for clarity
$ipArr [ 1 ] = ( $ipVint & 0xFF0000 ) >> 16 ;
$ipArr [ 2 ] = ( $ipVint & 0xFF00 ) >> 8 ;
$ipArr [ 3 ] = $ipVint & 0xFF ;
$ipDotted = implode ( ‘.’ , $ipArr );
?>

5 years ago

var_dump((int) «010»); //output 10

First one is octal notation so the output is correct. But what about the when converting «010» to integer. it should be also output 8 ?
—————————————————————————
Answer :

Casting to an integer using (int) will always cast to the default base, which is 10.

Casting a string to a number this way does not take into account the many ways of formatting an integer value in PHP (leading zero for base 8, leading «0x» for base 16, leading «0b» for base 2). It will simply look at the first characters in a string and convert them to a base 10 integer. Leading zeroes will be stripped off because they have no meaning in numerical values, so you will end up with the decimal value 10 for (int)»010″.

Converting an integer value between bases using (int)010 will take into account the various ways of formatting an integer. A leading zero like in 010 means the number is in octal notation, using (int)010 will convert it to the decimal value 8 in base 10.

This is similar to how you use 0x10 to write in hexadecimal (base 16) notation. Using (int)0x10 will convert that to the base 10 decimal value 16, whereas using (int)»0x10″ will end up with the decimal value 0: since the «x» is not a numerical value, anything after that will be ignored.

If you want to interpret the string «010» as an octal value, you need to instruct PHP to do so. intval(«010», 8) will interpret the number in base 8 instead of the default base 10, and you will end up with the decimal value 8. You could also use octdec(«010») to convert the octal string to the decimal value 8. Another option is to use base_convert(«010», 8, 10) to explicitly convert the number «010» from base 8 to base 10, however this function will return the string «8» instead of the integer 8.

Casting a string to an integer follows the same the logic used by the intval function:

Returns the integer value of var, using the specified base for the conversion (the default is base 10).
intval allows specifying a different base as the second argument, whereas a straight cast operation does not, so using (int) will always treat a string as being in base 10.

php > var_export((int) «010»);
10
php > var_export(intval(«010»));
10
php > var_export(intval(«010», 8));
8

Какое максимальное значение Integer в Python 3?

Всем доброго времени суток! Много лет программирую на PHP и вот решил выучить Python. И буквально на первых этапах обучения открыл для себя интересную особенность языка, описание которой нигде не нашел. А именно речь идет о максимальном значении Int. В книжке написано, что оно как и во всех основных языках программирования равно 2 147 483 647. Все что выше это уже как минимум long, но есть одно но.

x = 2147483647 ** 20000 print(type(x)) print(str(x).__len__())

Данный скрипт выдает тип Int, при том, что результирующее число превышает все мыслимые и немыслимые границы. И print(x) выводит число, как есть, а не в экспоненциальном виде, как это делает например PHP. Подскажите почему так происходит?

  • Вопрос задан более трёх лет назад
  • 38171 просмотр

1 комментарий

Оценить 1 комментарий

Типы

Вселенная Java состоит из трёх субстанций: примитивы, объекты и коты. Про последних в документации ничего не говорится, поэтому их рассматривать не будем, но они существуют!

Примитивные типы Java не являются объектами. К ним относятся:

  • boolean — булев тип, может иметь значения true или false
  • byte — 8-разрядное целое число
  • short — 16-разрядное целое число
  • int — 32-разрядное целое число
  • long — 64-разрядное целое число
  • char — 16-разрядное беззнаковое целое, представляющее собой символ UTF-16 (буквы и цифры)
  • float — 32-разрядное число в формате IEEE 754 с плавающей точкой
  • double — 64-разрядное число в формате IEEE 754 с плавающей точкой

Примитивный в данном случае не оскорбление, а просто даёт понять, что речь идёт о простом типе, который не умеет прыгать, спать или мяукать. Да что он вообще умеет? Ой, всё.

Простые числовые типы

Тип Разрядность MIN MAX
byte 8 бит -128 127
short 16 бит -32768 32767
int 32 бит -2147483648 2147483647
long 64 бит -9223372036854775808 9223372036854775807
float 32 бит -3.4E+38 3.4E+38
double 64 бит -1.7E+308 1.7E+308

Целочисленные типы

Java определяет четыре целочисленных типа: byte, short, int, long. Они могут быть положительными и отрицательными (Java не поддерживает только положительные значения без знака, как некоторые языки программирования).

Тип byte

Наименьший по размеру целочисленный тип — byte. Это 8-битовый тип с диапазоном допустимых значений от -128 до 127. Переменные типа byte часто используются при работе с потоком данных из сети или файла, а также при работе с необработанными двоичными данными или в массивах для экономии памяти.

Объявить переменную типа byte можно следующим образом:

 byte c, a, t; // объявили сразу три переменные 

В арифметических выражениях с переменными типа byte вычисления выполняются как с типом int, т.е. с помощью 32-битовой арифметики, а полученный результат будет 32-битовым. Смотри пример с short.

Строку с числом перевести в данный тип можно через метод parseByte(String):

 byte x = Byte.parseByte("100"); 

Класс Byte является оболочкой для данного типа. Без необходимости не используйте в Android класс Byte.

Слово «байт» (byte) возникло в компании IBM примерно в 1956 году. Оно произошло от слова bite («кусок»), но его было решено писать через букву y, чтобы не путать со словом «bit» («бит»). В течение некоторого времени слово «байт» обозначало просто число битов в конкретном потоке данных. Однако в середине 1960-х, в связи с разработкой семейства компьютеров System/360 в компании IBM, это слово стало обозначать группу из восьми бит.

Любопытно, что bite имеет также значение «укус» (сущ.) или «укусить» (глагол). Таким образом это наш родной «Кусь!»

Cat

Тип short

Тип short — 16-битовый тип в диапазоне от -32768 до 32767. Используется очень редко.

 short m; 

В арифметических выражениях с переменными типа short вычисления выполняются как с типом int, т.е. с помощью 32-битовой арифметики, а полученный результат будет 32-битовым. Например, такой код не пройдёт.

 // накорми кота short fishNumber = 3; // три рыбки short beefNumber = 2; // два кусочка говядины short breakfast = 0; breakfast = fishNumber + beefNumber; // завтрак чемпиона 

Java будет ругаться на последнюю строчку, так как итоговый результат не может быть short. Как вариант, вам нужно преобразовать результат снова в 16-битовое число.

 breakfast = (short) (fishNumber + beefNumber); // завтрак чемпиона 

Явно перевести строку с числом в тип short можно через метод parseShort(String):

 short x = Short.parseShort("100"); 

Класс Short является оболочкой для данного типа. Без необходимости не используйте в Android класс Short.

Тип int

Целые числа, представленные типом int, являются самым распространённым типом в программе, с которым вы будете работать. Поэтому нужно хорошенько изучить его и узнать его достоинства и ограничения. Это 32-битовый тип, имеющий диапазон допустимых значений от -2147483648 до 2147483647 (около двух миллиардов). Этого числа вполне достаточно, чтобы посчитать всех котов на свете. Часто используется в циклах, индексировании массивов, хотя может показаться, что для небольших операций в цикле и массивах проще использовать short или byte. Нужно запомнить, что тип int эффективен в этих случаях из-за особенностей структуры вычислительных процессоров. Просто примите на веру.

Сказка про тип int

Зададим себе вопрос, насколько большим может быть целое число типа int?

Напишем простую программу, где будем умножать переменную саму на себя. Для начала присвоим ей значение 2, а дальше строчка за строчкой будем выводить результат. Результаты будем отдавать коту учёному LogCat. Весь код поместим в обработчик события щелчка на кнопке нашей учебной программы, а первую строчку поместим выше её.

 final String TAG = "ExpressCourse"; public void onClick(View view)

Запустите программу и нажмите кнопку. В нижней части студии откройте панель Android Monitor и в ней вкладку logcat. Настройте его фильтр, чтобы отображались только наши сообщения. В результате мы получим такую картину:

2 4 16 256 65536 0 0 0 0

Странные результаты типа Integer

Что за бред, скажете вы. Когда мы умножаем 65536 на себя, то получаем 0 (Только не говорите об этом учительнице по математике). А потом, естественно, программа умножает 0 на 0 и продолжает выводить результаты.

Вы ещё больше удивитесь, если в качестве начального значения возьмёте число 3. На этот раз вы сможете получить даже отрицательные значения.

3 9 81 6561 43046721 -501334399 2038349057 -1970898431 120648705

Проверьте самостоятельно. Если вы и это попытаетесь доказать учительнице, то исключение из учебного заведения вам гарантировано.

Деление целочисленных чисел

Запомните, что при делении целочисленных чисел остаток отбрасывается. Поэтому следующие примеры вернут один и тот же результат. Бедная учительница, её увезут в психушку.

 6 / 3 = 2 7 / 3 = 2 8 / 3 = 2 9 / 3 = 3 

На ноль делить нельзя, увидите ошибку.

Если нужен узнать остаток от деления, то используйте оператор % (оператор деления по модулю).

 Log.d(TAG, "Остаток 6 % 3: " + 6 % 3); // 0 Log.d(TAG, "Остаток 7 % 3: " + 7 % 3); // 1 Log.d(TAG, "Остаток 8 % 3: " + 8 % 3); // 2 Log.d(TAG, "Остаток 9 % 3: " + 9 % 3); // 0 

Класс Integer является оболочкой для данного типа. Без необходимости не используйте в Android класс Integer. Для сравнения: тип int занимает 4 байт памяти, а Integer — 16 байт.

Также есть специальный класс BigInteger для проведения арифметических действий повышенной точности (финансовые расчёты).

В Java 7 можно использовать знак подчёркивания для удобства. Например, так:

 int myInt = 1_000_000; // миллион 

Компилятор не обращает внимания на эти знаки, а человеку проще понять, что ему предлагают миллион или миллиард. В Android относительно недавно появилась полноценная поддержка Java 7 и вам в настройках нужно указать новую версию компилятора.

Этот приём относится не только к int, но и к другим типам чисел.

Как сконвертировать строку или CharSequence в int?
 String mString = "42"; // строка int mInt = Integer.parseInt(mString); 

Если у вас тип CharSequence, то его можно сконвертировать сначала в строку при помощи метода toString(), а потом в int.

Метод parseInt() предпочтительнее метода valueOf():

 int number; // плохой вариант number2 = Integer.valueOf("1"); // отличный вариант number = Integer.parseInt("1"); 
Как сконвертировать число в строку?

Если сложить число и строку, то Java автоматически конвертирует число в строку. Пользуясь этим свойством, программисты часто прибавляют к числу пустую строку. Но лучше использовать метод valueOf():

 int number = 1; // плохой вариант String numberString = "" + number; // отличный вариант String numberString = String.valueOf(number); 
Добавить ведущие нули

Если мы хотим получить строку из числа, добавим при этом несколько нулей вначале, то поможет метод format(), только учитывайте число цифр в самом числе.

 int givenNumber = 777; String formattedNumber = String.format("%06d", givenNumber); System.out.println("Число с ведущими нулями: " + formattedNumber); // Число с ведущими нулями: 000777 

Тип long

Тип long — это 64-битный тип со знаком, используемый в тех случаях, когда используется очень большое значение, которое не способен хранить тип int. Например, чтобы вычислить расстояние, которое прошёл солнечный луч от солнца до зеркала, превратившись в солнечного зайчика, за которым безуспешно охотится котёнок, вам понадобится именно этот тип.

Можно использовать символы l или L для обозначения числа типа long. Рекомендую использовать заглавную букву, чтобы избежать возможной путаницы. Например, напишем пример:

 // сколько ночей в арабских сказках? long night = 101l; System.out.println(night); 

Запустив пример, вы увидите ответ 101. Почему так получилось? А потому что последний символ — это не единица, а символ l. Присмотритесь внимательнее. Если бы мы написали long night = 101L, то не ломали бы голову себе.

Конвертируем строку в данный тип.

 long x = Long.parseLong("100"); 

Класс Long является оболочкой для данного типа. Без необходимости не используйте в Android класс Long.

Типы с плавающей точкой

Числа с плавающей точкой (иногда их называют действительными числами) применяются при вычислении выражений, в которых требуется точность до десятичного знака. Например, это может быть вычисление квадратного корня, значений синуса, косинуса и т.п. Существует два типа с плавающей точкой: float и double, которые представляют числа одинарной и двойной точности.

Слово «плавающая» означает, что десятичная точка может располагаться в любом месте (она «плавает»). Вот коты плавать не особенно любят, поэтому они не float и не double.

Тип float

Тип float определяет значение одинарной точности, которое занимает 32 бит. Переменные данного типа удобны, когда требуется дробная часть без особой точности, например, для денежных сумм.

Рекомендуется добавлять символ F или f для обозначения этого типа, иначе число будет считаться типом double.

 float tugrik = 11.6F; 

Конвертируем из строки.

 float x = Float.parseFloat("19.95"); 

Класс Float является оболочкой для данного типа. Без необходимости не используйте в Android класс Float.

Также есть специальный класс BigDecimal для проведения арифметических действий повышенной точности (финансовые расчёты).

Тип double

Тип double обеспечивает двойную точность, что видно из его названия (double — двойная). Занимает 64 бит для хранения значений. Многие математические функции возвращают значения типа double. Кстати, современные процессоры оптимизированы под вычисления значений двойной точности, поэтому они предпочтительнее, чем тип float.

 double pi, r, a; pi = 3.1416; // приблизительное значение числа π r = 5.5; // радиус окружности a = pi * r * r; // вычисляем площадь окружности 

Тип double содержит не только числа, но и слова. Сейчас вам докажу. Разделим число типа double на ноль. Ошибки не произойдёт.

 double positive_infinity = 12.0 / 0; System.out.println(positive_infinity); 

Пример вернёт значение Infinity (Бесконечность). Если разделить отрицательное число на ноль, то вернётся -Infinity.

А что произойдёт, если сложить две бесконечности? Если рассуждать логически, то сломается интернет, наступит конец света или можно вызвать Волдеморта. Я долго не решался, но потом набрался храбрости и попробовал.

 double positive_infinity = 12.0 / 0; double negative_infinity = -15.0 / 0; mInfoTextView.setText(String.valueOf(positive_infinity + negative_infinity)); 

Вернулось ещё одно слово — NaN. Что это вообще? Может должно вернуться Nyan — ну вы знаете, это странный котик, который летит бесконечно в космосе, оставляя за собой шлейф из радуги.

Умножать две бесконечности я побоялся. И вам не советую.

Класс Double является оболочкой для данного типа. Без необходимости не используйте в Android класс Double.

Конвертация строки в double

Есть несколько вариантов.

 // если строка null, то будет исключение NullPointerException // если строка содержит неправильные данные, то будет исключение NumberFormatException String s = "435.23"; Double d = Double.valueOf(s); // возвращает не Double, а double (примитивный тип) // выбрасывает аналогичные исключения double x = Double.parseDouble("19.95"); // В Java 9 признан устаревшим. Не используйте и сейчас String s = "135.360"; Double d = new Double(s); // Через DecimalFormat String s = "135.130"; try < DecimalFormat decimalFormat = new DecimalFormat("#"); double d = decimalFormat.parse(s).doubleValue(); System.out.println("Double value for 135.130 is " + d); >catch (ParseException e)

Конвертация double в строку

При работе с числами double следует держать ухо востро. Рассмотрим пример конвертации трёх чисел.

 double number1 = 120; double number2 = 0.033; double number3 = 0.000045158458; System.out.println(String.valueOf(number1)); System.out.println(String.valueOf(number2)); System.out.println(String.valueOf(number3)); /* System.out: 120.0 System.out: 0.033 System.out: 4.5158458E-5 */ 

Первые два числа нормально преобразовались, а вот третье число преобразовалось в строку в странном виде (на самом деле это научное представление числа). И это может источником проблемы при передаче строки куда-нибудь, например, на сервер. Если сервер не ожидает от вас такой подлости, то будет генерировать ошибки из-за странной записи. Нужно найти другие способы конвертации.

Первый способ — используем String.format().

 double number3 = 0.000045158458; System.out.println(String.valueOf(number3)); System.out.println(String.format("%f", number3)); System.out.println(String.format("%.0f", number3)); System.out.println(String.format("%.12f", number3)); /* System.out: 4.5158458E-5 System.out: 0.000045 System.out: 0 System.out: 0.000045158458 */ 

Последний пример самый подходящий для нас, но вам нужно знать, сколько знаков идёт после десятичной точки. Остальные два пригодятся, если число можно округлить.

Второй способ — метод Double.toString(). У меня метод превратил число в «непонятную» строку. А у некоторых этот пример возвращал строку в нормальном виде. Не заслуживает доверия.

 double number3 = 0.000045158458; System.out.println(Double.toString(number3)); /* System.out: 4.5158458E-5 */ 

Третий способ — добавить пустую строку. В Android не помогло, хотя тоже утверждается, что у кого-то выводится в нормальном виде. Врут, наверное.

 double number3 = 0.000045158458; System.out.println(number3 + ""); /* System.out: 4.5158458E-5 */ 

Четвёртый экзотический способ, которым редко пользуются — DecimalFormat.

 double number3 = 0.000045158458; String pattern = "##.############"; DecimalFormat decimalFormat = new DecimalFormat(pattern); System.out.println(decimalFormat.format(number3)); /* System.out: 0.000045158458 */ 

Символы (тип char)

Для хранения символов Java использует специальный тип char. Он отличается от типа char в языках C/C++, где представляет собой целочисленный тип с размером 8 бит. В Java для char используется кодировка Unicode и для хранения Unicode-символов используется 16 бит или 2 байта. Диапазон допустимых значений — от 0 до 65536 (отрицательных значений не существует).

 char ch1, ch2, ch3; ch1 = 67; // код переменной ch2 = 'a'; // сам символ ch3 = 116; // код переменной mInfoTextView.setText("Слово из трёх букв: " + ch1 + ch2 + ch3); 

Из примера выше видно, что переменной можно присвоить код символа или непосредственно сам символ, который следует окружить одинарными кавычками. Попробуйте запустить пример и посмотреть, какое слово получится из трёх указанных символов.

Не следует путать символ ‘a’ со строкой «a», состоящей из одного символа. На экране монитора они выглядят одинаково, но в программах ведут себя по разному.

Стандартные символы ASCII можно выводить сразу. Если нужно вывести специальный символ из Unicode, то можно воспользоваться шестнадцатеричным представлением кода в escape-последовательности — вы указываете обратную наклонную черту и четыре цифры после u. Например:

 char myChar = '\u0054'; 

Хотя тип char используется для хранения Unicode-символов, его можно использовать как целочисленный тип, используя сложение или вычитание.

 char ch1; ch1 = 'x'; mInfoTextView.append("ch1 содержит " + ch1); ch1++; // увеличим на единицу mInfoTextView.append("ch1 содержит " + ch1); 

В результате получим:

 ch1 содержит x ch1 содержит y 

Если вы думаете, что увеличив значение переменной ch1 ещё на одну единицу, получите символ «й», то глубоко заблуждаетесь.

Чтобы узнать, какой символ содержится в значении переменной, заданной как int, можно воспользоваться двумя специальными методами из класса EncodingUtils:

Для стандартных символов ASCII:

 int i = 67; byte[] data = < (byte) i >; CharSequence strSymbol = EncodingUtils.getAsciiString(data); mInfoTextView.setText(strSymbol); 

Для расширенной таблицы символов:

 int i = 379; byte[] data = < (byte) i >; CharSequence strSymbol = EncodingUtils.getString(data, "windows-1251"); mInfoTextView.setText(strSymbol); 

Методы работают со строками, но если мы используем строку из одного символа, то получим то, что нам нужно.

В упрощённом виде, если работаем со стандартными символами ASCII (on 0 до 127), то можно получить символ из int ещё проще.

 int ascii = 65; if(ascii > 127)< System.out.println("Wrong value"); >else

Класс Character

Класс Character является оболочкой вокруг типа char. Чтобы получить значение типа char, содержащее в объекте класса Character, вызовите метод charValue().

С классом Character редко имеют дело в Android, но помните, что класс содержит огромное количество констант и методов. Например, можно определить, является ли символ цифрой или буквой, или написан ли символ в нижнем или в верхнем регистре.

Булевы значения

Тип boolean предназначен для хранения логических значений и может принимать только одно из двух возможных значений: true или false. Данный тип всегда возвращается при использовании операторов сравнения (больше, меньше, равно, больше или равно, меньше или равно, не равно). Также он используется в управляющих операторах if и for.

 boolean check; check = true; 

В отличие от реальной жизни, где вполне может состояться диалог:

- Кать, чай будешь? - Да нет наверное

В компьютерной программе нужно чётко определиться — истина или ложь.

В операторах if используется укороченная запись при значении true:

 if (check == true) . // необязательный вариант if (check) . // укороченная запись 

Java сам поймёт, что переменную check нужно сравнить с true.

Класс Boolean

Класс Boolean является оболочкой вокруг значений типа boolean. Чтобы получить значение типа boolean из объекта класса Boolean, используйте метод booleanValue(). Тип boolean использует 4 байт памяти, а Boolean — 16. Вывод понятен?

Ещё один совет, применимый ко всем типам. Допустим, нам нужно объявить 32 переменных типа boolean:

 boolean mProperty1; boolean mProperty2; . boolean mProperty32; 

Умножаем 4 байта на 32 переменных и получаем 128 байт занятой памяти. А если объявим массив:

 boolean[] mProperty = new boolean[32] 

Считаем: 4 + 8 + 8 + 32 * 1 = 52. С учётом выравнивания памяти по 8 байт, получаем не 52, а 56. Всё равно меньше, чем в первом примере.

Конвертируем строку в булево значение.

 Boolean booleanValue = Boolean.valueOf("true"); System.out.println(booleanValue); 

Конвертируем булево значение в строку.

 boolean boolenValue = true; // первый способ System.out.println(Boolean.toString(booleanValue)); // второй способ System.out.println(String.valueOf(booleanValue)); 

Приведение типов

Когда мы производим какие-то действия с переменными, то нужно следить за типами. Нельзя умножать котов на футбольные мячи, это противоречит здравому смыслу. Также и с переменными. Если вы присваиваете переменной одного типа значение другого типа, то вспоминайте теорию. Например, вы без проблем можете присвоить значение типа int переменной типа long, так как все числа из диапазона типа int гарантировано помещаются в диапазон чисел long. В этом случае Java выполнит преобразование автоматически, вы даже ничего не заметите.

Представим обратную картину — мы хотим присвоить переменной типа byte значение типа double. Java не сможет автоматически выполнить ваше желание. Не все числа типа double могут стать числом типа byte. Но часть чисел может, например, число 9. В таком случае используется так называемое приведение типов, чтобы подсказать Java о допустимости операции.

Итак, автоматическое преобразование типов осуществляется, если оба типа совместимы и длина целевого типа больше длины исходного типа. В этом случае происходит преобразование с расширением. Вы всегда можете преобразовать любое число типа byte в число типа int. Такая операция произойдёт без вашего участия автоматически.

Таблица выглядит следующим образом.

Приведение типов

Сплошные линии обозначают преобразования, выполняемые без потери данных. Штриховые линии говорят о том, что при преобразовании может произойти потеря точности.

Типы целых чисел и чисел с плавающей точкой совместимы частично. Например, число 5 вполне может быть числом с плавающей точкой (5.0).

Совсем не совместимы, например, char и boolean.

С автоматическим приведением мы разобрались. Рассмотрим вариант, когда нужно преобразовать число типа int в число типа byte. Преобразование автоматически невозможно, поскольку byte меньше int. Но, например, число 99 вполне можно использовать и как int и как byte. В этом случае используется явное приведение типов, то есть преобразование из одного типа в другой (преобразование с сужением).

Выглядит это следующим образом:

 int a; byte b; // какие-то операции с переменной b = (byte) a; 

Как видите, вы в скобках указываете тип, к которому нужно явно привести переменную.

Существует ещё вариант приведения с усечением. Это когда число с плавающей точкой приводится к целочисленному типу. В этом случае отбрасывается дробная часть (хвост). Например, число 3.14 будет усечено до числа 3:

 double a = 3.14; byte b = (byte) a; 

Если размер целочисленной части слишком велик для целочисленного типа, то значение будет уменьшено до результата деления по модулю на диапазон целевого типа.

Например, попробуйте преобразовать число 454.874 в тип byte:

 byte b; double d = 454.874; b = (byte) d; infoTextView.append("b равно " + b); 

У меня вывелся удивительный результат: b равно -58.

Рассмотрим такой пример. Допустим у нас есть выражение, где промежуточное значение может выходить за пределы допустимого диапазона:

 byte a = 44; byte b = 55; byte c = 101; int d = a * b - c; 

При умножении переменных a * b промежуточный результат вышел за пределы диапазона допустимых значений для типов byte. Java во время вычисления промежуточных результатов автоматически повышает тип каждого операнда до int и ошибки не происходит.

Это удобно, но может поставить в тупик в следующем примере:

 byte b = 50; b = b * 2; 

С виду всё правильно. Если не слишком больше число типа byte, а итоговый результат тоже не выходит за диапазон допустимых значений. Но Java не позволит вам написать подобный код. Происходит следующее. Во время вычисления выражения тип операндов был автоматически повышен до int, как об этом говорилось выше. При этом тип результата тоже был повышен до int. Получается, что результат вычисления равен типу int, а мы пытаемся его присвоить переменной b, которая у нас объявлена как byte. И это несмотря на то, что итоговый результат может быть типом byte. Как же выйти из этого положения? Следует использовать явное приведение типов:

 byte b = 50; b = (byte) (b * 2); 

Мы рассмотрели единичные примеры. Пора обобщить и запомнить несколько правил.

Типы всех значений byte, short, char повышаются до типа int, как это было рассмотрено выше.

Если один операнд имеет тип long, то тип всего выражения повышается до long.

Если один операнд имеет тип float, то тип всего выражения повышается до float.

Если один операнд имеет тип double, то тип всего выражения повышается до double.

 byte b = 45; char c = 'c'; short s = 1005; int i = 700000; float f = 4.55f; double d = 1.456; double result = (f * b) + (i / c) - (d * s); mInfoTextView.append("d равно " + d); 

В первом промежуточном выражении (f * b) тип переменной b повышается до float и промежуточный результат также становится float. В следующем выражении (i / c) тип у переменной c повышается до int и промежуточный результат также становится типом int. В выражении (d * s) тип переменной s повышается до double и промежуточное выражение также становится double. В результате у нас появились три промежуточные значения типов: float, int, double. При сложении float и int мы получаем float, затем при вычитании с использованием float и double тип повышается до double, который и становится окончательным типом результата выражения.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *