Содержание

Одинарная или двойная точность? / Хабр

Введение

В научных вычислениях мы часто используем числа с плавающей запятой (плавающей точкой). Эта статья представляет собой руководство по выбору правильного представления числа с плавающей запятой. В большинстве языков программирования есть два встроенных вида точности: 32-битная (одинарная точность) и 64-битная (двойная точность). В семействе языков C они известны как float и double, и здесь мы будем использовать именно такие термины. Есть и другие виды точности: half, quad и т. д. Я не буду заострять на них внимание, хотя тоже много споров возникает относительно выбора half vs float или double vs quad. Так что сразу проясним: здесь идёт речь только о 32-битных и 64-битных числах IEEE 754.

Статья также написана для тех из вас, у кого много данных. Если вам требуется несколько чисел тут или там, просто используйте double

и не забивайте себе голову!

Статья разбита на две отдельные (но связанные) дискуссии: что использовать для хранения ваших данных и что использовать при вычислениях. Иногда лучше хранить данные во float, а вычисления производить в double.

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

Точность данных

У 32-битных чисел с плавающей запятой точность примерно 24 бита, то есть около 7 десятичных знаков, а у чисел с двойной точностью — 53 бита, то есть примерно 16 десятичных знаков. Насколько это много? Вот некоторые грубые оценки того, какую точность вы получаете в худшем случае при использовании

float и double для измерения объектов в разных диапазонах:

Масштаб Одинарная точность Двойная точность
Размер комнаты микрометр радиус протона
Окружность Земли 2,4 метра нанометр
Расстояние до Солнца 10 км толщина человеческого волоса
Продолжительность суток 5 миллисекунд пикосекунда
Продолительность столетия 3 минуты микросекунда
Время от Большого взрыва тысячелетие минута

(пример: используя double, мы можем представить время с момента Большого взрыва с точностью около минуты).

Итак, если вы измеряете размер квартиры, то достаточно float. Но если хотите представить координаты GPS с точностью менее метра, то понадобится double.

Почему всегда не хранить всё с двойной точностью?

Если у вас много оперативной памяти, а скорость выполнения и расход аккумулятора не являются проблемой — вы можете прямо сейчас прекратить чтение и использовать

double. До свидания и хорошего вам дня!

Если же память ограничена, то причина выбора float вместо double проста: он занимает вдвое меньше места. Но даже если память не является проблемой, сохранение данных во float может оказаться значительно быстрее. Как я уже упоминал, double занимает в два раза больше места, чем float, то есть требуется в два раза больше времени для размещения, инициализации и копирования данных, если вы используете double

. Более того, если вы считываете данные непредсказуемым образом (случайный доступ), то с double у вас увеличится количество промахов мимо кэша, что замедляет чтение примерно на 40% (судя по практическому правилу O(√N), что подтверждено бенчмарками).

Влияние на производительность вычислений с одинарной и двойной точностью

Если у вас хорошо подогнанный конвейер с использованием SIMD, то вы сможете удвоить производительность FLOPS, заменив double на float. Если нет, то разница может быть гораздо меньше, но сильно зависит от вашего CPU. На процессоре Intel Haswell разница между float и

double маленькая, а на ARM Cortex-A9 разница большая. Исчерпывающие результаты тестов см. здесь.

Конечно, если данные хранятся в double, то мало смысла производить вычисления во float. В конце концов, зачем хранить такую точность, если вы не собираетесь её использовать? Однако обратное неправильно: может быть вполне оправдано хранить данные во float, но производить некоторые или все вычисления с двойной точностью.

Когда производить вычисления с увеличенной точностью

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

6) чисел, то теряются шесть десятичных знаков (а у float их всего семь!). Решение простое: вместо этого выполнять вычисления в формате double:

float sum(float* values, long long count)
{
    double sum = 0;
    for (long long i = 0; i < count; ++i) {
        sum += values[i];
    }
    return (float)sum;
}

Скорее всего, этот код будет работать так же быстро, как и первый, но при этом не будет теряться точность. Обратите внимание, что вовсе не нужно хранить числа в double, чтобы получить преимущества увеличенной точности вычислений!

Пример

Предположим, что вы хотите точно измерить какое-то значение, но ваше измерительное устройство (с неким цифровым дисплеем) показывает только три значимых разряда. Измерение переменной десять раз выдаёт следующий ряд значений:

3.16, 3.15, 3.16, 3.18, 3.15, 3.11, 3.14, 3.11, 3.14, 3.15

Чтобы увеличить точность, вы решаете сложить результаты измерений и вычислить среднее значение. В этом примере используется число с плавающей запятой в base-10, у которого точность составляет точно семь десятичных знаков (похоже на 32-битный

float). С тремя значимыми разрядами это даёт нам четыре дополнительных десятичных знака точности:

3.160000 +
3.150000 +
3.160000 +
3.180000 +
3.150000 +
3.110000 +
3.140000 +
3.110000 +
3.140000 +
3.150000 =
31.45000

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

314.4300

Всё ещё остались два неиспользованных разряда. Если суммировать тысячу чисел?

3140.890

Десять тысяч?

31412.87

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

31412.87 +
    3.11 =
31415.98

Заметьте, как мы сдвигаем меньшее число, чтобы выровнять десятичный разделитель. У нас больше нет запасных разрядов, и мы опасно приблизились к потере точности. Что если сложить сто тысяч значений? Тогда добавление новых значений будет выглядеть так:

314155.6  +
     3.12 =
314158.7

Обратите внимание, что последний значимый разряд данных (

2 в 3.12) теряется. Вот теперь потеря точности действительно происходит, поскольку мы непрерывно будем игнорировать последний разряд точности наших данных. Мы видим, что проблема возникает после сложения десяти тысяч чисел, но до ста тысяч. У нас есть семь десятичных знаков точности, а в измерениях имеются три значимых разряда. Оставшиеся четыре разряда — это четыре порядка величины, которые выполняют роль своеобразного «числового буфера». Поэтому мы можем безопасно складывать четыре порядка величины = 10000 значений без потери точности, но дальше возникнут проблемы. Поэтому правило следующее:

Если в вашем числе с плавающей запятой P разрядов (7 для float, 16 для double

) точности, а в ваших данных S разрядов значимости, то у вас остаётся P-S разрядов для манёвра и можно сложить 10^(P-S) значений без проблем с точностью. (16-3) = 10 000 000 000 000 значений без проблем с точностью.

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

Выводы


  • Не используйте лишнюю точность при хранении данных.
  • Если складываете большое количество данных, переключайтесь на двойную точность.

Приложение: Что такое число с плавающей запятой?

Я обнаружил, что многие на самом деле не вникают, что такое числа с плавающей запятой, поэтому есть смысл вкратце объяснить. Я пропущу здесь мельчайшие детали о битах, INF, NaN и поднормалях, а вместо этого покажу несколько примеров чисел с плавающей запятой в base-10. Всё то же самое применимо к двоичным числам.

Вот несколько примеров чисел с плавающей запятой, все с семью десятичными разрядами (это близко к 32-битному float). -3 =
3.141593 + 0.0001111111 =
3.141593 + 0.000111 =
3.141704

Заметьте, как мы сдвинули некоторые из значимых десятичных знаков, чтобы запятые совпадали. Другими словами, мы теряем точность, когда складываем числа разных величин.

Разница между поплавком и двойным

Float и Double оба являются типами данных в типе с плавающей точкой. Числа с плавающей точкой — это действительные числа с дробной составляющей. Основное различие между float и double заключается в том, что тип float имеет 32-битное хранилище. С другой стороны, тип double имеет 64-битное хранилище. Есть некоторые другие различия между float и double, которые обсуждаются в сравнительной таблице, приведенной ниже.

Сравнительная таблица:

Основа для сравнениятеркадвойной
точностьОдинарная точностьДвойная точность.
Биты32 бита64 бита
Б4 байта .8 байт.
Приблизительный диапазон1, 4e-045 до 3, 4e + 0384, 9e-324 до 1, 8e + 308
Представление битов1 бит представляет знак бита.
8 бит представляют экспоненту.
23 бита представляют мантиссу.
1 бит представляет знак бита.
11 бит представляют экспоненту.
52 бита представляют мантиссу.
точностьМенее точный.Более точным.

Определение поплавка

Тип с плавающей точкой является одним из типов с плавающей точкой. Тип данных с плавающей запятой имеет 32-разрядное хранилище (равное 4 байта) для переменной типа с плавающей запятой. Тип данных float указывает одинарную точность. Представление 32 бита в формате с плавающей запятой может быть объяснено как 1 бит представлен как знаковый бит, 8 бит представлены как показатель степени, а 23 бита представлены как мантисса. Максимальный диапазон типа с плавающей запятой — от 1.4e-045 до 3.4e + 038. По сравнению с двойным типом с плавающей точкой тип с плавающей точкой менее точен при математическом расчете. Давайте разберемся с плавающей точкой на примере.

 #include #include int main () {float num1 = sqrt (64.23) cout << num1; } // вывод 8.00060 

Как и в приведенном выше коде, вы можете заметить, что переменной с плавающей запятой num1 присваивается значение, которое является функцией sqrt (), которая возвращает квадратный корень из значения, переданного этой функции. Вы можете заметить, что когда печатается значение в num1, оно примерно соответствует точному значению, но не является точным. Давайте теперь посмотрим на пример ниже, когда та же программа выполняется с использованием double в качестве типа данных.

Определение двойного

Double — это второй тип данных с плавающей точкой. Тип данных double имеет 64-разрядное хранилище (равное 8 байтам) для переменной типа double. Он определяет двойную точность, так как его размер равен удвоенному значению. 64-битное представление типа double можно объяснить как 1 бит представляет знаковый бит, 11 бит представляет экспоненту, а оставшиеся 52 бита представляют мантиссу. Среди float и double наиболее часто используемый тип данных — double. Тип double используется при математических вычислениях, а также при необходимости идеальной точности. Математические функции sin (), cos () и sqrt () всегда возвращают двойное значение. Давайте разберемся с точностью типа данных double на примере.

 #include #include int main () {double num1 = sqrt (64.23) cout << num1; } // вывод 8.0143621 

Можно заметить, что вывод, полученный в примере с объяснением float, отличается от вывода, полученного в примере с объяснением double. Итак, из этого можно сказать, что результаты, полученные с помощью double, более точны по сравнению с float.

  1. Тип данных с плавающей точкой задает одинарную точность, что означает, что по сравнению с двойной он имеет меньшую точность, тогда как двойной тип определяет двойную точность, так как это просто двойная величина с плавающей точкой, его ошибка незначительна по сравнению с плавающей точкой.
  2. Переменная типа с плавающей запятой имеет 32-битное хранилище, тогда как переменная типа double имеет 64-битное хранилище, которое компилирует, что double больше в памяти по сравнению с плавающей запятой.
  3. Значение в float может варьироваться от 1, 4e-045 до 3, 4e + 038, тогда как значение типа double может варьироваться от 4, 9e-324 до 1, 8e + 308.
  4. Битовое представление значения с плавающей запятой напоминает, что 1 бит с плавающей запятой используется для пения, 8 бит для экспоненты и 23 бита для хранения мантиссы. С другой стороны, двойное значение напоминает, что его 1 бит используется для пения, 11 бит для экспоненты и 52 бита для хранения мантиссы.
  5. Следовательно, при сравнении с двойной плавающей точкой менее точным является математическое вычисление двойной.

