c изменение неявного преобразования с double на int

#c #type-conversion

#c #преобразование типа #c #преобразование типов

Вопрос:

У меня есть код , который содержит много преобразований из double в int . Код можно рассматривать как

 double n = 5.78;
int d = n; // double implicitly converted to a int
  

Неявное преобразование из double в int представляет собой усечение , которое означает , что 5.78 будет сохранено как 5 . Однако было решено изменить это поведение с помощью пользовательского округления .

Одним из подходов к такой проблеме было бы иметь свои собственные типы данных DOUBLE и INT и использовать операторы преобразования , но , увы , мой код большой , и мне не разрешено вносить большие изменения . Другой подход , о котором я подумал , состоял в том , чтобы добавить 0,5 к каждому из чисел , но , увы , код большой , и я слишком много менял .

Каким может быть простой подход к изменению поведения преобразования double в int, которое влияет на весь код.

Комментарии:

1. вы могли бы использовать #define int INT и предоставлять свои собственные преобразования. Не утверждаю, что это приятно, но, учитывая ваши ограничения, это может быть способом

2. Некоторые компиляторы имеют скрытые опции, которые позволяют переопределять встроенные операторы (например, operator (int, int) or operator int(double) . Однако я бы не рекомендовал их использовать, потому что они могут вызвать больше проблем, чем предотвратить.

Ответ №1:

Вы можете использовать унифицированный синтаксис инициализации, чтобы запретить сужающие преобразования:

 double a;
int b{a}; // error
  

Если вы этого не хотите, вы можете использовать std::round функцию (или ее сестер std::ceil / std::floor / std::trunc ):

 int b = std::round(a);
  

Если вы хотите внести минимальные изменения в diff, вот что вы можете сделать. Однако, пожалуйста, обратите внимание, что это плохое решение (если его можно так назвать), и гораздо более вероятно, что вы столкнетесь с сбоем и сгоранием из-за неопределенного поведения, чем на самом деле решаете реальные проблемы.

Определите свой пользовательский Int тип, который обрабатывает преобразования так, как вы хотите:

 class MyInt
{
//...
};
  

затем злонамеренно заменяйте каждое вхождение int на MyInt с помощью черной магии препроцессора:

 #define int MyInt
  

Проблемы:

  • если вы случайно измените определения в стандартной библиотеке — вы находитесь в UB-land
  • если вы измените возвращаемый тип main — вы находитесь в UB-land
  • если вы измените определение функции, но не ее прямые объявления — вы находитесь в зоне ошибок UB / компоновщика. Или в безмолвно зовущей-другой-перегрузочной-стране.
  • возможно, больше.

Комментарии:

1. Это потребовало бы от меня изменения кода во всех местах, где происходят такие преобразования (а это много), и мне не разрешено вносить много изменений в код.

2. @MAG короче #define int MyCustomInt Я не понимаю, как вы могли бы внести это небольшое изменение в diff.

3. @krzaq Удивительно, как вы назвали свой класс myInt в тот же самый момент, когда я отправил свой ответ, где я предложил это решение 🙂

4. @space_voyager У меня осталась машина времени после изучения C за 21 день курса

5. Добавьте в список проблем: бедный сокурсник, который будет следующим разработчиком, которому придется прочитать ваш код, понятия не будет, что вы сделали…

Ответ №2:

Сделайте что-то вроде этого:

 #include <iostream>
using namespace std;

int myConvert (double rhs)
{
    int answer = (int)rhs; //do something fancier here to meet your needs
    return answer;
}

int main()
{
    double n = 5.78;
    int d = myConvert(n);
    cout << "d = " << d << endl;
    return 0;
}
  

Вы можете сделать myConvert столько фантазии, сколько захотите. В противном случае вы могли бы определить свой собственный класс для int (например, myInt class) и перегрузить = оператор для выполнения правильного преобразования.