Не можете використовувати модуль у парних?


185

У мене є програма на C ++ (складена за допомогою g ++). Я намагаюся застосувати два дублі в якості операндів до функції модуля, але я отримую таку помилку:

помилка: недійсні операнди типів "подвійний" і "подвійний" до двійкового "оператора%"

Ось код:

int main() {
    double x = 6.3;
    double y = 2;
    double z = x % y;
}

12
Як зазначалося, fmod () забезпечує необхідну функцію. Як ще не зазначалося, важливо усвідомити, що помилки округлення у другому операнді fmodможе спричинити несподівані поведінки. Наприклад, fmod(1, 0.1);математично повинно бути нуль, але насправді буде майже 0,1. Ступінь помилки збільшується з величиною коефіцієнта. Наприклад, fmod(9E14, 0.1);оцінюється приблизно до 0,05, що з математичної точки зору просто неправильно.
supercat

1
@supercat більше деталей було б дивним. Я думаю, маєте уявлення про те, що відбувається за лаштунками, щоб зробити те, що ви говорите, правдою, але було б добре бачити причини, чому те, що ви говорите, є істинним; було б цікаво подивитися, як це працює за лаштунками (я думаю, я розумію, але міг би дуже легко помилитися).
RastaJedi

3
Значення з плаваючою комою представляють точні цілі кратні чи частки потужностей двох. Наприклад, ціле число буквально 0,1 дорівнює рівно 3602879701896397/36028797018963968 (останнє значення - потужність двох). fmod(x,0.1)поділимо х на цей точний дріб і візьмемо решту, а не ділимо на числове значення "одну десяту".
supercat

Відповіді:


272

%Оператор для цілих чисел. Ви шукаєте fmod()функцію .

#include <cmath>

int main()
{
    double x = 6.3;
    double y = 2.0;
    double z = std::fmod(x,y);

}

Я програмую на C ++ для Qt і у fmod є помилка. Результат fmod (кут, 360) може бути 360 (ВАТ ?!)
Пол

7
@Paul: Це, мабуть, не помилка. Якщо angleє, скажімо, 359.9999999тоді і те, angleі інше fmod(angle, 360), ймовірно, відображатиметься як 360. (Додайте ще 9 значень, якщо потрібно). Спробуйте надрукувати значення, скажімо, з 50 цифр точності.
Кіт Томпсон

Формат QString :: @Paul Qt завершиться. Якщо це так критично, вам доведеться або округлити себе, або перевірити вихід на "360" і замінити його на власне значення.
jfh

38

fmod(x, y) - це функція, яку ви використовуєте.


5

Використання fmod()від <cmath>. Якщо ви не хочете включати файл заголовка C:

template<typename T, typename U>
constexpr double dmod (T x, U mod)
{
    return !mod ? x : x - mod * static_cast<long long>(x / mod);
}

//Usage:
double z = dmod<double, unsigned int>(14.3, 4);
double z = dmod<long, float>(14, 4.6);
//This also works:
double z = dmod(14.7, 0.3);
double z = dmod(14.7, 0);
double z = dmod(0, 0.3f);
double z = dmod(myFirstVariable, someOtherVariable);

3
Чому ви не хочете включати файл заголовка C? Ось для чого це.
Кіт Томпсон

2

Ви можете реалізувати власну функцію модуля, щоб зробити це для вас:

double dmod(double x, double y) {
    return x - (int)(x/y) * y;
}

Тоді ви можете просто використовувати , dmod(6.3, 2)щоб отримати решту, 0.3.


Все ще не ідеальне рішення. x = 10.499999999999998, y = 0.69999999999999996 повертає 0.69999999999999929 замість 0.0
tarpista
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.