Одинарная или двойная точность?
В научных вычислениях мы часто используем числа с плавающей запятой (плавающей точкой). Эта статья представляет собой руководство по выбору правильного представления числа с плавающей запятой. В большинстве языков программирования есть два встроенных вида точности: 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 , но производить некоторые или все вычисления с двойной точностью.
Когда производить вычисления с увеличенной точностью
Даже если вы храните данные с одинарной точностью, в некоторых случаях уместно использовать двойную точность при вычислениях. Вот простой пример на С:
float sum(float* values, long long count) < float sum = 0; for (long long i = 0; i < count; ++i) < sum += values[i]; >return sum; >
Если вы запустите этот код на десяти числах одинарной точности, то не заметите каких-либо проблем с точностью. Но если запустите на миллионе чисел, то определённо заметите. Причина в том, что точность теряется при сложении больших и маленьких чисел, а после сложения миллиона чисел, вероятно, такая ситуация встретится. Практическое правило такое: если вы складываете 10^N значений, то теряете N десятичных знаков точности. Так что при сложении тысячи (10^3) чисел теряются три десятичных знака точности. Если складывать миллион (10^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 разрядов точности вместо 7, то могли бы сложить 10^(16-3) = 10 000 000 000 000 значений без проблем с точностью.
(Существуют численно стабильные способы сложения большого количества значений. Однако простое переключение с float на double гораздо проще и, вероятно, быстрее).
Выводы
- Не используйте лишнюю точность при хранении данных.
- Если складываете большое количество данных, переключайтесь на двойную точность.
Приложение: Что такое число с плавающей запятой?
Я обнаружил, что многие на самом деле не вникают, что такое числа с плавающей запятой, поэтому есть смысл вкратце объяснить. Я пропущу здесь мельчайшие детали о битах, INF, NaN и поднормалях, а вместо этого покажу несколько примеров чисел с плавающей запятой в base-10. Всё то же самое применимо к двоичным числам.
Вот несколько примеров чисел с плавающей запятой, все с семью десятичными разрядами (это близко к 32-битному float ).
1.875545 · 10^-18 = 0.000 000 000 000 000 001 875 545
3.141593 · 10^0 = 3.141593
2.997925 · 10^8 = 299 792 500
6.022141 · 10^23 = 602 214 100 000 000 000 000 000
Выделенная жирным часть называется мантиссой, а выделенная курсивом — экспонентой. Вкратце, точность хранится в мантиссе, а величина в экспоненте. Так как с ними работать? Ну, умножение производится просто: перемножаем мантисссы и складываем экспоненты:
1.111111 · 10^42 · 2.000000 · 10^7
= (1.111111 · 2.000000) · 10^(42 + 7)
= 2.222222 · 10^49
Сложение немного хитрее: чтобы сложить два числа разной величины, сначала нужно сдвинуть меньшее из двух чисел таким образом, чтобы запятая находилась в одном и том же месте.
3.141593 · 10^0 + 1.111111 · 10^-3 =
3.141593 + 0.0001111111 =
3.141593 + 0.000111 =
3.141704
Заметьте, как мы сдвинули некоторые из значимых десятичных знаков, чтобы запятые совпадали. Другими словами, мы теряем точность, когда складываем числа разных величин.
- float
- double
- плавающая запятая
- плавающая точка
- одинарная точность
- двойная точность
Перевод «Double» на русский
Так называемый двойной орел был отчеканен в 1933 году, но никогда не поступал в официальное обращение.
Double stiching and some exprienced workers.
Двойной шить и некоторые лицо имеющее трудовые стажи.
Double rooms with breakfast start at 70 euros.
Цены на двухместный номер с завтраком начинаются от 70 евро.
In video pokers the selection impresses with Aces and Eights, Deuces Wilds, Jacks or Better, and even Double Double Jackpot Poker.
В видео-покеры выбор впечатляет тузы и восьмерки, дикие двойки, Валеты или лучше, и даже двухместный Джекпот покер.
Double coding meant the buildings convey many meanings simultaneously.
Двойное кодирование означает, что здания скрывают в своем дизайне несколько значений одновременно.
Double standards are the reason terrorism still exists.
И двойные стандарты — причина, по которой терроризм все еще существует.
Double taxation treaties may indicate different rules to define resident status.
В конвенциях об избежании двойного налогообложения могут быть указаны различные правила для определения статуса резидента.
Double rim provides longer life and more aggressive material removal.
Двойной обод обеспечивает более длительный срок службы и более агрессивное удаление материала.
The Double 7 symbol substitutes other symbols to form high paid winning combinations.
Символ Двойная семерка (77) заменяет другие символы, чтобы сформировать как можно больше комбинаций с высокой выплатой.
Double rooms have access to a shared fully equipped kitchen.
Гости из двухместных номеров с 1 кроватью могут пользоваться общей полностью оборудованной кухней.
Double standards — those are precisely what distinguish despotism from democracy.
Двойные стандарты — это ведь как раз то, что отличает деспотию от демократии.
Double standards and impunity cannot prevail in addressing this sensitive issue.
Нельзя допускать того, чтобы в подходе к столь сложному вопросу возобладали двойные стандарты и безнаказанность.
Double insulated for safety and long life.
Двойная изоляция для повышения безопасности и длительного срока службы.
Double wishbones forged from aluminum guide all four wheels.
Двойные поперечные рычаги выкованы из алюминия, руководя всеми четырьмя колесами.
Double standards are often used in international relations.
Таким образом, двойные стандарты очень часто используются в мировой политике.
Double and student-designed majors can be arranged.
Двойные и студенческие разработанные крупные фирмы могут быть организованы.
Double standard still exists but not as powerful as before.
Двойной стандарт все еще существовал, но он не был столь сильным, как раньше.
Double standards in combating terrorism should be abandoned.
При борьбе с международным терроризмом должны быть исключены двойные стандарты.
Double CD compilations followed in 2007 and 2008.
Компиляции двойного CD была выпущеня в 2007 и 2008 годах.
All other facilities are as per the Double Room.
Все остальные удобства такие же, как и в двухместном номере.
Возможно неприемлемое содержание
Примеры предназначены только для помощи в переводе искомых слов и выражений в различных контекстах. Мы не выбираем и не утверждаем примеры, и они могут содержать неприемлемые слова или идеи. Пожалуйста, сообщайте нам о примерах, которые, на Ваш взгляд, необходимо исправить или удалить. Грубые или разговорные переводы обычно отмечены красным или оранжевым цветом.
Зарегистрируйтесь, чтобы увидеть больше примеров. Это просто и бесплатно
Ничего не найдено для этого значения.
Предложить пример
Больше примеров Предложить пример
Предложения, которые содержат Double
Показать больше
Новое: Reverso для Windows
Переводите текст из любого приложения одним щелчком мыши .
Скачать бесплатно
Перевод голосом, функции оффлайн, синонимы, спряжение, обучающие игры
Результатов: 60949 . Точных совпадений: 60949 . Затраченное время: 160 мс
Помогаем миллионам людей и компаний общаться более эффективно на всех языках.
Что означает тип размещения double (DBL) в отеле?
Решив изучить номерной фонд различных гостиниц и отелей (преимущественно зарубежных), можно столкнуться с многообразием различных сокращений и аббревиатур, которые призваны классифицировать абсолютно все аспекты размещения: от количества кроватей и вида из окна до типа корпуса. В данной статье мы рассмотрим, что представляет собой номер с типом размещения double.
Отличительные черты категории
Итак, под сокращением DBL или double (читается как «дабл») в отелях подразумевается двухместный номер с одной двуспальной кроватью. Наибольшей популярностью эта категория пользуется у семейных пар, а также постояльцев, состоящих в романтических отношениях.
Если позволяет площадь и имеется такая потребность, помещение можно оснастить еще одним спальным местом для ребенка. Это своего рода компромиссный вариант на случай, если чадо отказывается спать в одной кровати с родителями, но при этом гости хотят сэкономить на двухместном семейном варианте размещения.
Кроме того, в рамках существующей классификации иногда используют и такой вариант обозначения, как double for single use. В данном случае речь идет о точно таком же спальном месте, но рассчитанном на проживание лишь одного постояльца.
Особенности номеров дабл в отеле «Паллада»
Среди разновидностей номеров double room принято выделять категории повышенной комфортности (studio, deluxe, superior и др.), хотя, разумеется, комната на двоих жильцов с одной большой кроватью может быть любого класса (в т. ч. standard). Например, в гостинице «Паллада» подобный вариант размещения предусмотрен для всех доступных категорий:
- Эконом.
- Стандарт.
- Стандарт улучшенный.
- Полулюкс.
- Люкс.
Для всех гостей отеля бесплатно предоставляется вкусный завтрак, доступ к камере хранения, интернету через Wi-Fi сеть, парковочным местам на закрытой охраняемой стоянке, специально оборудованному теннисному корту. Кроме того, постояльцы могут воспользоваться дополнительными услугами: поужинать в ресторане, отпраздновать торжество в банкетном зале, арендовать конференц-зал и т. д.
Тип double — вещественные числа
Для работы с вещественными (дробными) числами в Java используется тип double . В памяти он занимает 8 байт (в два раза больше, чем тип int ) и может хранить значения в диапазоне -1.7*10 308 до +1.7*10 308 . Для сравнения: тип int может хранить значение в диапазоне -2*10 9 до +2*10 9 .
В вещественных числах дробная часть записывается после точки. Например, 123.456, или 2.5, или 100.00 или 0.01. Такие числа еще называют числами с плавающей точкой — floating point number – компьютерное название для вещественных чисел.
Кстати, кроме типа double есть еще вещественный тип float (размером всего 4 байта). Его название как раз и происходит от floating point . Название же double происходит от double float . Тип double в два раза больше, чем float : 8 байт против 4 . Его еще называют вещественное число двойной точности .
2. Создание переменной типа double
Тип double используется для хранения вещественных чисел. Чтобы создать в коде переменную, которая будет способна хранить вещественные числа, нужно воспользоваться командой:
double имя;
Создание переменной типа double
Где имя — это имя переменной. Примеры:
double price;
double weight;
double lightSpeed;
Так же, как и с типом int , можно использовать краткую запись для создания нескольких переменных типа double :
double имя1, имя2, имя3;
Создание нескольких переменных типа double
И даже сразу присваивать им значения:
double имя1 = значение1, имя2 = значение2, имя3 = значение3;
Создание и инициализация нескольких переменных типа double
double price = 5.0;
double weight = 2;
double x = 1.0, y = 2.0, z = 3.0;
3. Присваивание целых и вещественных чисел
Было бы плохо, если бы целые числа можно было присваивать только переменным типа int , а вещественные — только переменным типа double . Хотелось бы иметь возможность преобразовывать одни числа в другие. И в Java такая возможность есть.
Во-первых, переменным типа double можно присваивать как вещественные, так и целые числа. При присваивании целых чисел они просто преобразовываются в вещественные. Хотя иногда при этом возможна небольшая потеря точности.
double price = 5.0;
double weight = 2;
int t = 1000; double x = t * t;
Во-вторых, если в каком-то выражении участвуют целое и вещественное число, целое сначала преобразуется в вещественное и только потом взаимодействует с другим вещественным числом.
int t = 1000; double x = t * 5.0;
System.out.println(5 * 2);
System.out.println(5 * 2.0);
И наконец, есть возможность присваивать переменным типа int вещественные числа. Дробная часть числа при этом отбрасывается — число округляется вниз до целого.
Также компилятор требует, чтобы этот факт программист задокументировал явно (чтобы другие программисты понимали, что тут происходит отбрасывание дробной части). Общий вид этого выражения в коде такой:
целочисленная_переменная = (int)(вещественное_число);
Присваивание переменной типа int вещественного числа
int x = (int)(5.5);
double a = 5.999; int x = (int)(a);
double a = 5.999; int b = 2; int x = (int)(a * b);
4. Деление целых и вещественных чисел в Java
При делении целого числа на целое остаток всегда отбрасывается. Как же тогда, скажем, поделить 5 на 2 , чтобы получить 2.5 ?
Поначалу кажется, что правильный вариант такой:
double d = 5 / 2;
Однако не все так просто. Дело в том, что Java-машина сначала вычислит значение выражения 5 / 2 и только потом присвоит результат в переменную d . А деление 5 / 2 выполнится нацело. Т.е. d будет содержать 2 или, если быть более точным, 2.0
Правильный вариант такой: хотя бы одно из чисел, участвующих в делении, нужно записать как вещественное (т.е. с точкой):
double d = 5.0 / 2;
double d = 5 / 2.0;
double d = 5.0 / 2.0;
В любом из этих выражений d будет содержать значение 2.5
А как же быть с переменными? Что если у нас есть такой код:
int a = 5; int b = 2; double d = a / b;
Тут есть хитрое (и очевидное) решение — заставить Java-машину преобразовать переменные в вещественные, умножив их на вещественную единицу — 1.0
int a = 5; int b = 2; double d = a * 1.0 / b;
Обратите внимание, что у операций умножения и деления равный приоритет, и они выполняются слева направо, поэтому имеет значение, где именно мы умножаем на вещественную единицу.
int a = 5; int b = 2; double d = 1.0 * a / b;
int a = 5; int b = 2; double d = a * 1.0 / b;
int a = 5; int b = 2; double d = a / b * 1.0;