Преобразование double to int
6.3.1.4 Real floating and integer
When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.50)
Для C++ аналогично:
7.3.11
A prvalue of a floating-point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be represented in the destination type. [Note: If the destination type is bool, see [conv.bool]. — end note]
Как преобразовать double в int c
Если в арифметических операциях участвуют значения разных типов, то компилятор неявно пытается привести их к одному типу. Кроме того, когда мы присваиваем переменной какое-либо значение, это значение всегда приводится к типу переменной. Например:
char c = 6; int d = c;
Переменной d, которая представляет тип int, присваивается значение типа char, поэтому компилятор выполняет приведение значения от типа char к типу int.
В то же время не всегда преобразования могут быть безопасными, поскольку разные типы имеют разное внутреннее представление. И просто так перейти от одного представления к другому без потери точности данных не всегда возможно.
Рассмотрим, какие преобразования применяет компилятор при арифметических операциях:
- Если один из операндов имеет тип long double , то второй операнд тоже будет преобразован в тип long double
- Если предыдущий пункт не выполняется и если один из операндов имеет тип double , то второй операнд тоже будет преобразован к типу double
- Если предыдущий пункт не выполняется и если один из операндов имеет тип float , то второй операнд тоже будет преобразован к типу float
- Если предыдущий пункт не выполняется и если один из операндов имеет тип unsigned long int , то второй операнд тоже будет преобразован к типу unsigned long int
- Если предыдущий пункт не выполняется и если один из операндов имеет тип long , то второй операнд тоже будет преобразован к типу long
- Если предыдущий пункт не выполняется и если один из операндов имеет тип unsigned , то второй операнд тоже будет преобразован к типу unsigned
- Если предыдущий пункт не выполняется то оба операнда приводятся к типу int
int a = 10; #include int main(void) < int number1 = 10; double number2 = 4; double result = number1 + number2; // 14.000000 printf("result = %f \n", result); // result = 14.000000 return 0; >
В выражении number1 + number2 число number2 представляет тип double , поэтому число number1 будет автоматически приводиться к числу double. И результат операции сложения также будет представлять тип double .
Операция преобразования
С помощью специальной операции преобразования мы можем явным образом привести данные к нужному типу. Например:
int a = 10; int b = 4; int c = a / b; // 2 double d = a / b; // 2.00000 double e = (double)a / (double)b; // 2.50000 printf("c = %d \n", c); printf("d = %f \n", d); printf("e = %f \n", e);
В выражении int c = a / b; результат деления будет целочисленный — 2, при котором дробная часть будет отброшена, так как оба операнда операции представляют целые числа.
В выражении double d = a / b; результат деления будет представлять вещественное число — 2.00000, но так как оба операнда являются целыми числами, то опять же результат операции будет представлять целое число 2, и только поле выполнения деления произойдет присвоение результата переменной d с приведением значения 2 от типа int к типу double.
В выражении double e = (double)a / (double)b применяется явное преобразование данных к типу double, поэтому и результат деления будет представлять вещественное число — 2.50000.
Для выполнения операции приведении в скобках указывается тот тип, к которому надо привести значение:
int number = 70; char symbol = (char) number; printf("symbol = %c \n", symbol); // F printf("symbol (int code) = %d \n", symbol); // 70
В ряде случаев преобразования сопровождаются потерей информации, например, когда числа большей разрядности (скажем размером 4 байт) получаем число меньшей разрядности (например, в 2 байта). Без потери информации проходят следующие цепочки преобразований:
char -> short -> int -> long
unsigned char -> unsigned short -> unsigned int -> unsigned long
float -> double -> long double
При всех остальных преобразованиях, которые не входят в эти цепочки, мы можем столкнуться с потерей точности данных. Так, в примере выше преобразование от int к char не является безопасным, поэтому к таким преобразованиям следует относиться с осторожностью. Например:
#include int main(void) < int number1 = 300; char code = number1; // потеря точности - число number1 усекается до 1 байта printf("code = %d \n", code); // code = 44 return 0; short number2 = 100000; // потеря точности - число 100000 усекается до 2 байт printf("number2 = %d \n", number2); // number2 = -31072 >
Здесь две ситуации небезопасных преобразований. В первом случае число типа int , которое равно 300, присваивается переменной типа char . В итоге переменная code будет равна 44. Почему? Число 300 в двоичной системе:
0000000100101100
Оставляем только первый младший байт:
00101100
И у нас получается число 44 в десятичной системе.
Во втором случае число 100000 (которое по умолчанию представляет тип int ), усекается до разрядности типа short — до двух байт.
short number = 100000;
В итоге число number в реальности будет равно -31072.
Как преобразовать double в int c
Преобразование типов данных, это приведение одного типа к другому. Например, приведение целочисленной переменной к числу с плавающей точной, или преобразование числа в строку. В C# выделяют два варианта преобразования типов:
- Неявное преобразование типов. Это, так называемое безопасное преобразование типов в C#. Например, преобразование из типа float (более «маленький» тип) в тип double (более «большой» тип). При таком преобразовании никакая информация не «потеряется», что при обратном преобразовании вполне возможно.
- Явное преобразование типов. Такое преобразование выполняется программистом с прямым указанием типа, к которому нужно привести переменную. Для такого преобразования требуется наличие оператора преобразования.
А теперь, я покажу как можно использовать явное преобразование типов в C#:
using System; namespace TypesConvertion < class Program < static void Main(string[] args) < //Число с плавающей точкой double doubleData = 245.45; //Вывод этого числа Console.WriteLine(doubleData); //А теперь, мы сделаем на основе этого числа, цело число int intData = (int)doubleData; //Вывод целого числа Console.WriteLine(intData); //Чтобы окно не закрылось раньше времени Console.ReadKey(); >> >
Преобразование типа double в тип int выполнялось в выделенной строке (строке с номером 16). Если вы соберете данный пример и запустите его, то увидите, что преобразование типов прошло, т.е. из числа с плавающей точкой мы получили целое число.
Так же, для преобразования данных из одного типа в другой, есть целый класс с именем Convert, у которого имеются специальные методы. Ниже, в таблице, представлены основные методы этого класса.
Название метода | Целевой тип |
---|---|
ToBoolean | bool |
ToByte | byte |
ToChar | char |
ToDouble | double |
ToSingle | float |
ToInt32 | int |
ToInt64 | long |
ToString | string |
А теперь, пример использования класса Convert и его методов:
using System; namespace TypesConvertion < class Program < static void Main(string[] args) < //Число с плавающей точкой double doubleData = 245.45; //Вывод этого числа Console.WriteLine(doubleData); //А теперь, мы сделаем на основе этого числа, цело число int intData = Convert.ToInt32(doubleData); //Вывод целого числа Console.WriteLine(intData); //Чтобы окно не закрылось раньше времени Console.ReadKey(); >> >
Как видите, это практически тот же код, что был в первом примере, но с использованием другого подхода в преобразовании типов.
И обратите внимание на еще одни момент, если один тип нельзя преобразовать в другой, а вы это попытаетесь сделать, то получите ошибку в программе!
Пользоваться возможность преобразования типов вам придется довольно часто!
C++: Преобразование типов
Как мы уже поняли разные типы данных по-разному хранятся в памяти компьютера. Например, целочисленное значение 3 может быть сохранено как двоичное 0000 0000 0000 0000 0000 0000 0000 0011, тогда как значение с плавающей запятой 3.0 может быть сохранено как двоичное 0100 0000 0100 0000 0000 0000 0000 0000.
Так что же происходит когда мы инициализируем переменную типа float целым числом.
float f_age < 18 >;
А произойдет следующее: поскольку компилятор не может просто сохранить целое число в переменную с плавающей точкой, он преобразует это число в эквивалентное, но типа float .
Процесс преобразования значения из одного типа данных в другой тип данных называется преобразованием типа.
Преобразования типов могут быть неявные — по решению компилятора и явные по решению программиста.
Неявное преобразование типа выполняется компилятором автоматически, когда требуется один тип данных, но предоставляется другой тип. Подавляющее большинство преобразований типов в C++ являются неявными преобразованиями типов.
Неявное преобразование может происходить в следующих случаях:
- если мы делаем арифметическую операцию двух разных типoв. Преобразование идет в тот тип который шире.
double d_result < 4.2 / 3 >// 3 будет пеобразованна в double
- если происходит инициализация переменной другого типа. Тут уже может быть, что мы например сохраним число типа long в переменную типа int и тут уже зависит от способа инициализации переменной.
double d_num < 3 >; // 3 будет преобразованна в double int num = 3.14; // будет потерянна вещевственная часть int num = < 3.14 >; // ошибка компиляции
- Забегая вперед. При использовании небулевого значения в инструкции if
if (5) < >// 5 будет преобразованно в true
Но явное всегда лучше, чем неявное. В C++ существует 5 различных видов приведений типа: приведения в стиле C, статические приведения, константные приведения, динамические приведения и реинтерпретирующие приведения. Последние четыре иногда называют именованными приведениями.
Здесь мы рассмотрим приведение в стиле С и статическое приведение.
В стандартном программировании на C приведение типов выполняется с помощью оператора (), при этом имя типа, в который необходимо преобразовать значение, помещается в круглые скобки. Вы всё еще можете увидеть, что они используются в коде, преобразованном из C.
int main() < int x < 5 >; int y < 4 >; double d_result < (double)x / y >; // x преобразуется в тип double >
В приведенном выше коде мы явно указали компилятору чтобы он преобразовал int x в double .
C++ также позволяет вам использовать приведение в стиле C с синтаксисом, более похожим на вызов функций:
double d_result < double(x) / y >;
Это работает идентично предыдущему примеру, но тут преимущество в том, что преобразуемое значение заключено в скобки — это упрощает определение того, что конвертируется.
Приведение в стиле С не рекомендуется использовать поскольку под капотом он может выполнять множество различных преобразований в зависимости от контекста и даже убирать константность.
В C++ появился оператор приведения типов static_cast , который можно использовать для преобразования значения одного типа в значение другого типа. Этот способ наиболее безопасен и рекомендован в С++.
int main() < int x < 5 >; int y < 4 >; double d_result < static_cast(x) / y >; >
В угловых скобках указывается тип к которому приводим, а в круглые передаем переменную или число которое приводим.
Задание
В прошлом модуле мы писали программу, которая переводила евро в доллары, а доллары в рубли. На тот момент мы не знали типов данных с плавающей точкой и использовали автоматический вывод типов с помощью auto . Отрефакторите ее используя новые знания, используйте явное приведение типов.
Напишите программу, которая берет исходное количество евро, записанное в переменную euros_count , переводит евро в доллары и выводит на экран. Затем полученное значение переводит в рубли и выводит на новой строчке.
Пример вывода для 100 евро:
125.0 7500.0
- 1 евро = 1.65 долларов
- 1 доллар = 60 рублей
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Полезное
- static_cast
- Преобразования типов и безопасность типов