Заключение:

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

Тип float | Microsoft Learn

Twitter LinkedIn Facebook Адрес электронной почты

  • Статья
  • Чтение занимает 3 мин

Числа с плавающей запятой используют формат IEEE (Института инженеров по электротехнике и электронике). Значения с одиночной точностью и типом float имеют 4 байта, состоят из бита знака, 8-разрядной двоичной экспоненты excess-127 и 23-битной мантиссы. Мантисса представляет число от 1,0 до 2,0. Поскольку бит высокого порядка мантиссы всегда равен 1, он не сохраняется в числе. Это представление обеспечивает для типа float диапазон примерно от 3,4E–38 до 3,4E+38.

Можно объявить переменные в качестве типа float или double в зависимости от нужд приложения. Основные различия между двумя типами значения заключаются в представляемой ими значимости, требуемых ресурсах хранения и диапазоне. В следующей таблице показана связь между значимостью и требованиями к хранению.

Типы с плавающей запятой

TypeЗначимые цифрыЧисло байтов
float6–74
double15–168

Переменные с плавающей запятой представлены мантиссой, которая содержит значение числа, и экспонентой, которая содержит порядок возрастания числа.

В следующей таблице показано количество битов, выделенных мантиссе и экспоненте для каждого типа с плавающей запятой. Наиболее значимый бит любого типа float или double — всегда бит знака. Если он равен 1, число считается отрицательным; в противном случае — положительным.

Длина экспонент и мантисс

TypeДлина экспонентыДлина мантиссы
float8 бит23 бита
double11 бит52 бита

Поскольку экспоненты хранятся в форме без знака, экспоненты смещены на половину своего возможного значения. Для типа float смещение составляет 127; для типа double это 1023. Можно вычислить фактическое значение экспоненты, вычтя значение смещения из значения экспоненты.

Мантисса хранится в виде бинарной доли, которая больше или равна 1 и меньше 2. Для типов float и double в мантиссе подразумевается наличие начального 1 в наиболее значимой битовой позиции, поэтому фактически длина мантисс составляет 24 и 53 бит соответственно, даже если наиболее значимый бит никогда не хранится в памяти.

Вместо только что описанного метода хранения пакет значений с плавающей запятой может хранить двоичные числа с плавающей запятой как денормализованные числа. Денормализованные числа — это ненулевые числа с плавающей запятой и зарезервированными значениями экспонент, в которых наиболее значимый бит мантиссы равен 0. Используя денормализованный формат, можно расширить диапазон числа с плавающей запятой в ущерб точности. Невозможно контролировать, в какой форме будет представлено число с плавающей запятой — нормализованной или денормализованной. Пакет значений с плавающей запятой определяет представление. В пакете значений с плавающей запятой никогда не используется денормализованная форма. Исключение составляют случаи, когда экспонента становится меньше, чем минимальное значение, которое может быть представлено в нормализованной форме.

В следующей таблице показаны минимальное и максимальное значения, которое можно сохранить в переменных каждого типа с плавающей запятой. Значения, указанные в этой таблице, применяются только к нормализованным числам с плавающей запятой; денормализованные числа с плавающей запятой имеют меньшее минимальное значение. Обратите внимание, что номера, сохраненные в регистрах 80x87, всегда представлены в 80-разрядной нормализованной форме; при сохранении в 32- или 64-разрядных переменных с плавающей запятой числа могут быть представлены только в ненормализованной форме (переменные типов float и long).

Диапазон типов с плавающей запятой

TypeМинимальное значениеМаксимальное значение
плавающее1,175494351 E – 383,402823466 E + 38
double2,2250738585072014 E – 3081,7976931348623158 E + 308

Если точность менее важна, чем размер хранимых данных, имеет смысл использовать тип float для переменных с плавающей запятой. И наоборот, если точность — наиболее важный критерий, используйте тип double.

Уровень переменных с плавающей запятой можно повысить до типа большей значимости (преобразование типа float в тип double). Повышение уровня часто происходит при выполнении арифметических действий с переменными плавающего типа. Это арифметическое действие всегда выполняется на том же уровне точности, что и переменная с наивысшим уровнем точности. Например, проанализируйте объявления следующих типов.

float f_short;
double f_long;
long double f_longer;
f_short = f_short * f_long;

В предыдущем примере уровень переменной f_short повышается до типа double, а затем переменная умножается на f_long; затем результат округляется до типа float и присваивается объекту f_short.

В следующем примере (с использованием объявлений из предыдущего примера) арифметическая операция выполняется на уровне точности переменной типа float (32-разрядной). Уровень результата затем повышается до уровня double.

f_longer = f_short * f_short;

Хранение базовых типов

Decimal числа. Отличия от float

После рассказа про float меня просили рассказать про Decimal. Узнаем же, что это за зверь, как он устроен внутри и как с ним работать. Итак, Decimal – это класс из стандартного модуля decimal. Он представляет собой число с плавающей точкой, как и float. Да, именно с плавающей, потому что некоторые, я слышал, думают, что это число с фиксированной точкой.

Однако, Decimal имеет ряд существенных отличий от float.

Цель

Тип Decimal создан, чтобы операции над рациональными числами в компьютере выполнялись также, как они выполняются людьми, как их преподают в школе. Иными словами, чтобы все-таки 0.1 + 0.1 + 0.1 == 0.3. Из-за ошибок представления, float приводит к утере точности, и такие простые на первый взгляд равенства не выполняются. А это может быть критично в высокоточных научных вычислениях, и главное в сфере бизнеса и финансов!

Внутреннее устройство

float – реализован по стандарту IEEE-754 как число с плавающей запятой двойной точности (64 бита) на основании 2. Реализация таких чисел заложена прямо в железо почти любого современного процессора. Поэтому float в Python работает примерно также, как и double в С, С++, Java и прочих языках. И имеет такие же ограничения и «странности». Так как поддержка float имеет аппаратный характер, то его быстродействие сравнительно велико.

Decimal – число с плавающей точкой с основанием экспоненты – 10, отсюда и название (decima лат. – десятая часть, десятина).

Он реализован по стандарту IBM: General Decimal Arithmetic Specification Version 1.70 – 7 Apr 2009, который в свою очередь основан на стандартах IEEE. По поводу реализации, в исходниках CPython я нашел два варианта: на чистом Python и с помощью Си-библиотеки libmpdec. Обе реализации есть в кодовой базе, хотя в последних версиях Python 3 используется именно Си-версия, очевидно, она в разы быстрее! Видите букву Си?

Python 3. 7.5 (default, Nov 13 2019, 14:05:23)
[Clang 11.0.0 (clang-1100.0.33.12)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import decimal
>>> help(decimal)
Help on module decimal:
NAME
    decimal - C decimal arithmetic module
...

Поэтому первый важный вывод:

Хоть Decimal и написан на Си, он в разы медленнее, чем float, так как реализован программно, а float – аппаратно.

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

Теперь самое главное – основание 10. Оно позволяет записывать десятичные дроби точно, без ошибок представления.

Decimal_Число = ±мантисса * 10 экcпонента

Мантисса и экспоненты – целые числа.

Помните, что мы не могли представить 0. 1 в float с основанием 2? С основанием 10 – это элементарно:

0.1 = 1 * 10-1, и таким образом, 0.3 = 3 * 10-1 = (1 + 1 + 1) * 10-1 = 0.1 + 0.1 + 0.1

Как мы в школе учили десятичные дроби и знаем, как оперировать ими, так и здесь. Все точно и привычно. Ну почти все. Если мы разделим единицу на тройку, то получим бесконечную периодическую дробь 0.33333333…, либо по другому ее пишут 0.(3) – три в периоде. Естественно, что бесконечных чисел, записанных цифрами в памяти компьютера быть не может, иначе бы потребовалась бесконечная память. Поэтому количество троек в записи может быть большим, но обязано быть конечным.

Decimal оперирует с числами с произвольной (задаваемой пользователем), но конечной точностью.

По умолчанию точность – 28 десятичных знаков.

Еще одно следствие того, что Decimal реализовано программно – то, что его можно на ходу настраивать, как угодно пользователю.

Для этого есть контекст – объект, содержащий настройки для выполнения операций и флаги. Операции выполняемые в этом контексте следуют правилам, заданным в нем. В отличии от float, где все правила фиксированы на аппаратном или низшим программным уровнях. Настроить можно:

  • Точность выполнения операций в количестве десятичных знаках
  • Режимы округления (их целых 8 штук)
  • Пределы по экспоненте
  • Режимы обработки исключительных ситуаций – настройки сигналов (например, деление на ноль, переполнение и прочее).

Флаги в контексте устанавливаются со стороны модуля decimal, если при последнем вычислении случился какой-то из сигналов. (Это отдельная тема, о ней потом.)

Сам же объект Decimal содержит знак, мантиссу (коэффициент перед экспонентой) и саму экспоненту (степень). Лишние нули в мантиссе на обрезаются, чтобы сохранять значимость числа (1.20 * 2.40 = 2.8800).

Decimal – иммутабельный (неизменяемый) тип. Операции над ним приводят к созданию новых объектов, а старые не меняются.

Поработаем с Decimal

Начинаем с импорта и посмотрим, каков контекст по умолчанию:

>>> from decimal import *
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])

Мы видим здесь, что точность 28 знаков, округление к ближайшему четному, пределы по экспоненте ±999999, capitals – это про заглавную Е при печати, clamp не будем трогать пока что, флаги все сброшены, а включенные ловушки – неправильная операция, деление на ноль, переполнение. Если ловушка включена, это значит, что при возникновении соответствующего сигнала будет брошено исключение. Если нет ловушки, то при сигнале будет только втихую установлен флаг. Я оставлю тему ловушек на следующую статью.

Создание Decimal

Создать Decimal можно из обычного целого числа, из float, из строки или кортежа. С обычным числом все просто – int представлены и так точно:

>>> Decimal(1)
Decimal('1')
>>> Decimal(-1)
Decimal('-1')
>>> Decimal(10002332)
Decimal('10002332')

Из float – надо быть очень аккуратным. Потому что, float округляется внутри до ближайшего возможного, а Decimal не знает о ваших первоначальных намерениях, поэтому копирует содержимое float. К примеру, числа 0.1 в представлении float просто не существует. Python считывает 0.1 из кода как строку, потому ищет наиболее близкий к нему возможный float, а из него уже копируется содержимое в Decimal, как есть – уже с ошибкой:

