Вещественные типы (double, float)
Вещественные типы (или типы с плавающей точкой) представляют значения, имеющие дробную часть. В языке MQL5 есть два типа для чисел с плавающей точкой. Способ представления вещественных чисел в машинной памяти определен стандартом IEEE 754 и не зависит от платформ, операционных систем и языков программирования.
Размер в байтах
Минимальное положительное значение
Имя double означает, что точность этих чисел вдвое превышает точность чисел типа float . В большинстве случаев тип double является наиболее удобным. Ограниченной точности чисел float во многих случаях попросту недостаточно. Причина, по которой тип float все еще используется, — экономия памяти при хранении (это важно для больших массивов вещественных чисел).
Константы с плавающей точкой состоят из целой части, точки (.) и дробной части. Целая и дробная части представляют собой последовательности десятичных цифр.
double a= 12.111 ;
double b=- 956.1007 ;
float c = 0.0001 ;
float d = 16 ;
Существует научный способ записи вещественных констант, зачастую этот способ записи более компактный, чем традиционный.
double c1=1.12123515e-25;
double c2=0.000000000000000000000000112123515; // 24 нуля после десятичной точки
Print ( "1. c1 = " , DoubleToString (c1,16));
// Результат: 1. c1 = 0.0000000000000000
Print ( "2. c1 = " , DoubleToString (c1,-16));
// Результат: 2. c1 = 1.1212351499999999e-025
Print ( "3. c2 = " , DoubleToString (c2,-16));
// Результат: 3. c2 = 1.1212351499999999e-025
Необходимо помнить, что вещественные числа хранятся в памяти компьютера с некоторой ограниченной точностью в двоичной системе счисления, в то время как общепринятой в использовании является десятичная система счисления. Поэтому многие числа, которые точно записываются в десятичной системе, в двоичной системе можно записать только в виде бесконечной дроби.
Например, числа 0.3 и 0.7 представлены в компьютере бесконечными дробями, в то время как число 0.25 хранится точно, так как представляет из себя степень двойки.
В связи с этим, категорически не рекомендуется сравнивать между собой два вещественных числа на равенство, так как такое сравнение не является корректным.
void OnStart ()
<
//—
double three=3.0;
double x,y,z;
x=1/three;
y=4/three;
z=5/three;
if (x+y==z)
Print ( "1/3 + 4/3 == 5/3" );
else
Print ( "1/3 + 4/3 != 5/3" );
// Результат: 1/3 + 4/3 != 5/3
>
Если все же необходимо сравнить на равенство два вещественных числа, то можно сделать это двумя разными способами. Первый способ заключается в сравнении разницы между двумя числами с какой-то малой величиной, задающей точность сравнения.
bool EqualDoubles( double d1, double d2, double epsilon)
<
if (epsilon<0)
epsilon=-epsilon;
//—
if (d1-d2>epsilon)
return false;
if (d1-d2<-epsilon)
return false;
//—
return true ;
>
void OnStart ()
<
double d_val=0.7;
float f_val=0.7;
if (EqualDoubles(d_val,f_val,0.000000000000001))
Print (d_val, "equals" ,f_val);
else
Print ( "Different: d_val = " , DoubleToString (d_val,16), " f_val = " , DoubleToString (f_val,16));
// Результат: Different: d_val= 0.7000000000000000 f_val= 0.6999999880790710
>
Необходимо отметить, что значение параметра epsilon в приведенном примере не может быть меньше предопределенной константы DBL_EPSILON. Значение этой константы 2.2204460492503131e-016. Для типа float соответствующая константа FLT_EPSILON = 1.192092896e-07. Смысл этих значений таков, что это наименьшее значение, удовлетворяющее условию 1.0+DBL_EPSILON != 1.0 (для чисел типа float 1.0+FLT_EPSILON != 1.0).
Второй способ предполагает сравнивать нормализованную разность двух вещественных чисел с нулевым значением. Сравнивать разность нормализованных чисел с нулём бесполезно, так как в результате любой математической операции с нормализованными числами результат получается ненормализованным.
bool CompareDoubles( double number1, double number2)
<
if ( NormalizeDouble (number1-number2,8)==0)
return ( true );
else
return ( false );
>
void OnStart ()
<
double d_val=0.3;
float f_val=0.3;
if (CompareDoubles(d_val,f_val))
Print (d_val, "equals" ,f_val);
else
Print ( "Different: d_val = " , DoubleToString (d_val,16), " f_val = " , DoubleToString (f_val,16));
// Результат: Different: d_val= 0.3000000000000000 f_val= 0.3000000119209290
>
В результате некоторых операций математического сопроцессора может получиться недействительное вещественное число, которое нельзя использовать в математических операциях и операциях сравнения, так как результат выполнения операций над недействительными вещественными числами неопределен. Например, при попытке вычислить арксинус от 2, результатом будет минус бесконечность.
double abnormal = MathArcsin (2.0);
Print ( "MathArcsin(2.0) =" ,abnormal);
// Результат: MathArcsin(2.0) = -1.#IND
Кроме минус бесконечности существуют плюс бесконечность и NaN (не число). Чтобы определить, что данное число недействительно, можно использовать функцию MathIsValidNumber(). По стандарту IEEE они имеют специальное машинное представление. Например, плюс бесконечность для типа double имеет битовое представление 0x7FF0 0000 0000 0000.
struct str1
<
double d;
>;
struct str2
<
long l;
>;
//— начнем
str1 s1;
str2 s2;
//—
s1.d= MathArcsin (2.0); // получим недействительное число -1.#IND
s2=s1;
printf ( "1. %f %I64X" ,s1.d,s2.l);
//—
s2.l=0xFFFF000000000000; // недействительное число -1.#QNAN
s1=s2;
printf ( "2. %f %I64X" ,s1.d,s2.l);
//—
s2.l=0x7FF7000000000000; // наиобльшее нечисло SNaN
s1=s2;
printf ( "3. %f %I64X" ,s1.d,s2.l);
//—
s2.l=0x7FF8000000000000; // наименьшее нечисло QNaN
s1=s2;
printf ( "4. %f %I64X" ,s1.d,s2.l);
//—
s2.l=0x7FFF000000000000; // наибольшее нечисло QNaN
s1=s2;
printf ( "5. %f %I64X" ,s1.d,s2.l);
//—
s2.l=0x7FF0000000000000; // плюс бесконечность 1.#INF и наименьшее нечисло SNaN
s1=s2;
printf ( "6. %f %I64X" ,s1.d,s2.l);
//—
s2.l=0xFFF0000000000000; // минус бесконечность -1.#INF
s1=s2;
printf ( "7. %f %I64X" ,s1.d,s2.l);
//—
s2.l=0x8000000000000000; // отрицательный ноль -0.0
s1=s2;
printf ( "8. %f %I64X" ,s1.d,s2.l);
//—
s2.l=0x3FE0000000000000; // 0.5
s1=s2;
printf ( "9. %f %I64X" ,s1.d,s2.l);
//—
s2.l=0x3FF0000000000000; // 1.0
s1=s2;
printf ( "10. %f %I64X" ,s1.d,s2.l);
//—
s2.l=0x7FEFFFFFFFFFFFFF; // наибольшее нормализованное число (MAX_DBL)
s1=s2;
printf ( "11. %.16e %I64X" ,s1.d,s2.l);
//—
s2.l=0x0010000000000000; // наименьшее положительное нормализованное (MIN_DBL)
s1=s2;
printf ( "12. %.16e %.16I64X" ,s1.d,s2.l);
//—
s1.d=0.7; // покажем, что число 0.7 – бесконечная дробь
s2=s1;
printf ( "13. %.16e %.16I64X" ,s1.d,s2.l);
/*
1. -1.#IND00 FFF8000000000000
2. -1.#QNAN0 FFFF000000000000
3. 1.#SNAN0 7FF7000000000000
4. 1.#QNAN0 7FF8000000000000
5. 1.#QNAN0 7FFF000000000000
6. 1.#INF00 7FF0000000000000
7. -1.#INF00 FFF0000000000000
8. -0.000000 8000000000000000
9. 0.500000 3FE0000000000000
10. 1.000000 3FF0000000000000
11. 1.7976931348623157e+308 7FEFFFFFFFFFFFFF
12. 2.2250738585072014e-308 0010000000000000
13. 6.9999999999999996e-001 3FE6666666666666
*/
Что значит double
В С++ существуют два типа данных с плавающей точкой: float и double . Типы данных с плавающей точкой предназначены для хранения чисел с плавающей точкой. Типы данных float и double могут хранить как положительные, так и отрицательные числа с плавающей точкой. У типа данных float размер занимаемой памяти в два раза меньше, чем у типа данных double , а значит и диапазон принимаемых значений тоже меньше. Если тип данных float объявить с приставкой long , то диапазон принимаемых значений станет равен диапазону принимаемых значений типа данных double . В основном, типы данных с плавающей точкой нужны для решения задач с высокой точностью вычислений, например, операции с деньгами.
Как хранятся действительные числа в компьютере
Для хранения действительных чисел в памяти компьютера отводится определённое количество бит. Действительное число хранится в виде знака (плюс или минус), мантиссы и экспоненты. Что такое мантисса и экспонента лучше объяснить на примере: масса Земли равна 5.972*10 24 килограмм. Здесь 5.972 — мантисса, а 24 — экспонента.
При выводе больших (или очень маленьких) чисел в программе на C++ можно увидеть на экране запись типа 5.972E23. Сначала выводится мантисса, затем — буква E, а затем — экспонента. Запись представлена в десятичной системе счисления. В таком же формате можно вводить большие или очень маленькие действительные числа. Этот формат называется экспоненциальной записью числа.
Мы будем работать с типом double (с числами двойной точности), который занимает 8 байт. Один бит отводится под знак числа, 11 под экспоненту и 52 под мантиссу. С помощью 52 бит можно хранить числа длиной до 15-16 десятичных цифр. Таким образом, независимо от того, какая у числа экспонента, правильные значения будут иметь только первые 15 цифр. В примере с массой Земли точно заданы первые 4 цифры, таким образом, погрешность составляет 10 20 килограмм. Это довольно большая погрешность. Чтобы масса Земли с точностью до первых четырёх знаков изменилась, на неё нужно дополнительно поселить миллиард миллиардов довольно упитанных людей.
Таким образом, можно сказать, что числа в компьютере хранятся не с абсолютной, а с относительной погрешностью (то есть погрешность зависит от значения хранимого числа).
То, что числа хранятся неточно, создаёт нам множество проблем.
Итак, мы рассмотрели главные моменты, касающиеся основных типов данных в С++. Осталось только показать, откуда взялись все эти диапазоны принимаемых значений и размеры занимаемой памяти. А для этого разработаем программу, которая будет вычислять основные характеристики всех, выше рассмотренных, типов данных.
что означает слово дабл.
Ква́друпл-дабл (англ. Quadruple-double, дословно четверной двойной или четверной дубль) — баскетбольный термин, означающий набор игроком в течение 1 матча двузначного количества пунктов одновременно в 4 статистических показателях. В качестве показателей могут выступать очки, перехваты, блокшоты, результативные передачи и подборы. Это выдающееся достижение чрезвычайно редко на высшем уровне, и каждый сделанный квадрупл-дабл говорит о незаурядных игровых качествах баскетболиста.
Трипл-дабл (англ. triple-double, дословно тройной двойной или тройной дубль) — баскетбольный термин, означающий набор игроком в одном матче в трёх статистических показателях более 10 пунктов (т. е. двузначного числа) . В качестве показателей могут выступать очки, перехваты, блокшоты, результативные передачи и подборы. Пример — 16 очков, 11 передач, 12 подборов. Термин впервые был использован в статистике Национальной баскетбольной ассоциации применительно к Мэджику Джонсону, рекордсмену по трипл-даблам в плей-офф. Сделанный трипл-дабл свидетельствует о разносторонности игровых качеств баскетболиста. Самым сложным является набор 10 перехватов — абсолютный рекорд НБА по перехватам в одной игре составляет всего лишь 11, а с 1973 года было всего лишь 19 случаев (в среднем — раз в 2 года) , когда баскетболисты делали 10 или 11 перехватов. 10 блокшотов тоже являются редкостью в НБА — лишь около 130 случаев за
последние 36 лет.
Дабл-дабл (англ. Double-double) — так у баскетболі називають досягнення гравця, що має за гру двозначний загальний результат в двох з основних статистичних показників. Основні статистичні показники — очки, підбирання, результативні передачі, перехоплення, блокшоти. Найчастіші дабл-дабли — «очки+підбирання» (наприклад, 18 очок і 11 підбирань) , «очки+результативні передачі» (наприклад, 14 очок і 10 передач) , «підбирання+результативні передачі» (наприклад, 11 підбирань і 13 результативних передач за гру) .
Інші види дабл-даблів зустрічаються рідше. Основна причина в тому, що набрати за гру 10 блокшотів чи перехоплень складніше, ніж 10 очок, передач чи підбирань. Також дабл-дабл може бути складовою більш вагомих досягнень — трипл-дабла чи квадрупл-дабла. Приклад — якщо гравець набрав 26 очок, 14 передач та 11 підбирань (це трипл-дабл «очки+підбирання+результативні передачі»), то можна також сказати, що йдеться про дабл-дабл «очки+підбирання» , «підбирання+результативні передачі» або «очки+результативні передачі».
Дабл ю (англ. W) — фільм режисера Олівера Стоуна про життя та президенство Джорджа Буша. Фільм продовжує серію фільмів Стоуена про відомих особистостей сучасності, таких як «Королева» (2006 р. ) про королеву Єлизавету ІІ та «Ніксон» (1995 р. ) про колишнього президента США Річарда Ніксона. Зйомки фільму почалися 12 травня 2008 р. , він має вийти на екрани 17 жовтня, 2008 р. до завершення виборів президента США.