Как найти остаток от деления double

double amount;
cin >> amount;
if (amount % 1 == 0)
{...}

Вот такой код не работает, поскольку amount в программе имеет тип double, сама ошибка:

E2140 выражение должно относиться к целочисленному типу или типу
перечисления без области видимости

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

задан 9 июл 2022 в 16:08

Єгор Тітаренко's user avatar

4

Остаток от деления для вещественных чисел считается функцией fmod.

ответ дан 9 июл 2022 в 20:42

Qwertiy's user avatar

QwertiyQwertiy

121k24 золотых знака121 серебряный знак291 бронзовый знак

3

Проверить, что вещественное число целое, можно так:

fabs(x) >= 9007199254740992 || (long long)x == x

ответ дан 9 июл 2022 в 21:40

Qwertiy's user avatar

QwertiyQwertiy

121k24 золотых знака121 серебряный знак291 бронзовый знак

Опреатор остатка от деления не может быть использован на не целочисленных типах попробуй такой вариант:

if (amount  == (int)amount )

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

ответ дан 9 июл 2022 в 20:13

StackITS64's user avatar

3

Прототип функции fmod:

     double fmod(      double num,      double denom );
      float fmod(       float num,       float denom );
long double fmod( long double num, long double denom );

Заголовочный файл

Название Язык
math.h С
cmath С++

Описание

Функция fmod вычисляет остаток от деления и возвращает значение с плавающей точкой, оставшуюся часть от целочисленного деления параметров num/denom.

Остаток от деления является результатом вычитания из числителя, произведение целого частного num / denom на знаменатель:

остаток = числитель — (целое частное) * знаменателю

В Си, определён только один прототип данной функции, с типом данных double.

Параметры:

  • num
    Вещественное значение — числитель.
  • denom
    Вещественное значение — знаменатель.

Возвращаемое значение

Остаток от деления числителя на знаменатель.

Пример: исходный код программы

// пример использования функции fmod

#include <iostream>                                             // для оператора cout
#include <cmath>                                                // для функции fmod

int main()
{
  std::cout << "fmod(7.3, 2.9)      = "  << fmod(7.3, 2.9)    << std::endl;
  std::cout << "fmod(15.5, 2.2)  = "  << fmod(15.5, 2.2) << std::endl;

  return 0;
}

Пример работы программы

CppStudio.com

fmod(7.3, 2.9) = 1.5
fmod(15.5, 2.2) = 0.1

Описание

      fmod выдает в плавающем формате остаток от деления од-
      ного числа на другое.  Она возвращает x, если он ноль,
      либо число F с тем же знаком, что у x, - такое, что
      x = L*y + F для некоторого целого L  и  |F| < |y|.

Использование

      #include <math.h>
      double f mod (double x, double y);

Возвращаемое значение

      fmode возвращает остаток в формате с плавающей точкой.

