Неявное преобразование типов в выражениях int в double

StackOverflow https://stackoverflow.com/questions/1799157

Вопрос

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

const double foo = 5;

я хотел бы использовать

const double foo = 5.0;

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

const double halfFoo = foo / 2;

и т. д.Это число 2 оценивается как целое число и преобразуется ли оно неявно?Должен ли я вместо этого использовать 2.0?

Это было полезно?

Решение

А 2 неявно преобразуется в двойной, потому что foo является двойником.Вы должны быть осторожны, потому что, если foo было, скажем, целым числом, выполнялось бы целочисленное деление, а затем результат сохранялся бы в halfFoo.

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

Другие советы

Это известно как Тип Принуждение.В Википедии есть хорошая информация по этому поводу:

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

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

...

Такое поведение следует использовать с осторожностью, так как могут возникнуть непредвиденные последствия.Данные могут быть потеряны при преобразовании представлений с плавающей запятой в целочисленные представления, поскольку дробные компоненты значений с плавающей запятой будут усечены (округлены в меньшую сторону).И наоборот, преобразование из целочисленного представления в представление с плавающей запятой также может привести к потере точности, поскольку тип с плавающей запятой может быть неспособен точно представлять целое число (например, float может быть типом одинарной точности IEEE 754, который не может представлять целое число). целое число ровно 16777217, тогда как 32-битный целочисленный тип может).Это может привести к таким ситуациям, как сохранение одного и того же целочисленного значения в двух переменных целого типа и типа вещественный, которые возвращают false при сравнении на равенство.

В случае C и C++ значение выражения целочисленного типа (т.е.longs, целые числа, шорты, символы) — это самый большой целочисленный тип в выражении.Я не уверен, но я предполагаю, что нечто подобное происходит (при условии, что значения с плавающей запятой «больше», чем целочисленные типы) с выражениями, включающими числа с плавающей запятой.

Строго говоря, то, чего вы пытаетесь достичь, кажется контрпродуктивным.

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

const double foo = 5; /* better */

чем

const double foo = 5.0; /* worse */

потому что последнее лишнее.Правила неявного преобразования типов языка C гарантируют правильную работу первого.То же самое можно сказать и о сравнениях.Этот

if (foo > 0)

Это лучше чем

if (foo > 0.0)

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

Неявное преобразование типов в данном случае — это очень хорошо, а не плохо.Это помогает вам писать общий типонезависимый код.Почему вы пытаетесь их избегать?

Это правда, что в некоторых случаях у вас нет другого выбора, кроме как явно выразить тип (например, использовать 2.0 вместо 2 и так далее).Но обычно человек делает это только тогда, когда это действительно необходимо.Зачем кому-то это делать без реальной необходимости, я не понимаю.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top