Перейти к содержимому

Чем double отличается от float в c

  • автор:

Встроенные типы (C++)

Встроенные типы (также называемые фундаментальными типами) задаются стандартом языка C++ и встроены в компилятор. Встроенные типы не определены в файле заголовка. Встроенные типы делятся на три основные категории: целочисленные, с плавающей запятой и void. Целочисленные типы представляют целые числа. Типы с плавающей запятой могут указывать значения, которые могут содержать дробные части. Большинство встроенных типов рассматриваются как отдельные типы компилятором. Однако некоторые типы являются синонимами или рассматриваются как эквивалентные типы компилятором.

Тип void

Тип void описывает пустой набор значений. Переменная типа void не может быть указана. Тип void используется в основном для объявления функций, которые не возвращают значения или объявляют универсальные указатели на нетипизированные или произвольные типизированные данные. Любое выражение можно явно преобразовать или привести к типу void . Однако такие выражения можно использовать только в следующих операторах и операндах:

  • в операторе выражения (Дополнительные сведения см. в разделе Выражения.)
  • в левом операнде оператора запятой (Дополнительные сведения см. в разделе Оператор запятой.)
  • во втором и третьем операндах условного оператора ( ? : ). (Дополнительные сведения см. в разделе Выражения с условным оператором.)

std::nullptr_t

Ключевое слово nullptr является константой std::nullptr_t типа null-указателя, которая преобразуется в любой необработанный тип указателя. Дополнительные сведения см. в разделе nullptr .

Тип Boolean

Тип bool может иметь значения true и false . Размер bool типа зависит от реализации. Дополнительные сведения о реализации см. в разделе «Размеры встроенных типов «.

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

Тип char — это тип представления символов, который эффективно кодирует элементы базового набора символов выполнения. Компилятор C++ обрабатывает переменные типа char , signed char и unsigned char как переменные разных типов.

Корпорация Майкрософт: переменные типа char по умолчанию действуют как int будто из типа signed char , если /J только не используется параметр компиляции. В этом случае они рассматриваются как тип unsigned char и повышаются до int без расширения знака.

Переменная типа wchar_t — это расширенный или многобайтовый тип символов. L Используйте префикс перед символом или строковым литералом, чтобы указать тип расширенных символов.

Корпорация Майкрософт: по умолчанию wchar_t — это собственный тип, но вы можете использовать /Zc:wchar_t- его для unsigned short определения wchar_t типа. __wchar_t — синоним для машинного типа wchar_t для систем Майкрософт.

Тип char8_t используется для представления символов UTF-8. Он имеет то же представление, что unsigned char и , но рассматривается как отдельный тип компилятором. Тип char8_t новый в C++20. Корпорация Майкрософт: для использования char8_t требуется /std:c++20 параметр компилятора или более поздней версии (например /std:c++latest , ).

Тип char16_t используется для представления символов UTF-16. Оно должно быть достаточно большим, чтобы представить любую единицу кода UTF-16. Он рассматривается как отдельный тип компилятором.

Тип char32_t используется для представления символов UTF-32. Оно должно быть достаточно большим, чтобы представить любую единицу кода UTF-32. Он рассматривается как отдельный тип компилятором.

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

Типы с плавающей запятой используют представление IEEE-754 для обеспечения приближения дробных значений по широкому диапазону величин. В следующей таблице перечислены типы с плавающей запятой в C++ и относительные ограничения на размеры типов с плавающей запятой. Эти ограничения являются обязательными стандартом C++ и не зависят от реализации Майкрософт. Абсолютный размер встроенных типов с плавающей запятой не указан в стандарте.

Тип Содержимое
float Тип float является наименьшим типом с плавающей запятой в C++.
double double — это тип с плавающей запятой, размер которого больше или равен размеру типа float , но меньше или равен размеру типа long double .
long double long double — это тип с плавающей запятой, размер которого больше или равен размеру типа double .

