Ну, я пытался скомпилировать следующий код (просто фрагмент) в Java
:
class MyClass{
public float get100(){
return 100.05; // returning 100.05f should work
}
}
Но, как вы можете видеть 100.5
быть double
в природе, но get100()
возвращается float
своей декларацией, javac
выдает ошибку как: can't convert double to float
,
Что совершенно понятно. Но вот что я заметил c++
Я попробовал следующий код (почти аналогичный приведенному выше):
#include<iostream>
using namespace std;
class MyClass{
public:
float get100(){
return 100.05;
}
};
int main(){
MyClass m;
cout<<m.get100()<<endl;
return 0;
}
и этот код работает нормально в c++
..
Может кто-нибудь сказать мне, почему это так? или это значит c++
Компилятор достаточно умен, чтобы он мог автоматически конвертировать double
в float
?
Но, как double
имеет больший диапазон, чем float
как это работает в c++
?
Любая помощь / предложение приветствуется. Заранее спасибо.
Да, компилятор C ++ достаточно умен, чтобы автоматически конвертировать double в float. Компилятор Java мог сделать то же самое, но дизайнеры Java решили, что лучше не допустить этого, если программист ошибается.
cppreference.com о неявных преобразованиях:
Преобразования с плавающей точкой
Значение типа с плавающей запятой может быть преобразовано в значение любого другого типа с плавающей запятой. Если конверсия указана в разделе «Акции с плавающей запятой», то это акция, а не конверсия.
Если исходное значение может быть представлено точно в типе назначения, оно не изменяется.
Если исходное значение находится между двумя представимыми значениями целевого типа, результатом является одно из этих двух значений (которое определяется реализацией)
В противном случае поведение не определено.
Здесь дело второе правило. 100.05
не совсем представимо как float
или же double
, Для таких значений, как 0.375
или же 34
будет применено первое правило, поскольку исходное значение может быть точно представлено.
Что касается Java, return
является контекстом присваивания JLS§5.2 состояния:
Контексты назначения позволяют использовать одно из следующего:
* преобразование личности (§5.1.1)
* расширяющееся примитивное преобразование (§5.1.2)
* расширение конверсии ссылки (§5.1.5)
* преобразование бокса (§5.1.7), возможно, сопровождаемое расширяющимся эталонным преобразованием
* распаковка преобразования (§5.1.8), возможно, сопровождаемая расширяющимся примитивным преобразованием.
Обратите внимание, что неявное сужающее преобразование не здесь разрешено, если только возвращаемое значение не является константным значением (то есть конечным полем или литеральным выражением, которое компилятор может вычислить).