Почему 5 / 2 равно 2: деление целых чисел
Если оба числа в делении целые, деление тоже целое: дробная часть отбрасывается. Чтобы получить дробный результат, хотя бы одно из чисел должно быть дробным:
#include <stdio.h>
int main(void) {
int a = 5, b = 2;
printf("%d\n", a / b);
printf("%.1f\n", (double)a / b);
printf("%.1f\n", 5.0 / 2);
printf("%.1f\n", a / 2.0);
return 0;
}2
2.5
2.5
2.5(double)a — приведение типа: значение a превращается в double до деления, и деление становится дробным.
Где ставить приведение
Приведение должно стоять до деления. Частые ошибки:
#include <stdio.h>
int main(void) {
int sum = 7, n = 2;
double wrong1 = sum / n;
double wrong2 = (double)(sum / n);
double right = (double)sum / n;
printf("%.1f %.1f %.1f\n", wrong1, wrong2, right);
printf("%.2f %.2f\n", 1 / 2 * 10.0, 10.0 * 1 / 2);
return 0;
}3.0 3.0 3.5
0.00 5.00double wrong1 = sum / n;— деление целое (3), а потом 3 записывается вdoubleкак 3.0. Тип переменной слева на вычисление справа не влияет.(double)(sum / n)— скобки сначала делят нацело, а приводят уже готовую тройку.1 / 2 * 10.0— сначала1 / 2, это 0, и только потом умножение. А10.0 * 1 / 2начинается с дробного числа и даёт 5.
Отсюда частая ошибка в среднем арифметическом: double avg = (a + b + c) / 3; — целое деление. Правильно: (a + b + c) / 3.0.
Отрицательные числа
С C99 деление целых всегда отбрасывает дробную часть к нулю, а знак остатка совпадает со знаком делимого:
#include <stdio.h>
int main(void) {
printf("%d %d\n", -7 / 2, -7 % 2);
printf("%d %d\n", 7 / -2, 7 % -2);
return 0;
}-3 -1
-3 1Математически −7 / 2 = −3.5, и C даёт −3, а не −4. Из-за этого проверка нечётности x % 2 == 1 для отрицательных чисел не работает: у −7 остаток −1. Надёжная проверка — x % 2 != 0.
Деление на ноль
Целое деление на ноль (a / 0, a % 0) — неопределённое поведение: в Linux программа обычно падает с сообщением Floating point exception, в Windows — с ошибкой деления на ноль. Перед делением на переменную проверяйте её: if (b != 0).
Дробное деление на ноль программу не роняет: 1.0 / 0 даёт бесконечность (printf выведет inf), а 0.0 / 0 — «не число» (nan или -nan).