sqrt(int_value + 0.0) Есть ли у него цель?

выполняя домашнюю работу по моей очень странной книге C++, которую мне раньше говорили выбросить имел очень своеобразный сегмент кода. Я знаю, что домашние задания всегда добавляют дополнительную «загадку», чтобы попытаться запутать вас, например, отступ на 2 строки после цикла for с одним оператором. Но этот я запутался, потому что он, кажется, служит какой-то реальной цели.

в основном это так:

int counter=10;
...
if(pow(floor(sqrt(counter+0.0)),2) == counter)
...

Меня особенно интересует эта часть:

sqrt(counter+0.0)

Есть ли какая-то цель в +0.0? Это способ бедняков сделать статическое приведение к двойнику? Избегает ли это предупреждения компилятора о каком-то компиляторе, который я не использую? Вся программа печатала одно и то же и компилировалась без предупреждений на g++ всякий раз, когда я пропускал часть +0.0. Может быть, я использую недостаточно странный компилятор?

Редактировать:

Кроме того, gcc просто нарушает стандарт и не делает ошибку для неоднозначной ссылки, поскольку sqrt может принимать 3 разных типа параметров?

[earlz@EarlzBeta-~/projects/homework1] $ cat calc.cpp
#include <cmath>

int main(){
  int counter=0;
  sqrt(counter);
}
[earlz@EarlzBeta-~/projects/homework1] $ g++ calc.cpp
/usr/lib/libstdc++.so.47.0: warning: strcpy() is almost always misused, please use strlcpy()
/usr/lib/libstdc++.so.47.0: warning: strcat() is almost always misused, please use strlcat()
[earlz@EarlzBeta-~/projects/homework1] $

Кроме того, вот соответствующая часть моих системных библиотек cmath Я не слишком увлекаюсь шаблонами, поэтому не знаю, что она делает

  using ::sqrt;

  inline float
  sqrt(float __x)
  { return __builtin_sqrtf(__x); }

  inline long double
  sqrt(long double __x)
  { return __builtin_sqrtl(__x); }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                       double>::__type
    sqrt(_Tp __x)
    { return __builtin_sqrt(__x);

person Earlz    schedule 12.04.2010    source источник
comment
Главный вопрос в том, почему ты еще не выбросил книгу? :)   -  person Justin Ardini    schedule 12.04.2010
comment
@Justin требуется для получения степени, иначе я определенно сожгу каждую страницу.   -  person Earlz    schedule 12.04.2010


Ответы (3)


Это способ бедняков сделать статическое приведение к двойнику?

Да.

Вы не можете вызвать sqrt с int в качестве параметра, потому что sqrt принимает float, double или long double. Вы должны привести int к одному из этих типов, иначе вызов будет неоднозначным.