>>> Decimal(0. 1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')

Не рекомендуется создавать Decimal из float. В Decimal попадет уже неправильно округленное число. Создавайте Decimal из целых чисел, либо из строк!

Логически правильно создавать Decimal сразу из строки, избегая фазу с превращением его в float! Что есть в строке – попадет в Decimal. Может показаться, что это немного криво – хранить числах в строках, но теперь вы знаете о представлении двоичного float, и строки обретают реальный смысл.

>>> Decimal('0.1')
Decimal('0.1')
>>> Decimal('3.14')
Decimal('3.14')
>>> Decimal('1.2e+10')
Decimal('1.2E+10')
>>> Decimal('10_000_000_000')  # c версии Python 3.6 можно подчеркивания
Decimal('10000000000')

Можно строкой еще задавать бесконечности и NaN (не число). Примеры:

>>> Decimal('Inf')
Decimal('Infinity')
>>> Decimal('-Inf')
Decimal('-Infinity')
>>> Decimal('nan')
Decimal('NaN')

Если использовать кортеж для конструирования Decimal, то он должен содержать три элемента:

  1. Знак, как число: 0 – это плюс, 1 – это минус.
  2. Кортеж из значащих цифр мантиссы
  3. Число – показатель экспоненты

Вообще кортеж для Decimal использует редко. Но вот вам пример:

>>> Decimal((0, (1, 2, 3, 4, 5), -1))
Decimal('1234.5')
>>> Decimal((1, (7, 7, 7), 3))
Decimal('-7.77E+5')

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

>>> Decimal("1e9999999999999999999")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]

Точность представление Decimal задается исключительно длиной задающего числа (или длиной строки). Настройки точности и режимов округления из контекста в ступают в игру только во время совершения математических операций.

>>> с = Context(prec=3)  # точность 3
>>> Decimal('5.643434231', c)  # но число целиком сохраняется
Decimal('5. 643434231')
>>> Decimal('5.643434231', c) * 2  # после операции уже применяется округление до нужной точности
Decimal('11.287')
>>> +Decimal('5.643434231', c)  # трюк: унарный плюс применит контекст
Decimal('5.6434')

Decimal отлично интегрирован в среду Python. Что касается математики, то с Decimal работают все привычные операции: сложение, вычитание, умножение, деление, возведение в степень и так далее.

Работайте с Decimal как с обычными числами: складывайте, вычитайте, умножайте, делите и прочее. Можете, миксовать их с целыми числами. Но не рекомендуется миксовать их с float.

>>> x = Decimal('1.2')
>>> y = Decimal('2.3')
>>> x + y
Decimal('3.5')
>>> x - y
Decimal('-1.1')
>>> x * y
Decimal('2. 76')
>>> x / y
Decimal('0.52174')
>>> y // x  # деление нацело
Decimal('1')
>>> y % x  # остаток
Decimal('1.1')
>>> Decimal('2.2') * 2
Decimal('4.4')
>>> Decimal('2.2') - 1
Decimal('1.2')

Дополнительно еще доступны некоторые математические функции:

>>> getcontext().prec = 10  # просто точность задали
>>> Decimal(2).sqrt()  # корень квадратный
Decimal('1.414213562')
>>> Decimal(2).ln()  # логарифм натуральный
Decimal('0.6931471806')
>>> Decimal(100).log10()  # логарифм десятичный
Decimal('2')

А вот чисел π и e из коробки не завезли, потому что не ясно, какая точность вам нужна. Их можно взять из модуля math в виде float или задать вручную до нужной точности или на худой конец вычислить. Аналогично для тригонометрии и специальных функций: либо берите неточные значения из math, либо вычисляйте сами до нужной точности рядами Тейлора или другими методами с помощью примитивных операций. В документации есть примеры вычисления констант и функций.

Кстати, Decimal можно передавать как аргументы функций, ожидающих float. Тогда они будут преобразованы во float:

>>> math.sin(Decimal(1))
0.8414709848078965

Метод quantize округляет число до фиксированной экспоненты, полезно для финансовых операций, когда нужно округлить копейки (центы). Первый аргумент – Decimal – что-то вроде шаблона округления. Смотрите примеры:

>>> Decimal('10.4266').quantize(Decimal('.01'), rounding=ROUND_DOWN)
Decimal('10.42')
>>> Decimal('10. 4266').quantize(Decimal('.01'), rounding=ROUND_UP)
Decimal('10.43')
>>> Decimal('10.4266').quantize(Decimal('1.'), rounding=ROUND_UP)
Decimal('11')

Кроме того Decimal можно сравнивать между собой, как обычные числа. Причем допускается сравнивать даже на точное равенство:

>>> x = Decimal('0.1')
>>> x + x + x == Decimal('0.3')
True

Можно сортировать списки Decimal, искать минимум и максимум. А также преобразовывать Decimal обратно в обычные типы int, float, str. Пример из документации:

>>> data = list(map(Decimal, '1. 34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
>>> max(data)
Decimal('9.25')
>>> min(data)
Decimal('0.03')
>>> sorted(data)
[Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),
 Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]
>>> sum(data)
Decimal('19.29')
>>> a, b, c = data[:3]
>>> str(a)
'1.34'
>>> float(a)
1.34
>>> round(a, 1)
Decimal('1.3')
>>> int(a)
1

Но! Не все сторонние библиотеки поддерживают Decimal. Например, не получится использовать его для numpy!

Не все операции над Decimal абсолютно точные, если результат неточен, то возникает сигнал Inexact.

>>> c = getcontext()
>>> c.clear_flags()
>>> Decimal(1) / Decimal(3)
Decimal('0. 3333333333')
>>> c.flags[Inexact]
True

Выбор между Decimal и float – это поиск компромисса с учетом условий конкретной задачи.

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

Примечание: а для целочисленных вычислений может сгодится и простой int, он умеет из коробки длинную математику!

Еще

В этой статье я не осветил полностью вопросы:

  • Сигналы, флаги и ловушки
  • Обзор режимов округления
  • Управление контекстами
  • Контексты и многопоточность

Если сообществу будет интересно, то я продолжу тему. Голосование будет на канале!

Специально для канала @pyway.  Подписывайтесь на мой канал в Телеграм @pyway 👈 

6 823

Что такое float в C#?

1.

Что такое double в C#?

Тип данных double – 64-разрядная переменная с плавающей запятой Тип double — это основной тип данных, который используется для переменных, содержащих числа с дробной частью. Double используется в C, C++, C# и других языках программирования. Он может представлять как дробные, так и целые значения длинной до 15 знаков.

Что такое decimal c#?

В данной совсем короткой статье я бы хотел рассказать про тип данных decimal в C#. … Данный тип данных, в основном, используется в финансовых расчетах. Он имеет разрядность 127 бит, что позволяет ему представлять числа с точностью до 28 десятичных разрядов.

Сколько байтов в long?

Занимает в памяти 4 байта (32 бита). Имеет синоним unsigned long int. long long: представляет целое число в диапазоне от −9 до +9 Занимает в памяти, как правило, 8 байт (64 бита). /span>

Сколько памяти выделяется под bool?

Размер основных типов данных в C++

КатегорияТипМинимальный размер
Логический тип данныхbool1 байт
Символьный тип данныхchar1 байт
wchar_t1 байт
char16_t2 байта

Сколько памяти выделяется на тип Byte?

В языке имеется 4 целых типа, занимающих 1, 2, 4 и 8 байтов в памяти. Для каждого типаbyte, short, int и long, есть свои естественные области применения. Тип byte — это знаковый 8-битовый тип. Его диапазон — от -128 до 127.

Сколько памяти выделяется под int?

Например, переменная типа int в одном компиляторе может занимать в памяти 16 бит, в другом — 32 бита, в третьем — 8 бит. Все определяет конкретный компилятор. Правда, все стремятся к универсализации, и в основном в большинстве компиляторов тип int, например, занимает 2 байта, а тип char — один. /span>

Сколько памяти выделяется на тип long?

Целый тип long имеет размер 8 байт (64 бита). Минимальное значение -9 максимальное значение 9

Сколько памяти занимает один символ?

256 = 28, то вес 1 символа – 8 бит. Единице в 8 бит присвоили свое название — байт.

Сколько байтов памяти отводится для типа Integer?

Тип INTEGER (целый). Этот тип представляет множество целых чисел диапазона от -32768 до 32767. В памяти ЭВМ под целое число отводится два байта (16 бит).

Сколько байтов в int?

Для 16-разрядных операционных систем — этот тип (int) составляет 2 байта и совпадает с типом short int (можно использовать как short, опуская слово int), для 32-разрядных операционных систем он будет равен 4 байтам и совпадает с длинным целым long int (можно использовать как long, опуская слово int), и в этом случае …

В чем разница между int и long int?

Тип long не «занимает в памяти 4 байта». Он занимает как минимум 32 бита, т. е. … Тип int занимает как минимум 16 бит, ибо имеет диапазон как минимум [−32767, +32767] (как вы сами заметили)./span>

Что означает int в Python?

В языке программирования Python встроенная функция int() возвращает целое число в десятичной системе счисления (класс int). Если вызвать функцию int() без аргументов, она вернет 0. … Попытка преобразовать строку, содержащую вещественное число, в целое число с помощью функции int() вызывает ошибку.

Что такое int в программировании?

Int, сокращение от integer, является фундаментальным типом переменной, встроенным в компилятор и используемым для определения числовых переменных, содержащих целые числа. Другие типы данных включают float и double . C, C ++, C # и многие другие языки программирования распознают int как тип данных./span>

Каков смысл слова int?

Ответ: int — это ЦЕЛОЕ. Это основной тип данных для хранения чисел. Один из самых простых и распространенных языков программирования./span>

Для чего нужен int?

int (integer) — целочисленный тип данных. Используется для объявления переменных в программе. … Например, в Pascal объявление переменных выглядит так: var a, b, c:integer; А в C++ объявление переменных будет выглядеть так: int a, b, c; Вроде бы всё!/span>

Что такое int в C#?

int: хранит целое число от -до и занимает 4 байта. Представлен системным типом System. Int32 ./span>

Сколько байтов в 32 битного целого числа?

Теперь я постараюсь ответить на вопросы : 1.) означает ли это, что мы можем отправить 4 числа (длиной 8 бит/байт каждое) для 32 бит? Или комбинация 8-битных (байт), 32битных (4 байта) и т.

Для чего нужен язык программирования C++?

C++ используется во всех сферах деятельности программирования: от высоконагруженных систем до программирования микроконтроллеров. На С++ можно написать как web-сервер, так и игры, любые компьютерные программы, компоненты и так далее.

Где используется язык с?