Корпорация Майкрософт: представление long double и double идентично. long double Однако и double рассматриваются как отдельные типы компилятором. Компилятор Microsoft C++ использует представления с плавающей запятой 4 и 8-байтов IEEE-754. Дополнительные сведения см. в представлении с плавающей запятой IEEE.

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

Тип int — базовый целочисленный тип по умолчанию. Он может представлять все целые числа по определенному диапазону реализации.

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

Модификатор размера указывает ширину в битах используемого целочисленного представления. Язык поддерживает short и long long long модификаторы. Тип short должен быть не менее 16 бит ширины. Тип long должен быть не менее 32 битов ширины. Тип должен быть по крайней long long мере 64-разрядным. Стандарт задает связь размера между целочисленными типами:

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

Ключевое слово int могут быть опущены при signed unsigned указании модификаторов размера или размера. Модификаторы и int тип, если они присутствуют, могут отображаться в любом порядке. Например, short unsigned и unsigned int short ссылаться на тот же тип.

Синонимы целочисленного типа

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

Типы целых чисел, зависящие от Майкрософт, включают определенные ширины __int8 , __int16 __int32 а также __int64 типы. Эти типы могут использовать signed модификаторы и unsigned модификаторы. Тип данных __int8 аналогичен типу char , __int16 — типу short , __int32 — типу int , а __int64 — типу long long .

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

Большинство встроенных типов имеют определенные реализацией размеры. В следующей таблице перечислены объем хранилища, необходимый для встроенных типов в Microsoft C++. В частности, long 4 байта даже в 64-разрядных операционных системах.

Тип Size
bool , char , char8_t , unsigned char , signed char , __int8 1 байт
char16_t , __int16 , short , unsigned short , wchar_t , __wchar_t 2 байта
char32_t , float , __int32 , int , unsigned int , long , unsigned long 4 байта
double , __int64 , long double , long long , unsigned long long 8 байт

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

Дополнительные сведения о преобразовании типов см. в разделе «Стандартные преобразования».

Вещественные типы (double, float)

Вещественные типы (или типы с плавающей точкой) представляют значения, имеющие дробную часть. В языке MQL4 есть два типа для чисел с плавающей точкой. Способ представления вещественных чисел в машинной памяти определен стандартом 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
*/

В чем отличие float/double и decimal?

Здравствуйте, хотел попросить какие-то материалы, которые будут понятны новичку, насчёт ошибок округления и типа decimal, заранее спасибо!

  • Вопрос задан более года назад
  • 1703 просмотра

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

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

В MSDN смотрели?
https://learn.microsoft.com/ru-ru/dotnet/csharp/la.
Решения вопроса 1

vabka

Василий Банников @vabka Куратор тега C#
Токсичный шарпист

float и double — это числа с плавающей точкой по стандарту IEEE754. Операции с ними происходят достаточно быстро, тк они реализованы в процессоре на аппаратном уровне.
Но они достаточно не точные в плане выражения десятичных дробей. (То самое 0.1+0.2 != 0.3).
Настоящие деньги на них считать не следует.

decimal же напротив очень точный, но медленный.

Вопрос по c++ float и double в чем разница

чем команда float отличается от double ?
когда делал самый примитивный калькулятор
у меня возникли ошибки
на строчках где объявлял дробное число (1.3)
для объявления использовал float
и не мог понять в чем дело ,
мне объяснили шо надо double
все начало работать, но остался вопрос «шо не так то с float ?

Голосование за лучший ответ

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

good cucumberУченик (81) 7 лет назад

#include
#include
#include
using namespace std;
int main(int nNubmdersofArgs, char* pszArgs[])

Зло Просветленный (38729) и? заменил на float — ни одной ошибки, только предупреждение, что в x = 1.3; double до float уменьшается

float — 32-х разрядное число с плавающей точкой одинарной точности, при включенной оптимизации выполняется в SSE;
double — 64-х разрядное число с плавающей точкой двойной точности, при включенной оптимизации также выполняется в SSE;
long double — 96 разрядное число с плавающей точкой, всегда выполняется только на сопроцессоре.

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

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