person James McNellis    schedule 12.04.2010
comment
но почему? в данном случае это даже не нужно. - person Earlz; 12.04.2010
comment
@Earlz: я не знаю, почему кто-то рекомендует использовать + 0.0. Единственное, что у него есть, это то, что его нужно печатать меньше, чем static_cast<double> или (double), но это не веская причина для его использования. - person James McNellis; 12.04.2010
comment
@James, почему тогда g++ не выдает ошибку или предупреждение об этом? Смотрите мою правку. - person Earlz; 12.04.2010
comment
@ Джеймс, да, но даже явное приведение не обязательно. Неявное преобразование должно позаботиться об этом. - person Derrick Turk; 12.04.2010
comment
Для информации ваших парней, это на самом деле способ, которым большинство авторов книг учат превращать int в double. Поскольку Precision Math добавлен к Interger Math, по умолчанию используется Precision. - person AjayP; 12.04.2010
comment
Кроме того, книга ищет, если вы измените код, чтобы сделать счетчик, взятый из пользовательского ввода, он автоматически применит его. - person AjayP; 12.04.2010
comment
Причина, по которой вы не получаете предупреждения, заключается в том, что компилятор удовлетворен. Он хочет двойника и получает двойника. Разница между добавлением 0.0 и явным приведением с использованием оператора C++ static_cast заключается в том, что последний подход очень явный. Никто не спросит, что вы делаете в этом случае (в отличие от добавления 0,0, что здесь явно неясно). - person wilhelmtell; 12.04.2010
comment
Точки данных: без какого-либо приведения (или принуждения выражения к типу double) MSVC 2003 или более поздней версии и Comeau генерируют ошибку; GCC 3.4.5, Digital Mars и MSVC 6 этого не делают. Интересно, как позже решают разрешить перегрузку? - person Michael Burr; 12.04.2010
comment
@Earlz: я не знаю, почему g++ принимает ваш тривиальный пример, если только у вас нет дополнительных перегрузок для float и long double в вашей стандартной библиотеке. Visual C++ и Comeau справедливо отвергают пример кода из-за неоднозначности перегрузки. - person James McNellis; 12.04.2010
comment
@Майкл. А, я компилирую весь код домашней работы с помощью g++, так что думаю, именно поэтому я его не уловил. Так что, очевидно, этот парень не мог написать static_cast<double>(counter) и вместо этого должен был оставить код студенту, чтобы он разобрался... что он никогда не говорил об этом трюке конкретно в книге. - person Earlz; 12.04.2010
comment
@James, ну, перегруженные не должны быть частью стандарта ANSI (и, следовательно, не должны быть включены в стандартные библиотеки), потому что с самой последней версией gcc она компилируется без предупреждений. - person Earlz; 12.04.2010
comment
@Earlz: все перегрузки являются частью стандартной библиотеки C++ с тех пор, как язык был стандартизирован. В стандартной библиотеке C они имеют разные имена (так как должны): sqrtf, sqrt и sqrtl. Вы можете легко узнать это, заглянув в заголовок cmath. - person James McNellis; 12.04.2010
comment
@Michael Burr: в стандартной библиотеке, поставляемой с VC 6, перегруженные версии sqrt (и других математических функций в стиле C) отключены по умолчанию с помощью макроса. Название макроса не помню, но во всяком случае именно поэтому ВК 6 не жалуется. В VC 6 по умолчанию sqrt работает так же, как и в C - ожидает double и только double. Никаких перегрузок. - person AnT; 12.04.2010
comment
@James, значит, gcc нарушил стандарт? Смотрите мое редактирование для моего файла cmath. - person Earlz; 12.04.2010
comment
@Earlz: это объясняет, почему нет неоднозначности перегрузки. Шаблон функции используется для выбора перегрузки sqrt(double), если аргумент имеет целочисленный тип. Я не думаю, что это нарушает библиотечный стандарт (может, но я в этом сомневаюсь). Это, безусловно, добавление, зависящее от реализации, и полагаться на него было бы плохой идеей, если вы пытаетесь написать переносимый код. - person James McNellis; 12.04.2010
comment
@Джеймс. Хорошо, приятно знать. Я думаю, это то, что я получаю только за использование g++ и glibc: P - person Earlz; 12.04.2010
comment
Лично я считаю, что это дело +0.0 бред. Я думал, все знают, что в такой ситуации нужно умножать на 1,0. - person Michael Daum; 12.04.2010
comment
@Майкл. какие? У меня всегда было впечатление, что нужно просто смириться и сделать приведение static_typecast или, по крайней мере, приведение в стиле C. - person Earlz; 12.04.2010

причина для счетчика выражения + 0.0 состоит в том, чтобы явно сделать его действительным числом. если мы не добавим 0.0, компилятор выполнит неявное преобразование

person Gaurav Kushwaha    schedule 12.04.2010

Это просто еще один способ приведения к двойнику. Это потому, что sqrt не принимает целые числа. Поскольку двойное число выше, оно объединит целое число с 0.0.0. Таким же образом можно преобразовать из (int,double,float) в строку.

двойной п = 0;

строка m = ""+n;

person flopex    schedule 12.04.2010
comment
Я думаю, вы думаете о каком-то другом языке программирования; вы не можете сделать это в С++. - person James McNellis; 13.04.2010