Си обычно используется в довольно специфичных и сложных задачах, потому что более лёгкие задачи проще сделать с помощью высокоуровневых языков….Информационная безопасность

  • Использование уязвимостей: переполнения буфера, двойные удаления (повреждения кучи).
  • Инъекция (сокрытие) кода. …
  • Перехват (hooking).

Чем питон так хорош?

Python это язык программирования общего назначения, нацеленный в первую очередь наповышение продуктивности самого программиста, нежели кода, который он пишет. … За счёт простоты кода, дальнейшее сопровождение программ, написанных на Python, становится легче и приятнее по сравнению с Java или C++.

  • © QuestionS
  • 2020-2022

Основные типы — Kotlin

В Kotlin всё является объектом, в том смысле, что пользователь может вызвать функцию или получить доступ к свойству любой переменной. Некоторые типы являются встроенными, т.к. их реализация оптимизирована, хотя для пользователя они выглядят как обычные классы. В данном разделе описываются основные типы: числа, логические переменные, символы, строки и массивы.

Числа

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

В Kotlin есть набор встроенных типов, которые представляют числа. Для целых чисел существует четыре типа с разными размерами и, следовательно, разными диапазонами значений.

ТипРазмер (биты)Минимальное значениеМаксимальное значение
Byte8-128127
Short16-3276832767
Int32-2,147,483,648 (-231)2,147,483,647 (231 — 1)
Long64-9,223,372,036,854,775,808 (-263)9,223,372,036,854,775,807 (263 — 1)

Все переменные, инициализированные целыми значениями, не превышающими максимальное значение Int, имеют предполагаемый тип Int. Если начальное значение превышает это значение, то тип Long. Чтобы явно указать тип Long, добавьте после значения L.

val one = 1 // Int
val threeBillion = 3000000000 // Long
val oneLong = 1L // Long
val oneByte: Byte = 1

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

Для действительных чисел в Kotlin есть типы с плавающей точкой Float и Double. Согласно стандарту IEEE 754, типы с плавающей точкой различаются своим десятичным разрядом, то есть количеством десятичных цифр, которые они могут хранить. С точки зрения IEEE 754 Float является одинарно точным, а Double обеспечивает двойную точность.

ТипРазмер (биты)Значимые битыБиты экспонентыРазряды
Float322486-7
Double64531115-16

Вы можете инициализировать переменные Double и Float числами, имеющими дробную часть. Она должна быть отделена от целой части точкой (.). Для переменных, инициализированных дробными числами, компилятор автоматически определяет тип Double.

val pi = 3.14 // Double
// val one: Double = 1 // Ошибка: несоответствие типов
val oneDouble = 1.0 // Double

Чтобы явно указать тип Float, добавьте после значения f или F. Если такое значение содержит более 6-7 разрядов, оно будет округлено.

val e = 2.7182818284 // Double
val eFloat = 2.7182818284f // Float, фактическое значение 2.7182817

Обратите внимание, что в отличие от некоторых других языков, в Kotlin нет неявных преобразований для чисел. Например, функция с Double параметром может вызываться только для Double, но не для Float, Int или других числовых значений.

fun main() {
    fun printDouble(d: Double) { print(d) }
    val i = 1    
    val d = 1.0
    val f = 1.0f 
    printDouble(d)
//  printDouble(i) // Ошибка: несоответствие типов
//  printDouble(f) // Ошибка: несоответствие типов
}

Чтобы преобразовать числовые значения в различные типы, используйте Явные преобразования.

Символьные постоянные

В языке Kotlin присутствуют следующие виды символьных постоянных (констант) для целых значений:

  • Десятичные числа: 123
    • Тип Long обозначается заглавной L: 123L
  • Шестнадцатеричные числа: 0x0F
  • Двоичные числа: 0b00001011

ВНИМАНИЕ: Восьмеричные литералы не поддерживаются.

Также Kotlin поддерживает числа с плавающей запятой:

  • Тип Double по умолчанию: 123.5, 123.5e10
  • Тип Float обозначается с помощью f или F: 123.5f

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

val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

Представление чисел в JVM

Обычно платформа JVM хранит числа в виде примитивных типов: int, double и так далее. Если же вам необходима ссылка, которая может принимать значение null (например, Int?), то используйте обёртки. В этих случаях числа помещаются в Java классы как Integer, Double и так далее.

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

val a: Int = 100
val boxedA: Int? = a
val anotherBoxedA: Int? = a
val b: Int = 10000
val boxedB: Int? = b
val anotherBoxedB: Int? = b
println(boxedA === anotherBoxedA) // true
println(boxedB === anotherBoxedB) // false

Все nullable-ссылки на a на самом деле являются одним и тем же объектом из-за оптимизации памяти, которую JVM применяет к Integer между «-128» и «127». Но b больше этих значений, поэтому ссылки на b являются разными объектами.

Однако, равенство по значению сохраняется.

val b: Int = 10000
println(b == b) // Prints 'true'
val boxedB: Int? = b
val anotherBoxedB: Int? = b
println(boxedB == anotherBoxedB) // Prints 'true'

Явные преобразования

Из-за разницы в представлениях меньшие типы не являются подтипами бОльших типов. В противном случае возникли бы сложности.

// Возможный код, который на самом деле не скомпилируется:
val a: Int? = 1 // "Обёрнутый" Int (java.lang.Integer)
val b: Long? = a // неявное преобразование возвращает "обёрнутый" Long (java.lang.Long)
print(b == a) // Нежданчик! Данное выражение выведет "false" т. к. метод equals() типа Long предполагает, что вторая часть выражения также имеет тип Long

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

Как следствие, неявное преобразование меньших типов в большие НЕ происходит. Это значит, что мы не можем присвоить значение типа Byte переменной типа Int без явного преобразования.

val b: Byte = 1 // всё хорошо, литералы проверяются статически
// val i: Int = b // ОШИБКА
val i1: Int = b.toInt()

Каждый численный тип поддерживает следующие преобразования:

  • toByte(): Byte
  • toShort(): Short
  • toInt(): Int
  • toLong(): Long
  • toFloat(): Float
  • toDouble(): Double
  • toChar(): Char

Часто необходимости в явных преобразованиях нет, поскольку тип выводится из контекста, а арифметические действия перегружаются для подходящих преобразований.

val l = 1L + 3 // Long + Int => Long

Операции

Котлин поддерживает стандартный набор арифметических операций над числами: +, -, *, /, %. Они объявляются членами соответствующих классов.

println(1 + 2)
println(2_500_000_000L - 1L)
println(3.14 * 2.71)
println(10.0 / 3)

Вы также можете переопределить эти операторы для пользовательских классов. См. Перегрузка операторов для деталей.

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

Деление целых чисел всегда возвращает целое число. Любая дробная часть отбрасывается.

val x = 5 / 2
// println(x == 2.5) // ОШИБКА: Оператор '==' не может быть применен к 'Int' и 'Double'
println(x == 2) // true

Это справедливо для деления любых двух целочисленных типов.

val x = 5L / 2
println(x == 2L) // true

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

val x = 5 / 2.toDouble()
println(x == 2. 5) // true
Побитовые операции

Kotlin поддерживает обычный набор побитовых операций над целыми числами. Они работают на двоичном уровне непосредственно с битовыми представлениями чисел. Побитовые операции представлены функциями, которые могут быть вызваны в инфиксной форме. Они могут быть применены только к Int и Long.

val x = (1 shl 2) and 0x000FF000

Ниже приведён полный список битовых операций:

  • shl(bits) – сдвиг влево с учётом знака (<< в Java)
  • shr(bits) – сдвиг вправо с учётом знака (>> в Java)
  • ushr(bits) – сдвиг вправо без учёта знака (>>> в Java)
  • and(bits) – побитовое И
  • or(bits) – побитовое ИЛИ
  • xor(bits) – побитовое исключающее ИЛИ
  • inv() – побитовое отрицание

Сравнение чисел с плавающей точкой

В этом разделе обсуждаются следующие операции над числами с плавающей запятой:

  • Проверки на равенство: a == b и a != b
  • Операторы сравнения: a < b, a > b, a <= b, a >= b
  • Создание диапазона и проверка диапазона: a. .b, x in a..b, x !in a..b

Когда статически известно, что операнды a и b являются Float или Double или их аналогами с nullable-значением (тип объявлен или является результатом умного приведения), операции с числами и диапазоном, который они образуют, соответствуют стандарту IEEE 754 для арифметики с плавающей точкой.

Однако для поддержки общих вариантов использования и обеспечения полного упорядочивания, когда операнды статически не объявлены как числа с плавающей запятой (например, Any, Comparable<...>, параметр типа), операции используют реализации equals и compareTo для Float и Double, которые не согласуются со стандартом, так что:

  • NaN считается равным самому себе
  • NaN считается больше, чем любой другой элемент, включая «POSITIVE_INFINITY»
  • -0. 0 считается меньше, чем 0.0

Целые беззнаковые числа

В дополнение к целочисленным типам, в Kotlin есть следующие типы целых беззнаковых чисел:

  • UByte: беззнаковое 8-битное целое число, в диапазоне от 0 до 255
  • UShort: беззнаковое 16-битное целое число, в диапазоне от 0 до 65535
  • UInt: беззнаковое 32-битное целое число, в диапазоне от 0 до 232 — 1
  • ULong: беззнаковое 64-битное целое число, в диапазоне от 0 до 264 — 1

Беззнаковые типы поддерживают большинство операций своих знаковых аналогов.

Изменение типа с беззнакового типа на его знаковый аналог (и наоборот) является двоично несовместимым изменением.

Беззнаковые массивы и диапазоны

Беззнаковые массивы и операции над ними находятся в стадии бета-тестирования. Они могут быть несовместимо изменены в любое время.

Как и в случае с примитивами, каждому типу без знака соответствует тип массивов знаковых типов:

  • UByteArray: массив беззнаковых byte
  • UShortArray: массив беззнаковых short
  • UIntArray: массив беззнаковых int
  • ULongArray: массив беззнаковых long

Как и целочисленные массивы со знаком, такие массивы предоставляют API, аналогичный классу Array, без дополнительных затрат на оборачивание.

При использовании массивов без знака вы получите предупреждение, что эта функция еще не стабильна. Чтобы удалить предупреждение используйте аннотацию @ExperimentalUnsignedTypes. Вам решать, должны ли ваши пользователи явно соглашаться на использование вашего API, но имейте в виду, что беззнаковый массив не является стабильной функцией, поэтому API, который он использует, может быть нарушен изменениями в языке. Узнайте больше о требованиях регистрации.

Диапазоны и прогрессии поддерживаются для UInt и ULong классами UIntRange,UIntProgression, ULongRange и ULongProgression. Вместе с целочисленными беззнаковыми типами эти классы стабильны.

Литералы