Пример

      #include <stdio.h>
      #include <math.h>
      main ()
      {
        double x, y, d;
        x = 5.0; y = 3.0;
        d = fmod (x,y);
        printf("fmod(%.2f, %.2f) = %fn,x,y,d);
      }

Рекомендация

      Смотрите также ceil, floor, modf

оглавление

Содержание

  • Арифметические операторы C#
    • Унарные арифметические операторы C#
      • Операторы приращения (++) и уменьшения (—)
      • Унарные операторы плюса и минуса
    • Бинарные арифметические операторы
      • Умножение (*)
      • Деление (/)
      • Остаток от деления (%)
      • Операторы сложения (+) и вычитания (-)
      • Операторы составного присваивания
    • Приоритет и ассоциативность операторов
  • Итого

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

При изучении любого языка программирования, будь то Delphi, Python или C#, одной из основных тем изучения на начальном этапе является перечень основных операторов в языке и их применение. Конечно, со временем работать с теми или иными операторами начинаешь, как говориться, «на автомате», но в самом начале пути изучения нового языка эта тема является безусловно одной из основных. Все возможные операторы я, конечно, сейчас рассматривать не буду, но основные всё же стоит рассмотреть, чтобы в дальнейшем не путаться в их применении.

Как и в Delphi операторы делятся на две группы: унарные и бинарные.

К унарным арифметическим операторам в C# относят:

  • ++ (приращение),
  • -- (уменьшение),
  • + (плюс) и — (минус)

к бинарным:

  • * (умножение),
  • / (деление),
  • % (остаток от деления),
  • + (сложение) и — (вычитание).

Большинство из этих операторов нам может быть известно из Delphi (кто не знает, как работает умножение или деление в Delphi?), но некоторые из операторов имеют свои особенности в C#. Например, в статье про работу с числами в C# упоминалось что деление 1/3 в C# не вернет нам результат 0,3333 Начнем с унарных.

Унарные арифметические операторы C#

Операторы приращения (++) и уменьшения (—)

Ближайшими аналогами в Delphi для этих операторов являются процедуры Inc() и Dec().

Оператор инкремента ++ увеличивает операнд на 1, а оператор декремента --, соответственно, уменьшает операнд на 1. При этом операндом должна быть переменная, свойство или индексатор.

Например, результатом выполнения вот такого кода:

double f = 4.45; 
int i = 10; 
f++;//увеличиваем f на 1 
i--;//уменьшаем i на 1 
Console.WriteLine("f = {0}, i = {1}",f,i);

будет строка:

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

«Усложним» пример и напишем следующее:

double f = 4.45; 
int i = 10; 
double a = f++; 
int b = i--;
Console.WriteLine("a = {0}, b = {1}", a, b);

Казалось бы, результат измениться не должен и строка должна быть той же, но нет. В результате мы получим:

То есть, переменные а и b получили первоначальные значения f и i. Почему так происходит?

Дело в том, что операторы инкремента и декремента в C# поддерживается в двух формах: постфиксной (например, x++) и префиксной (например, ++x).

Результатом постфиксного оператора приращения или уменьшения является значение переменной перед выполнением операции, а результатом префиксного оператора, соответственно, значение переменно после выполнения операции.

Теперь, если взглянуть на пример выше, становится понятно поведение программы — мы использовали постфиксные операторы и в результате, вначале переменной a присваивается значение f, а уже потом значение переменной f увеличивается на 1. Аналогично происходит и с переменной b — она получает первоначальное значение i и только после этого i уменьшается на 1.

На первый взгляд может показаться странным, но вот такое действие:

int i = 0;
i = i++;

не поменяет значение переменной i — она также останется равной нулю. Причина такого поведения C# описана выше — использовалась постфиксная форма инкремента.

Чтобы наше переменные получили измененные значения код надо переписать с использованием префиксной формы операторов, то есть вот так:

double f = 4.45; 
int i = 10; 
double a = ++f; //сначала наращиваем f на 1, а потом - присваиваем значение переменной a 
int b = --i; 
Console.WriteLine("a = {0}, b = {1}",a,b);

Результатом выполнения будет строка:

Унарные операторы плюса и минуса

Как и в Delphi, унарный оператор + возвращает значение полученного операнда. Унарный оператор - изменяет знак операнда на противоположный. Здесь никаких «подводных камней» нет и результат выполнения следующего кода можно угадать с первого раза:

double f = -4.45;
int i = 10;
Console.WriteLine("+f = {0}, -i = {1}", +f, -i);

Результатом будет строка:

Остается только отметить, что целочисленный тип ulong не поддерживает унарный минус. Если мы попытаемся сделать вот так:

ulong i = 10;
Console.WriteLine("-i = {0}", -i);

То ещё до компиляции получим ошибку:

Ошибка CS0023 Оператор «-» невозможно применить к операнду типа «ulong»

При этом для целочисленных типов ushort и uint оператор «-» работает.  Вот такой код:

ushort i = 10; //создали переменную
Console.WriteLine(i.GetType()); //получили тип данных для i
ushort b = i; //присвоили значение i переменной b
Console.WriteLine((-b).GetType()); //получили тип данных для отрицательного значения b

Выведет на экран следующее:

System.UInt16
System.Int32

Бинарные арифметические операторы

Умножение (*)

Оператор умножения * вычисляет произведение операндов, например:

ushort a = 10; //создали переменную
int b = 5; //присвоили значение i переменной b
Console.WriteLine(a * b);

вернет значение 50, а типом данных для произведения будет, ожидаемо, int. Соответственно, в этом примере:

float a = 10.0f; //создали переменную
int b = 5; //присвоили значение i переменной b
Console.WriteLine((a * b).GetType());
Console.ReadLine();

Программа вернет нам вещественный тип float (System.Single).  Другое дело — оператор деления.

Деление (/)

В C# различают деление целых чисел и деление чисел с плавающей точкой (запятой).

Для операндов целочисленных типов (int, short, uint и т.д.) результат оператора / является целочисленным типом, который равен частному двух операндов, округленному в сторону нуля. Собственно об этом мы говорили в заметке про работу с числами в C#.

Для типов float, double и decimal результатом оператора / является частное двух операндов. Однако и здесь есть момент, который стоит помнить, а именно: если один из операндов — это decimal, второй операнд не может быть ни float, ни double, так как ни float, ни double не преобразуется неявно в тип decimal. Необходимо явным образом преобразовать операнд float или double в тип decimal (также, про такое поведение C# см. здесь). Вот такой код:

decimal a = 10;
double b = 3;
Console.WriteLine(a / b);

Приведет к ошибке:

Ошибка CS0019 Оператор «/» невозможно применить к операнду типа «decimal» и «double»

Чтобы код сработал без ошибок надо произвести приведение типов, а именно переписать код следующим образом:

decimal a = 10;
double b = 3;
Console.WriteLine(a / (decimal)b);

и деление пройдет успешно с результатом

3,3333333333333333333333333333

Остаток от деления (%)

Ближайшим «родственником» в Delphi является оператор mod. Но и здесь у C# есть свои особенности.

Для целочисленных операндов результатом a % b является значение полученное из выражения a - (a / b) * b. Знак ненулевого остатка такой же, как и у левого операнда, например:

int a = 10;
int b = 3;
Console.WriteLine(a % b);

вернет нам значение 1. Тут всё ровно так же, как и в Delphi. В отличие от Delphi, в C# можно получить остаток от деления вещественных чисел, например:

double a = 10.4;
double b = 3.45;
Console.WriteLine(a % b);

Вернет значение

В Delphi с оператором mod такое проделать нельзя. Для получения аналогичного результата нам бы пришлось воспользоваться функцией FMod() из модуля Math.

Операторы сложения (+) и вычитания (-)

Эти операторы так же, как и везде производят математическое сложение/вычитание правого операнда из левого. Никаких подводных камней и особенностей в этом плане в C# нет.

int a = 10;
double b = 3.45;
Console.WriteLine(a - b);

вернет

Операторы составного присваивания

В C# имеются также операторы составного присваивания (чего нет в Delphi), которые можно использовать, например, для более короткой записи арифметических операций и в общем случае выглядят следующим образом:

x op= y

где op  — какой-либо из рассмотренных выше операторов. Читается такое выражение в развернутом виде следующим образом:

x = x op y

Например,

int a = 10;
a += 10; //a=a+10 = 20;
Console.WriteLine(a);
a /= 10; //a = a/10 = 2;
Console.WriteLine(a);
a *= 5; //a = a*5 = 10
Console.WriteLine(a);
a %= 3; //a = a mod 3 = 1
Console.WriteLine(a);

вернет нам значения, которые написаны в комментариях к коду, то есть строки:

При этом, в случае работы с операторами составного присваивания следует иметь в виду следующее примечание из справки Microsoft по языку C#:

Из-за восходящих приведений результат операции op может быть невозможно неявно преобразовать в тип T из x. В этом случае, если op является предопределенным оператором, и результат операции является явно преобразуемым в тип T``x, выражение составного присваивания формы x op= y эквивалентно x = (T)(x op y), за исключением того, что x вычисляется только один раз.

Пример такого поведения представлен там же в справке:

byte a = 200;
byte b = 100;

var c = a + b;
Console.WriteLine(c.GetType());  // output: System.Int32
Console.WriteLine(c);  // output: 300

a += b;
Console.WriteLine(a);  // output: 44

Мы бы, возможно, ожидали, что последний вывод в консоль содержал бы число 300, но тип byte у нас только от 0 до 255. В результате в вывод попало значение (300-256 = 44).

Приоритет и ассоциативность операторов

Арифметические операторы выполняются в следующем порядке (по убыванию приоритета):

  • Постфиксный инкремент x++ и декремент x--
  • Префиксный инкремент ++x и декремент --x, унарные операторы + и -
  • Мультипликативные операторы *, /, и %
  • Аддитивные операторы + и -

Бинарные арифметические операторы имеют левую ассоциативность. То есть операторы с одинаковым приоритетом вычисляются в направлении слева направо.

Порядок вычисления, определяемый приоритетом и ассоциативностью операторов, можно изменить с помощью скобок (()).

Итого

Сегодня мы узнали, какие виды арифметических операторов есть в C#, как они работают и в чем их особенности. А также разобрали несколько примеров, показывающих особенности вычисления арифметических выражений в C#.

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.


Форум программистов Vingrad

Модераторы: Daevaorn

Страницы: (2) Все [1] 2 
( Перейти к первому непрочитанному сообщению )

Поиск:

Ответ в темуСоздание новой темы
Создание опроса
> остаток от деления вещественных чисел 

:(

   

Опции темы

PRF
Дата 29.9.2008, 22:20 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 135
Регистрация: 13.10.2007

Репутация: нет
Всего: нет

Привет. Ребята как получить остаток от деления. 

double A = 1.23202;

A % 1 =  выдает ошибку, но это понятно, так вот, как получить остаток от деления вещественного числа???
Заранее спасибо.

PM MAIL   Вверх
volvo877
Дата 29.9.2008, 22:38 (ссылка)
|    (голосов:1)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Комодератор
Сообщений: 2072
Регистрация: 15.11.2004

Репутация: 1
Всего: 116

Попробуй функцию fmod из math…

PM MAIL   Вверх
sergejzr
Дата 30.9.2008, 00:13 (ссылка)
|  (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Un salsero
Group Icon

Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360

Остатка от деления вещественного числа в природе быть не может.

———————

Me.
FB.
LinkedIn.
ORCID.
YT.

PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
NebelDT
  Дата 30.9.2008, 08:48 (ссылка)
   | (голосов:4)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 54
Регистрация: 29.9.2008
Где: RU

Репутация: -1
Всего: -10

Как тебе такой примечик??? smile

Код

#include <stdio.h>
#include <math.h >
main()
{
double i=0,j=0,N=0,M=0,K=0,X=0,Z=0,G=0;
scanf("%f%f",&N,&K);
j=K;i=2;G=i;
while(i<=N){
X=(G%K); :shok 
if(X==0){Z++;}
i++;G++;
}
printf("%f",Z);
return (0);
}

PM MAIL WWW YIM   Вверх
mrbrooks
Дата 30.9.2008, 08:55 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

трололомен
****

Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 2
Всего: 306

NebelDT, это че за дичь?

PM MAIL   Вверх
Alexeis
Дата 30.9.2008, 09:15 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Амеба
Group Icon

Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459

NebelDT, а теперь подумай smile . 
PRF, возможно тебе следует привести числа с плавающей точкой к целым и потом получить остаток деления целых чисел.

———————

Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать

PM ICQ Skype   Вверх
vinter
Дата 30.9.2008, 12:32 (ссылка)
|    (голосов:1)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Explorer
****

Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56

кастанув спелл  телепатии, я решил, что тебе нужно следущее 

Код

double A = 1.23202;
double B = A - static_cast<long>(A); 

———————

Мой блог

PM MAIL WWW   Вверх
inside_pointer
Дата 30.9.2008, 13:07 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Опытный
**

Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12

Код

#include <stdio.h>
#include <math.h>

main()
{
    printf("%gn", fmod(1.555, 1.0));
    return 0;
}

подключение математической библиотеки
[[email protected] tmp]$ cc -lm test.c -o test

PM MAIL   Вверх
volvo877
Дата 30.9.2008, 13:17 (ссылка)
|    (голосов:1)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Комодератор
Сообщений: 2072
Регистрация: 15.11.2004

Репутация: 1
Всего: 116

inside_pointer, во втором посте что было, не заметил? Однако, здесь появилось мнение, что разработчики С/С++ и библиотек — полные идиоты, и занимаются не тем, чем нужно, ибо остатка быть не может… Значит, твой пост — фикция… Не может быть такой функции в природе, ибо считать ей НЕЧЕГО…

PM MAIL   Вверх
vinter
Дата 30.9.2008, 14:13 (ссылка)
|    (голосов:2)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Explorer
****

Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56

Цитата(volvo877 @  30.9.2008,  14:17 Найти цитируемый пост)
Не может быть такой функции в природе, ибо считать ей НЕЧЕГО…

конечно нечего, любое вещественое число, делиться на любое другое без остатка. Значит у вещественных чисел нет остатка ;)

———————

Мой блог

PM MAIL WWW   Вверх
system
Дата 30.9.2008, 16:04 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

Профиль
Группа: Участник
Сообщений: 48
Регистрация: 16.5.2008

Репутация: нет
Всего: 2

Код

#include <iostream>
#include <math.h>

double rest( double x, double y ) {
double i, f;
        if (y == 0.0) {
                return 0.0;
        }
        i = floor(x/y);
        f = x - i*y;
        if ((x < 0.0) != (y < 0.0))
                f = f-y;
        return f;
}

int main() {
        std::cout << rest( -10.1, 3.1 ) << std::endl; 
        return 0;
}
//out : -0.8

Это сообщение отредактировал(а) system — 30.9.2008, 16:56

PM MAIL   Вверх
korian
Дата 30.9.2008, 20:10 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Опытный
**

Профиль
Группа: Участник
Сообщений: 650
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17

шото поискав по инету нашел тока такое определение:

Цитата
По определению найти частное и остаток от деления целого числа а на целое число b, отличное от нуля, означает нахождение целых q и r (называемых соответственно частным и остатком), удовлетворяющих двум условиям:
1) a=b*q + r
2) 0 <= r < |b|

видно т.к. операция mod над действительными числами не имеет большой популярности, другое определение фиг найдешь  smile 
а вообще в данном выражение, целым обязано быть только число q.

PM   Вверх
Alexeis
Дата 30.9.2008, 21:22 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Амеба
Group Icon

Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459

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

———————

Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать

PM ICQ Skype   Вверх
korian
Дата 1.10.2008, 11:50 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Опытный
**

Профиль
Группа: Участник
Сообщений: 650
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17

Alexeis, вы имеете ввиду, что функция fmod делает что-то типа:
floor(x) % floor(y) ?
если б это было так, то fmod(5., 2.5) должен быть равен 1
а так оно равно нулю, что вообщем-то и правильно, т.к. результат деления 5 на 2.5 целое число.

PM   Вверх
J0ker
Дата 1.10.2008, 19:32 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Опытный
**

Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 4
Всего: 14

 

smile

Код

The fmod function calculates the floating-point remainder f of x / y such that x = i * y + f, where i is an integer, f has the same sign as x, and the absolute value of f is less than the absolute value of y.

———————

user posted image

PM MAIL   Вверх



















Страницы: (2) Все [1] 2 

Ответ в темуСоздание новой темы
Создание опроса
Правила форума «С++:Общие вопросы»
Earnest
Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл
    черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе — для этого существует «Центр Помощи».
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением,
Earnest
Daevaorn

 

0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »

Понравилась статья? Поделить с друзьями:
  • Как найти лучшего врача уролога
  • Как найти макросы в word
  • Как найти код банка альфа банк
  • Как составить письмо по возврату денежных средств
  • Если потерялся телефон самсунг как его найти