Чтобы целые беззнаковые числа было легче использовать, в Kotlin можно помечать целочисленный литерал суффиксом, указывающим на определенный беззнаковый тип (аналогично Float или Long):

  • u и U помечают беззнаковые литералы. Точный тип определяется на основе ожидаемого типа. Если ожидаемый тип не указан, компилятор будет использовать UInt или ULong в зависимости от размера литерала.
val b: UByte = 1u  // UByte, есть ожидаемый тип
val s: UShort = 1u // UShort, есть ожидаемый тип
val l: ULong = 1u  // ULong, есть ожидаемый тип
val a1 = 42u // UInt: ожидаемого типа нет, константе подходит тип UInt
val a2 = 0xFFFF_FFFF_FFFFu // ULong: ожидаемого типа нет, тип UInt не подходит константе
  • uL and UL явно помечают литерал как unsigned long.
val a = 1UL // ULong, даже несмотря на то, что ожидаемого типа нет и константа вписывается в UInt
Дальнейшее обсуждение

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

Логический тип

Тип Boolean представляет логический тип данных и принимает два значения: true и false.

При необходимости использования nullable-ссылок логические переменные оборачиваются Boolean?.

Встроенные действия над логическими переменными включают:

  • || – ленивое логическое ИЛИ
  • && – ленивое логическое И
  • ! – отрицание
val myTrue: Boolean = true
val myFalse: Boolean = false
val boolNull: Boolean? = null
println(myTrue || myFalse)
println(myTrue && myFalse)
println(!myTrue)

В JVM: nullable-ссылки на логические объекты заключены в рамки аналогично числам.

Символы

Символы в Kotlin представлены типом Char. Символьные литералы заключаются в одинарные кавычки: '1'.

Специальные символы начинаются с обратного слеша \. Поддерживаются следующие escape-последовательности: \t, \b, \n, \r, \', \", \\ и \$.

Для кодирования любого другого символа используйте синтаксис escape-последовательности Юникода: '\uFF00'.

val aChar: Char = 'a'
println(aChar)
println('\n') // выводит дополнительный символ новой строки
println('\uFF00')

Если значение символьной переменной – цифра, её можно явно преобразовать в Int с помощью функции digitToInt().

В JVM: Подобно числам, символы оборачиваются при необходимости использования nullable-ссылки. При использовании обёрток тождественность (равенство по ссылке) не сохраняется.

Строки

Строки в Kotlin представлены типом String. Как правило, строка представляет собой последовательность символов в двойных кавычках (").

val str = "abcd 123"

Строки состоят из символов, которые могут быть получены по порядковому номеру: s[i]. Проход по строке выполняется циклом for.

for (c in str) {
    println(c)
}

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

val str = "abcd"
println(str.uppercase()) // Создается и выводится новый объект String
println(str) // исходная строка остается прежней

Для объединения строк используется оператор +. Это работает и для объединения строк с другими типами, если первый элемент в выражении является строкой.

val s = "abc" + 1
println(s + "def") // abc1def

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

Строковые литералы

В Kotlin представлены два типа строковых литералов:

  • экронированные строки с экранированными символами
  • обычные строки, которые могут содержать символы новой строки и произвольный текст

Вот пример экранированной строки:

val s = "Hello, world!\n"

Экранирование выполняется общепринятым способом, а именно с помощью обратного слеша (\). Список поддерживаемых escape-последовательностей см. в разделе Символы выше.

Обычная строка выделена тройной кавычкой ("""), не содержит экранированных символов, но может содержать символы новой строки и любые другие символы:

val text = """
  for (c in "foo")
    print(c)
"""

Чтобы удалить пробелы в начале обычных строк, используйте функцию trimMargin().

val text = """
    |Tell me and I forget.
    |Teach me and I remember.
    |Involve me and I learn.
    |(Benjamin Franklin)
    """.trimMargin()

По умолчанию | используется в качестве префикса поля, но вы можете выбрать другой символ и передать его в качестве параметра, например, trimMargin(">").

Строковые шаблоны

Строки могут содержать шаблонные выражения, т.е. участки кода, которые выполняются, а полученный результат встраивается в строку. Шаблон начинается со знака доллара ($) и состоит либо из простого имени (например, переменной),

val i = 10
println("i = $i") // выведет "i = 10"

либо из произвольного выражения в фигурных скобках.

val s = "abc"
println("$s.length is ${s.length}") // выведет "abc.length is 3"

Шаблоны поддерживаются как в обычных, так и в экранированных строках. При необходимости вставить символ $ в обычную строку (такие строки не поддерживают экранирование обратным слешом) перед любым символом, который разрешен в качестве начала идентификатора, используйте следующий синтаксис:

val price = """
${'$'}_9.99
"""

Массивы

Массивы в Kotlin представлены классом Array, обладающим функциями get и set (которые обозначаются [] согласно соглашению о перегрузке операторов), и свойством size, а также несколькими полезными встроенными функциями.

class Array<T> private constructor() {
    val size: Int
    operator fun get(index: Int): T
    operator fun set(index: Int, value: T): Unit
    operator fun iterator(): Iterator<T>
    // ...
}

Для создания массива используйте функцию arrayOf(), которой в качестве аргумента передаются элементы массива, т. е. выполнение arrayOf(1, 2, 3) создаёт массив [1, 2, 3]. С другой стороны функция arrayOfNulls() может быть использована для создания массива заданного размера, заполненного значениями null.

Также для создания массива можно использовать фабричную функцию, которая принимает размер массива и функцию, возвращающую начальное значение каждого элемента по его индексу.

// создаёт массив типа Array<String> со значениями ["0", "1", "4", "9", "16"]
val asc = Array(5) { i -> (i * i).toString() }
asc.forEach { println(it) }

Как отмечено выше, оператор [] используется вместо вызовов встроенных функций get() и set().

Обратите внимание: в отличие от Java массивы в Kotlin являются инвариантными. Это значит, что Kotlin запрещает нам присваивать массив Array<String> переменной типа Array<Any>, предотвращая таким образом возможный отказ во время исполнения (хотя вы можете использовать Array<out Any>, см. Проекции типов).

Массивы примитивных типов

Также в Kotlin есть особые классы для представления массивов примитивных типов без дополнительных затрат на оборачивание: ByteArray, ShortArray, IntArray и т.д. Данные классы не наследуют класс Array, хотя и обладают тем же набором методов и свойств. У каждого из них есть соответствующая фабричная функция:

val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
// int массив, размером 5 со значениями [0, 0, 0, 0, 0]
val arr = IntArray(5)
// инициализация элементов массива константой
// int массив, размером 5 со значениями [42, 42, 42, 42, 42]
val arr = IntArray(5) { 42 }
// инициализация элементов массива лямбда-выражением
// int массив, размером 5 со значениями [0, 1, 2, 3, 4] (элементы инициализированы своим индексом)
var arr = IntArray(5) { it * 1 } 

Разница между float и double в C/C++

Table of Contents

Введение

Числа повсюду — на ценниках, счетах, книгах, номерных знаках, телефонах, даже на наших клавиатурах. А вы когда-нибудь задумывались, как компьютеры понимают и хранят эти числа? Да, вы правы, они хранят в них все в нулях и единицах.

Но люди более изобретательны и знают больше, чем просто нули и единицы. Таким образом, некоторые великие инженеры изобрели языки программирования. Основная цель программирования — передать алгоритм машине (компьютеру), т. е. заставить компьютер что-то делать.

Существует около 700 языков программирования , и каждый из них имеет свой синтаксис, правила и положения.

Хорошо! Но есть одна общая черта; В большинстве языков программирования все основные типы данных являются встроенными. Кроме того, многие языки также предоставляют набор составных типов данных. В настоящее время! Что такое типы данных? Тип данных определяет тип данных , которые может хранить переменная , например целочисленные, с плавающей запятой, символьные и т. д.

Источник изображения: Quora

Сегодня мы собираемся различать типы данных float и double в C/C++. Но прежде чем перейти непосредственно к различиям, давайте сначала поговорим о фундаментальных понятиях, таких как, что такое float и double, требуемое для них хранилище, их точность, преобразование переменной float в double и наоборот.

Что такое тип данных «плавающий»?
  • Тип данных с плавающей запятой используется для хранения действительных чисел или больших чисел с дробным компонентом, например 1,0,14,01,23,45,-21,560,19.1,123456 и т. д. Часть после запятой называется дробной частью.
  • Хорошо, но почему имя «плавающее»?

Десятичное число называется числом с плавающей запятой, потому что мы можем наблюдать выше, что десятичное число поддерживает переменное количество цифр до и после него, что означает, что десятичная точка может плавать между числами. Таким образом, название типа данных float происходит от числа с плавающей запятой.

  • Число с плавающей запятой может храниться в диапазоне от 3,4E-38 до 3,4E+38, т. е. от -3,4 x 10 38   до +3,4 x 10 38 
  •  Синтаксис объявления переменных с плавающей запятой в C и C++ следующий:
  • имя_переменной с плавающей запятой = значение;
  • поплавковый вес = 85,6;

Теперь мы знаем основное определение типа данных float. Давайте перейдем к другим интересным фактам о float.

  • Float — это 32-битное число с плавающей запятой одинарной точности IEEE 754.
  • 1 бит для знака, 8 бит для экспоненты, 23 бита для значения или мантиссы.
  • Размер числа с плавающей запятой составляет 4 байта (32 бита), т. е. переменная с плавающей запятой требует 4 байта памяти компьютера.
  • Число с плавающей запятой имеет 6-значную точность, что означает, что мы можем использовать до 6 цифр после запятой; в противном случае он усекет все после этого. Например, 12.4356716 можно сохранить в переменной, используя тип данных float.

В приведенной ниже программе C++ показана 6-значная точность переменной с плавающей запятой и усеченные цифры после этого.

Что такое «двойной» тип данных?
  • Тип данных double также используется для хранения действительных чисел или больших чисел с дробным компонентом, например -10,231,19,345621.

Так в чем же разница между double и float?

Основное различие между ними заключается в размере и точности.

  • Double может хранить числа в диапазоне от -1,7E+308 до +1,7E+308, то есть от -1,7 x 10 308  до +1,7 x 10 308 
  • Синтаксис для объявления переменных типа double в C и C++ выглядит следующим образом:
    • двойное имя_переменной = значение;
    • двойной вес = 85,6;

Некоторые другие интересные факты о double:

Double — это 64-битное число с плавающей запятой двойной точности стандарта IEEE 754.

  • 1 бит для знака, 11 бит для экспоненты, 52 бита для значения мантиссы.
  • Точность — это общее количество цифр (или значащих цифр) действительного числа.
  • Размер двойной переменной составляет 8 байт (64 бита), т. е. для двойной переменной требуется 8 байтов памяти компьютера.
  • Double имеет 15-значную точность, что означает, что переменная double значима до 15 десятичных цифр, и, следовательно, она будет усекать все после этого. Например, 12.435671123654328 можно сохранить в переменной, используя тип данных double.

Преобразование переменной с плавающей запятой в двойную
  • Число с плавающей запятой занимает 4 байта в памяти и имеет точность 7 цифр.
  • Double занимает в памяти 8 байт и имеет точность 15 цифр.

В коде C++ показано преобразование числа с плавающей запятой в двойное:

Из приведенного выше вывода кода видно, что невозможно добиться большей точности, чем та, что у нас уже есть. Таким образом, если вы приведете переменную с плавающей запятой к типу double, результирующий тип double будет иметь точность только в 6 цифр.

Преобразование переменной типа double в число с плавающей запятой

Преобразование из значения типа double в число с плавающей запятой даст максимально возможное число с плавающей запятой, поскольку значение типа double занимает в памяти 8 байт и имеет точность 15 цифр. Напротив, float занимает половину размера и точности по сравнению с double.

Код C++ показывает двойное преобразование в число с плавающей запятой:

Примечание :

  •   Для приведенных выше кодов используется компилятор MinGW, допускающий точность до 6 цифр. Итак, наши значения переменных были округлены и усечены компилятором до 6 цифр.
  • Точность, поддерживаемая компилятором, меньше реальных цифр числа. Таким образом, последняя цифра округляется, а остальные усекаются.

Функция SetPrecision():

  • Мы можем указать количество десятичных знаков для печати в cout, используя функцию setprecision() в C++.
  • Функция setprecision() определена в заголовочном файле iomanip, что означает манипуляции с вводом/выводом .
  • В приведенном ниже коде C++ показано использование функции setprecision().

Из приведенных выше кодов мы можем сделать следующие выводы:

  • Преобразование из числа с плавающей запятой в двойное число и из числа двойного числа в число с плавающей запятой допустимо, но данные или цифры будут потеряны из-за низкой точности числа с плавающей запятой, если мы преобразуем двойное число в число с плавающей запятой. .
  • Double требует больше места в памяти по сравнению с float. Таким образом, Double дороже, чем float.
  • Как правило, float используется для хранения чисел с плавающей запятой, но Double чаще используется, когда требуется высокая точность, например, в валютах, Sensex и т. д.

Поскольку мы знаем все о float и double, давайте создадим таблица, в которой обсуждаются различия между float и double для быстрого ознакомления.

Таблица различий
FLOAT DOUBLE
Тип данных одинарной точности. Тип данных двойной точности.
Может хранить числа в диапазоне от 3.4E-38 до 3.4E+38, т. е. от -3,4 x 10 38   до +3,4 x 10 38  Double может хранить числа в диапазоне -1,7E от +308 до +1,7E+308, то есть от -1,7 x 10 308 до +1,7 x 10 308
Синтаксис объявления переменной с плавающей запятой: float weight=67,4; Синтаксис объявления типа данных double: Double weight=78,9;
Спецификатор формата для типа данных float: %f Спецификатор формата для типа данных double: %lf
Float — это 32-битный тип данных с плавающей запятой. 1 бит для знака, 8 -бит для экспоненты, 23-бит для значения или мантиссы Double — это 64-битный тип данных с плавающей запятой. 1-бит для знака, 11-бит для экспоненты, 52-бит для значения или мантиссы.
Для переменной с плавающей запятой требуется 4 байта памяти. Для двойной переменной требуется 8 байт памяти. Просто вдвое больше, чем у float.
Число с плавающей запятой имеет 6-значную точность. Double имеет 15-значную точность.
Преобразование из числа с плавающей запятой в число с двойной точностью допустимо, данные не теряются. Преобразование из числа double в число с плавающей запятой также допустимо, но данные теряются.
Плавающие операции экономичны, занимают меньше места в памяти. Double дороже, занимает больше места в памяти
Хорошо использовать число с плавающей запятой, когда точность не требуется. Если требуется высокая точность, рекомендуется использовать double.

Часто задаваемые вопросы

Что такое float и double?


Особенности Float:

1. Float — это тип данных одинарной точности.
2. Число с плавающей запятой имеет 6-значную точность.
3. Float — это 32-битный тип данных с плавающей запятой.
4. Для переменной с плавающей запятой требуется 4 байта памяти.

Особенности Double:

1. Double — это тип данных двойной точности.
2. Double имеет 15-значную точность.
3. Double — это 64-битный тип данных с плавающей запятой.
4. Для переменной double требуется 8 байт памяти. Просто вдвое больше, чем у float.

Число 99,9 с плавающей запятой или двойное?

Числа с плавающей запятой по умолчанию имеют тип double. Следовательно, 99,9 — это двойное число, а не число с плавающей запятой.

Что такое пример двойного типа данных?

Double может хранить числа в диапазоне от -1,7 x 10308 до +1,7 x 10308. Поэтому 1,3 x 1038 также является примером double.

Что лучше: float или double?

Double более точен, чем float, и может хранить 64 бита; удвоить количество битов, которые может хранить число с плавающей запятой. Мы предпочитаем double, а не float, если нам нужна точность до 15 или 16 знаков после запятой; в противном случае мы можем придерживаться float в большинстве приложений, так как double дороже.

Что такое число с плавающей запятой?

Десятичное число называется числом с плавающей запятой, потому что мы знаем, что десятичное число поддерживает переменное количество цифр до и после него, что означает, что десятичная точка может плавать между числами.

Может ли число с плавающей запятой быть отрицательным?

Да, числа с плавающей запятой могут быть положительными или отрицательными.

Является ли значение double быстрее, чем число с плавающей запятой?

Да, операции с числами типа double обычно выполняются быстрее, чем с числами с плавающей запятой, но двойные операции требуют больших затрат памяти.

Ключевые выводы

В этой статье кратко объясняется концепция типов данных float и double в C/C++.

Мы начали с формального определения числа с плавающей запятой, за которым последовали некоторые интересные факты, например, почему оно носит название «плавающая», объем памяти, который он занимает, и значение точности. Затем мы перешли к типу данных double и объяснили его хранение, точность и чем он отличается от типа данных float.

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

В конце создается таблица, в которой обсуждаются различия между float и double для быстрого ознакомления и подведения итогов.

Да! Это конец статьи, но не вашего обучения. «Развивайте страсть к обучению. Если вы это сделаете, вы никогда не перестанете расти». Если вы когда-нибудь почувствуете потребность в экспертном руководстве, чтобы изучить больше концепций, Coding Ninjas всегда будет рядом; ознакомьтесь с нашими курсами DSA, начав бесплатную пробную версию сегодня.

Кроме того, вы можете решить как можно больше задач на нашей платформе CodeStudio, созданной амбициозными и творческими умами, которая предоставляет вам удобные, адаптивные и превосходные онлайн-курсы, практические вопросы, блоги, поддержку наставников, опыт интервью и все, что вам нужно, чтобы стать идеальным кандидатом для компании вашей мечты!

Автор Aanchal Tiwari

Разница между Float и Double

И действительные, и десятичные числа являются числами с плавающей запятой, и в этой статье мы обсудим разницу между числами с плавающей запятой и двойным числом, то есть числом с плавающей запятой и двойным числом. В языки программирования подобно C, C++ и Java, у нас есть два примитивных типа данных, float и double, для представления чисел с плавающей запятой и вещественных постоянных чисел.

Проще говоря, числа с плавающей запятой или вещественные константы — это те числа, которые содержат десятичные точки, например 5,000 и 6,2123.

Поплавок против двойного

В С++ и Java , у нас есть два встроенных типа данных, float и double, для представления всех чисел с плавающей запятой, но всегда возникает путаница в отношении того, какой тип данных выбрать, поскольку оба должны выполнять одну и ту же работу.

В мелкомасштабном программировании мы не увидим никакой разницы между float и double. , но когда мы говорим о науке о данных или научных вычислениях, даже одна точка может иметь огромное значение. Здесь программист должен знать, какой тип данных следует использовать для представления действительного числа.

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

Что такое поплавок?

Float — это тип данных формата с плавающей запятой одинарной точности, который в основном используется для представления чисел с плавающей запятой. Обычно он занимает 32 бита в памяти компьютера при 4 байтах. Целое число может иметь максимальное значение 2 147 483 647, тогда как максимальное значение числа с плавающей точкой может составлять 3,4028235 × 10. 38 . Кроме того, число с плавающей запятой может содержать шесть цифр после запятой.

Что такое двойник?

Двойник — это ИЭЭЭ 754 64-битный формат данных с плавающей запятой двойной точности, который также используется для представления чисел с плавающей запятой. IEEE 754 — это стандартное представление чисел с плавающей запятой в компьютере.

Тип данных double может занимать 8 байт в памяти компьютера и хранить от 15 до 16 чисел после запятой. По сравнению с типом данных float тип double показывает большую точность и занимает больше памяти. Точность означает точность результата.

Float vs Double: прямое сравнение
Параметр Двойной Плавать
Объяснение Это тип данных с плавающей запятой двойной точности. Он используется для представления чисел с плавающей запятой. Float — это тип данных с плавающей запятой одинарной точности, который используется для представления чисел с плавающей запятой.
Память 64-битный 32-битный
Размер 9(38)
Преимущества Это более точно, чем float.
  • Практически все языки программирования имеют тип данных float.
  • Его поддерживают многие библиотеки.

Ключевая разница между двойным и плавающим

Основной причиной использования чисел с плавающей запятой является точность. Часто в арифметических операциях мы сталкиваемся с такими результатами вычислений, где цифры после запятой бесконечны и не могут быть представлены ни одним типом данных.

Например, 2/3 (что бесконечно продолжается до 0,666666…). Для таких бесконечных десятичных цифр типы данных float и double округляют десятичные точки после определенной цифры в большую сторону. Хотя округление таких действительных чисел в большинстве случаев делает за нас задачу, подумайте о научных вычислениях, где одна десятичная разница может иметь огромное влияние на общий результат. В этих случаях нам требуются типы данных, которые имеют большую точность и хранят больше десятичных цифр.

И double, и float не обеспечивают полной точности и аккуратности, но между ними double выходит на первое место с большей точностью. По этой причине C++ также предоставляет тип данных long double для большей точности чисел с плавающей запятой. В следующей таблице представлены память и диапазон значений double и float.

Тип Память (32/64 бита) Диапазон
плавать 4 байта от 1. 2E-38 до 3.4E+38
двойной 8 байт 2.3E-308 до 1.7E+308
длинный двойной 16 байт от 3.4E-4932 до 1.1E+4932

В языках программирования, таких как C и C++, у нас есть возможность объявить переменную с помощью ключевого слова float или double, но в Java он принимает числа с плавающей запятой как тип данных float. В Java мы должны явно привести десятичное число к типу, используя суффикс ‘f’. В противном случае JVM обрабатывает десятичное число как двойное.

//С++
поплавок х=2,2234;
двойной у = 2,34244;
//Ява
поплавок х= 2,343f;
двойной у = 2,3435; 

Когда использовать поплавок?

Обычно мы используем тип данных float с мелкомасштабной программой, где точность точки не имеет большого значения. Он имеет меньший размер и занимает всего 32 бита памяти, что делает его очень быстрым для вычислений. Если вы хотите сделать программу как можно меньше, вам следует использовать тип данных float для чисел с плавающей запятой.

Когда использовать двойной?

При написании кода для высокопроизводительных компьютеров, где потребление оперативной памяти и разрядка аккумулятора не являются основными проблемами, следует использовать тип данных double. Double обеспечивает больший диапазон и точность по сравнению с float. Поэтому, если точность является вашей главной заботой, вам следует использовать тип данных double.

Вывод

Float и double — два самых запутанных типа данных в таких языках программирования, как C, C++, Java. В большинстве случаев не имеет значения, используете ли вы float или double. В наши дни нам не нужно беспокоиться о размере переменной данных, потому что в настоящее время у нас есть высокопроизводительные процессоры с несколькими ядрами.

С другой стороны, точность может быть основной причиной изменения типа данных с float на double. В других языках программирования, таких как JavaScript, PHP и Python, у нас нет специальных типов данных для чисел с плавающей запятой. Там мы получаем только тип данных float.

Люди также читают:

  • Стек против кучи
  • Союз против структуры
  • Разница между массивом и списком
  • Умножение матриц в C
  • Структура данных Python
  • Что такое наука о данных?
  • C Вопросы для интервью
  • Лучшие книги C
  • Локальная переменная против глобальной переменной
  • Стек против кучи
  • Массив против списка

Разница между Float и Double

Последнее обновление: 30 августа 2022 г. / By Piyush Yadav / Проверка фактов / 5 минут

В компьютерах имеется большое количество типов данных, и они широко используются для хранения различных значений. Float и double — два популярных типа данных, которые используются для хранения больших десятичных значений.

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

Float vs Double

Основное различие между float и double заключается в том, что float — это один из простейших типов данных, которым могут управлять компиляторы, и который очень полезен для инициирования производительности обработки, тогда как double — широко используемый тип данных. тип данных, который используется для обозначения значения или числа переменной.

Тип данных float — один из самых точных типов данных в компьютерном программировании, обеспечивающий гораздо большую точность, чем любой другой тип данных. Float имеет 32-битную точность, что является высоким, но намного меньшим, чем точность, предлагаемая типом данных double.

Тип данных double является наиболее точным и точным в компьютерном программировании, предлагая 64-битную точность, самую высокую среди всех типов данных.

Double сравнительно чаще используется отдельными лицами и компаниями по сравнению с float. Double может легко настроить от 15 до 16 цифр.

Таблица сравнения между Float и Double
Параметры сравнения Float Double
. Поплавок имеет 32 бита памяти. Double имеет сравнительно больше памяти по сравнению с float. Тип данных double имеет 64 бита памяти.
Значение От 1.4e-045 до 3.4e+038 — это диапазон, в котором находится значение float. От 4.9e-324 до 1.8e+308 — это диапазон, в котором находится значение переменной, использующей тип данных double.
Распределение битов Распределение:-
Sing бит- 1 бит
экспонента- 8 бит
мантисса- 23 бита 52 бита
Десятичные разрядыПоплавок имеет десятичные разряды до 6 разрядов. Double имеет до 15 знаков после запятой.
Величина точности Тип данных float указывает одинарную и индивидуальную точность или точность, следовательно, он сравнительно менее точен, чем double. Тип данных double указывает на двойную точность и точность, следовательно, он сравнительно более точен, чем тип данных с плавающей запятой.

Что такое поплавок?

Тип данных с плавающей запятой — один из наиболее широко используемых типов данных почти во всех языках программирования, будь то Java, Python, C и C++.

Число с плавающей запятой имеет одинарную точность и точность и имеет память в 32 бита и 4 байта, что вполне достаточно для хранения любого типа значения.

Скорость регулирования переменных с плавающей запятой оценивается с точки зрения понятия, известного как FLOPS.

Число с плавающей запятой — лучший тип данных в программировании, когда речь идет о скорости. Все люди, которые предпочитают скорость точности, предпочитают использовать float, а затем использовать double в качестве второго варианта.

Число с плавающей запятой пользуется большим спросом, когда число десятичных знаков, которым обладает переменная, точно определено. Одним из основных недостатков Java является то, что тип данных по умолчанию для чисел с плавающей запятой — double, а не float.

Поскольку тип данных по умолчанию, используемый в java для чисел с плавающей запятой, — double, у float должен быть свой суффикс. Для сохранения значения в переменной с плавающей запятой необходимо добавить суффикс «F» к значению.

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

Он имеет 32-битную точность и достаточно приличную точность.

Что такое двойной?

Тип данных double является наиболее популярным почти во всех языках программирования, таких как Java, C, C++ и Python. Точность и аккуратность, которые он предлагает, чрезвычайно высоки.

Обеспечивает точность до 15 и 16 знаков после запятой. Он имеет 64-битную точность, что в 2 раза больше, чем тип данных с плавающей запятой.

Значение по умолчанию для типа данных double — 0.0d. Одним из идентификаторов, по которым известен тип данных, является его класс-оболочка, классом-оболочкой для double в языке Java является java. яз.

Двойной. Одним из основных недостатков преобразования типа данных double в тип данных с плавающей запятой является потеря данных, происходящая во время этого преобразования.

Добавление суффикса необязательно в случае типа данных double, но если кто-то хочет это сделать, он должен использовать D или d. Многие люди предпочитают использовать double вместо float, если в коде нет ограничений по памяти и пространству.

Люди, занимающиеся веб-разработкой и программированием, всегда предпочитают использовать double, поскольку он в значительной степени ориентирован на веб-разработку. В Java double является типом данных по умолчанию для всех переменных и чисел с плавающей запятой.

Основные различия между Float и Double
  1. Float имеет сравнительно меньший объем памяти по сравнению с double. Float имеет 32 бита памяти, тогда как double имеет 64 бита памяти.
  2. Число с плавающей запятой принимает десятичные дроби до 6 знаков. С другой стороны, double принимает десятичные дроби до 15 или 16 пунктов.
  3. Класс-оболочка float в Java — java. яз. Float, тогда как класс-оболочка double в Java — это java. яз.Double.
  4. Когда переменная с типом данных float преобразуется в тип данных double, потери данных нет, тогда как потеря данных происходит в случае преобразования типа double в float.
  5. Точность, предлагаемая float, ниже по сравнению с типом данных double.

Заключение

В компьютерном программировании существует множество типов данных, таких как int, float, double. Double и float используются для хранения чисел с плавающей запятой, поэтому играют очень важную роль в коде или программе.

Точность, хранение и точность обоих типов данных различаются и, следовательно, путают пользователей, какой тип данных они должны предпочесть для хранения значений с плавающей запятой.

Большинство людей предпочитают использовать тип данных типа double вместо float, поскольку возможности и преимущества, которые дает тип данных double, гораздо больше, чем у float или любого другого подобного типа данных.

Ссылки
  1. https://www.sciencedirect.com/science/article/pii/01678191947
  2. https://link.springer.com/chapter/10.1007/3-5940-485199-45191-

    Найдите в Google запрос «Спроси любую разницу». Оцените этот пост!

    [Всего: 0]

    Один запрос?

    Я приложил столько усилий, чтобы написать этот пост в блоге, чтобы он был вам полезен. Это будет очень полезно для меня, если вы подумаете о том, чтобы поделиться им в социальных сетях или со своими друзьями/семьей. SHARING IS ♥️

    Содержание

    сообщите об этом объявлении

    Java: Float vs Double | 4 Основные отличия (и когда использовать?)

    Каждый язык программирования имеет дело с широким спектром типов данных. В Java числа с плавающей запятой представляются с помощью двух типов данных: float и double. Если вы хотите глубже погрузиться в язык Java и узнать некоторые важные концепции типов данных, то эта статья определенно для вас. Наша статья о различиях между float и double в Java должна помочь вам узнать об основных концепциях этих двух типов данных. Мы также включили сравнительную таблицу для float и double в программировании на Java.

    Что такое Float & Double?

    В целом данные можно разделить на два основных типа: числовые и нечисловые данные. К нечисловым данным относятся символы и строки. Числовые данные состоят из целых чисел и чисел с плавающей запятой. Целые числа, как и следует из названия, состоят только из целой части — дробь здесь не используется. Числа с плавающей запятой, с другой стороны, поставляются с дробной частью и целой частью из коробки. В зависимости от размера требуемых данных целым числам назначаются разные типы данных, которые можно использовать в зависимости от требований. Точно так же, в зависимости от размера числа — особенно дробной части: числам с плавающей запятой также могут быть назначены разные типы данных. Float и Double используются для представления чисел с плавающей запятой.

    Float и double — это два типа данных, которые Java выделяет для работы с числами с плавающей запятой. Оба типа данных примитивны по своей природе: это означает, что их определения включены как часть самого языка (или, точнее, пакета java.lang — импорта по умолчанию для любой программы Java). Почему именно два типа данных выделяются для выполнения одной и той же работы? Ну, они сильно различаются по своему охвату и удобству использования в различных сценариях.

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

    4 различия ч/б Float и Double в Java

    Итак, вот 4 основных различия между float и double в Java:

    1. Размер: Float имеет размер 32 бита, а double имеет размер 64 бита. . Следовательно, double может обрабатывать гораздо большие дробные числа, чем float. Отличаются они выделением битов для представления числа. И float, и double используют 1 бит для представления знака числа. Однако они отличаются распределением битов для мантиссы и экспоненты. Float выделяет 23 бита для мантиссы, а double выделяет 52 бита для мантиссы. Точно так же float использует 7 бит для экспоненты, а double выделяет 11 бит для экспоненты.
    2. Точность: Число с плавающей запятой допускает только 7-битную точность. Double выделяет почти вдвое больше битов для экспоненты, что позволяет обрабатывать до 15 бит точности. Чрезвычайно малый размер экспоненты означает некоторое сжатие данных при работе с числом с плавающей запятой. Сжатие данных неизбежно означает потерю некоторых битов. Эта потеря битов с конца числа очень заметна при использовании числа с плавающей запятой. Количество потерянных битов намного меньше при использовании double из-за большого количества битов, выделенных для экспоненты.
    3. По умолчанию: Double — тип данных по умолчанию, используемый Java для работы с дробными числами. Чтобы заставить Java использовать тип данных с плавающей запятой, к числу должен быть добавлен символ «f» или «F». Это также можно сделать, принудительно приведя число к типу с плавающей запятой, добавив префикс (с плавающей запятой) к числу во время инициализации.
    4. Класс оболочки: И float, и double являются примитивными типами. Это означает, что у них будут свои классы-оболочки, позволяющие использовать их в качестве типов объектов. Класс-оболочка для float — java.lang.Float, а класс-оболочка для double — java.lang.Double.

    Сравнение Float и Double в Java

    Следующая инфографика суммирует различия между float и double в Java:

    Когда использовать Float и Double в Java?

    Плавающая обычно используется, когда скорость важнее точности. Хотя наши повседневные программы не требуют больших вычислений, в практических приложениях эта разница становится весьма существенной. Кроме того, число с плавающей запятой обычно используется, когда известно количество требуемых десятичных цифр. Double используется почти во всех других случаях: особенно когда точность очень важна. Имейте в виду, что Java требует использования double в качестве типа данных по умолчанию для работы с числами с плавающей запятой.

     

    Заключение

    Float и double — это два типа данных, выделенных в Java для работы с числами с плавающей запятой (или дробными числами). Хотя они могут показаться похожими, на самом деле они сильно отличаются друг от друга. Вам нужна помощь в понимании типов float и double в Java? Наша интерактивная справка по Java экспертов доступны. Наша статья о ключевых различиях между этими двумя типами данных суммирует Float и Double в программировании на Java.

    c++ — Когда вы используете float и когда вы используете double

    спросил

    Изменено 9 месяцев назад

    Просмотрено 286 тысяч раз

    Часто, по моему опыту программирования, мне приходится принимать решение, следует ли мне использовать с плавающей запятой или двойное для моих действительных чисел. Иногда я выбираю float , иногда double , но на самом деле это более субъективно. Если бы мне пришлось защищать свое решение, я бы, вероятно, не привел веских причин.

    Когда вы используете float и когда вы используете double ? Вы всегда используете double , только когда присутствуют ограничения памяти, вы выбираете с плавающей запятой ? Или вы всегда используете с плавающей запятой , если требование точности не требует, чтобы вы использовали double ? Существуют ли существенные различия в вычислительной сложности основных арифметических операций между float и double ? Каковы плюсы и минусы использования float или double ? А вы использовали long double ?

    • c++
    • c
    • числа с плавающей запятой
    • числа

    9

    Выбор по умолчанию для типа с плавающей запятой должен быть double . Это также тип, который вы получаете с литералами с плавающей запятой без суффикса или (в C) стандартными функциями, которые работают с числами с плавающей запятой (например, exp , sin и т. д.).

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

    long double можно использовать, если вам требуется больший диапазон или точность, чем double , и если он обеспечивает это на вашей целевой платформе.

    Таким образом, float и long double должны быть зарезервированы для использования специалистами, а double — для «повседневного» использования.

    12

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

    Основные причины, по которым я могу использовать float:

    1. Вы храните большие массивы чисел и вам нужно уменьшить потребление памяти программой.
    2. Вы нацелены на систему, которая изначально не поддерживает числа с плавающей запятой двойной точности. До недавнего времени многие видеокарты поддерживали только одинарную точность. плавающие точки. Я уверен, что есть много маломощных и встроенные процессоры с ограниченной поддержкой плавающей запятой.
    3. Вы нацелены на оборудование, где одинарная точность работает быстрее. чем двойная точность, и ваше приложение интенсивно использует арифметика с плавающей запятой. На современных процессорах Intel я верю всем Вычисления с плавающей запятой выполняются с двойной точностью, поэтому вы ничего здесь не заработаешь.
    4. Вы выполняете низкоуровневую оптимизацию, например, используя специальные инструкции ЦП, которые работают с несколькими числа за раз.

    Так что, по сути, лучше использовать double, если у вас нет аппаратных ограничений или если анализ не показал, что хранение чисел с двойной точностью значительно увеличивает использование памяти.

    5

    Используйте дважды для всех ваших расчетов и временных переменных. Используйте float , когда вам нужно поддерживать массив чисел — float[] (если точность достаточна), и вы имеете дело с более чем десятками тысяч чисел float .

    Многие/большинство математических функций или операторов преобразуют/возвращают double , и вы не хотите возвращать числа обратно к float для каких-либо промежуточных шагов.

    Если у вас есть ввод 100 000 чисел из файла или потока и вам нужно их отсортировать, поместите числа в с плавающей запятой[] .

    Некоторые платформы (ARM Cortex-M2, Cortex-M4 и т.д.) не поддерживают double (Всегда можно проверить в справочнике к вашему процессору. Если при компиляции нет предупреждений или ошибок, это не значит, что код оптимален. двойной можно эмулировать.). Вот почему вам может понадобиться придерживаться int или float .

    Если это не так, я бы использовал double .

    Вы можете ознакомиться со знаменитой статьей Д. Голдберга («Что должен знать каждый компьютерщик об арифметике с плавающей запятой»). Вы должны дважды подумать, прежде чем использовать арифметику с плавающей запятой. Есть довольно большая вероятность, что они вообще не нужны в вашей конкретной ситуации.

    http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf

    3

    Для реальных проблем порог выборки ваших данных важен при ответе на этот вопрос. Точно так же важен и уровень шума. Если какой-либо из них превышен выбранным вами типом данных, повышение точности не принесет никакой пользы.

    Большинство реальных сэмплеров ограничены 24-битными ЦАП. Предполагая, что 32-битная точность в реальных расчетах должна быть адекватной, где мантиссы составляют 24-битную точность.

    Двойная точность достигается за счет удвоения памяти. Таким образом, ограничение использования двойных чисел над числами с плавающей запятой может резко сократить объем памяти/пропускную способность работающих приложений.

    Очень простое правило: вы используете double, если только вы лично не можете привести аргументы, которые вы можете защитить, почему вы должны использовать float.

    Следовательно, если вы спросите «должен ли я использовать double или float», ответ будет «использовать double».

    Выбор переменной для использования между float и double зависит от точности требуемых данных. Если требуется, чтобы ответ имел незначительное отличие от фактического ответа, требуемое количество знаков после запятой будет большим, поэтому будет требоваться использование двойного числа. Float отрежет часть десятичных знаков, что снизит точность.

    1

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

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

    Стандарт C99 говорит следующее:

    Существует три типа чисел с плавающей запятой: float, double и long double. Тип double обеспечивает по меньшей мере такую ​​же точность, как и float, а тип тип long double обеспечивает по меньшей мере такую ​​же точность, как и double. множество значений типа float является подмножеством множества значений тип двойной; множество значений типа double является подмножеством множество значений типа long double.

    Я никогда не использовал long double , но я не так часто использую C/C++. Обычно я использую языки с динамической типизацией, такие как Python, где вам не нужно заботиться о типах.

    Для получения дополнительной информации о Double vs Float см. этот вопрос на SO.

    12

    Разница между плавающей и двойной переменной в Java? Пример

    Хотя оба числа с плавающей точкой и с двойной девяткой0752 используются для представления чисел с плавающей запятой в Java, тип данных double более точен, чем float. Переменная типа double может обеспечивать точность до 15–16 знаков после запятой по сравнению с точностью от 6 до 7 знаков с плавающей запятой. Еще одно существенное различие между float и double заключается в их требованиях к хранению, double дороже, чем float. Для хранения переменной требуется 8 байт, а для float — всего 4 байта. Это означает, что если память является ограничением, то лучше использовать float, чем double. Кстати, тип double также имеет больший диапазон, чем float, и если ваши числа не подходят для float, вам придется использовать double в Java.

    Также стоит отметить, что числа с плавающей запятой или действительные числа в Java по умолчанию удваиваются. Если вы хотите сохранить их в переменной с плавающей запятой, вам нужно либо преобразовать их, либо использовать префикс «f» или «F», как показано в нашем примере.

    И, если вы новичок в мире Java, я также рекомендую вам пройти эти курсы по программированию и разработке на Java   на Udemy и Coursera, чтобы лучше и структурированнее изучить Java. Это один из лучших и современных онлайн-курсов по изучению Java. Они также охватывают новые функции Java из последних выпусков.


    float и double в Java — сходства

    Вот некоторые общие атрибуты типов данных float и double в языке программирования Java:

    1. Вещественные числа

    И двойные числа, и числа с плавающей запятой используются для представления действительных чисел в Java, то есть чисел с дробями или десятичными точками.

    2. Приблизительные типы

    И double, и float являются приблизительными типами, они не являются точными.

    3. Сравнение

    Для сравнения переменных типа float и double вместо = и != следует использовать логические операторы, такие как  > или <, поскольку они не точны.

    Дополнительные сведения о сравнении переменных типа float и double в Java см. в этой статье.

    Вы также можете посетить эти бесплатные веб-сайты для изучения Java, чтобы узнать больше о сходствах и различиях между типами данных float и double в Java. Этот список содержит бесплатные онлайн-курсы по Java от Coursera, Udemy, Pluralsight и т. д., чтобы изучать Java онлайн.

    Разница между float и double в Java

    Вот некоторые ключевые различия между float и double в Java:

    1. Тип данных double более точен, чем float в Java.

    2. double-занимает больше места, чем float в Java. double требует 64-битного хранилища по сравнению с 32-битным хранилищем типа данных с плавающей запятой.

    3. У double диапазон больше, чем у float, потому что у него больше битов для хранения данных.

    4. float использует 1 бит для знака, 8 бит для экспоненты и 23 бита для мантиссы, а double использует 1 бит для знака, 11 бит для экспоненты и 52 бита для мантиссы.

    5. По умолчанию числа с плавающей запятой в Java являются двойными. Чтобы сохранить их в переменной с плавающей запятой, вам нужно привести их явно или добавить к ним суффикс «f» или «F», как показано ниже:

     public static final float PIE = 3.14; // ошибка времени компиляции 

    Используйте cast

     public static final float PIE = (float) 3.14; 

    или суффикс ‘f’ или ‘F’

     public static final float PIE = 3.14f;
    общедоступный статический окончательный плавающий элемент GRAVITY = 9,8F; 

    Как я уже говорил, вы также можете ознакомиться с этими бесплатными курсами по программированию на Java, чтобы узнать больше о сходствах и различиях между типами данных float и double в Java. Один из лучших бесплатных онлайн-ресурсов для изучения Java.

    Когда использовать double и float в Java?

    Хотя оба они могут использоваться для представления чисел с плавающей запятой, есть несколько вещей, которые вы можете рассмотреть, чтобы выбрать между double и float. Хотя оба типа являются приблизительными, если вам нужны более точные и точные результаты, используйте double.

    Используйте float, если у вас есть ограничения по памяти, потому что он занимает почти вдвое меньше места, чем double. Если ваши числа не помещаются в диапазон, предлагаемый float, используйте double. Хотя будьте осторожны с вычислениями и представлениями с плавающей запятой, не используйте double или float для денежного расчета, вместо этого используйте BigDecimal.


    Вот и вся разница между float и double в Java . Помните, что по умолчанию числа с плавающей запятой в Java являются двойными, и если вы хотите сохранить их в переменных с плавающей запятой, вам нужно либо привести их явно, либо добавить к ним суффикс, используя символы «f» или «F».