Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
Dennis Ritchie
549 / 141 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
1

Определить, почему во втором варианте программы происходит переполнение при вычислении переменной dist

24.01.2015, 19:59. Просмотров 969. Ответов 3
Метки нет (Все метки)

Добрый вечер. Не могу понять, почему во втором варианте программы происходит переполнение при вычислении переменной dist на таком тесте:
8066 7339 19155 -90534 -60666
В итоге программа выводит 2147483648 вместо 8. Или временный результат выражения 15950516170 хранится в int, а потом уже преобразуется в long long? Объясните, пожалуйста.
C
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <math.h>
 
int main()
{
    long long r, x, y, xx, yy;
    scanf("%lld%lld%lld%lld%lld", &r, &x, &y, &xx, &yy);
    long long dist = (x - xx) * (x - xx) + (y - yy) * (y - yy);
    printf("%lld\n", (int) ceil(pow(dist, 0.5) / (2 * r)));
    return 0;
}
C
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <math.h>
 
int main()
{
    int r, x, y, xx, yy;
    scanf("%d%d%d%d%d", &r, &x, &y, &xx, &yy);
    long long dist = (x - xx) * (x - xx) + (y - yy) * (y - yy);     // dist переполняется
    printf("%lld\n", (int) ceil(pow(dist, 0.5) / (2 * r)));
    return 0;
}
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.01.2015, 19:59
Ответы с готовыми решениями:

Почему не происходит переполнение переменной типа float?
1.Почему не происходит переполнение переменной overflow?Вернее происходит,но только после...

Почему значение переменной при вычислении копируется в буфер обмена
Доброго времени суток. Сделал программку, которая по даблклику на метке увеличивает ее значение...

Почему не сходятся корни в первом и втором варианте (метод простой итерации)
Почему не сходятся корни в первом и втором варианте.

Подскажите почему происходит ошибка в вычислении
При введении следующих параметров (60 2.3 3) выходит ответ 4rub. 13cop. хотя должен выдавать 4rub....

Почему происходит переполнение?
Если диапазон float: -2 147 483 648.0 / 2 147 483 647.0, то почему происходит переполнение. Или...

3
korvin_
2765 / 2037 / 366
Регистрация: 28.04.2012
Сообщений: 6,948
25.01.2015, 11:17 2
Цитата Сообщение от Dennis Ritchie Посмотреть сообщение
почему во втором варианте программы происходит переполнение
Потому что арифметические операции выполняются над значениями типа int, который в 32-хразрядных программах может вмещать максимум 2млрд с чем-то там.

У меня, кстати 7 выдает, т.к. переполнение знаковых типов — это UB, насколько я знаю.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <math.h>
 
int
main(void)
{
    int r, x, y, xx, yy;
    long long dist;
 
    scanf("%d%d%d%d%d", &r, &x, &y, &xx, &yy);
    dist = (long long) (x - xx) * (x - xx) + (y - yy) * (y - yy);
    printf("%lld\n", (int) ceil(pow(dist, 0.5) / (2 * r)));
 
    printf("sizeof(int) = %d\n", sizeof(int));
    return 0;
}
Bash
1
2
3
4
% tcc -run long.c
8066 7339 19155 -90534 -60666
7
sizeof(int) = 4
1
Байт
Эксперт C
21883 / 13647 / 2878
Регистрация: 24.12.2010
Сообщений: 29,042
25.01.2015, 11:55 3
Лучший ответ Сообщение было отмечено Dennis Ritchie как решение

Решение

Цитата Сообщение от Dennis Ritchie Посмотреть сообщение
почему во втором варианте программы происходит переполнение
То же самое чуток другими словами.
Транслятор видит int x, xx; ... (x - xx) И у него нет никаких поводов это к чему-то приводить. Он работает с ними как с интами. Аналогично (x-xx)*(x-xx) и так далее. Пока дело не дошло до присваивания dist=, ему типы приводить совершенно не к чему. А тут уже поздно, все вычисления прошли в предположении int и все переполнения уже случились.
Цитата Сообщение от Dennis Ritchie Посмотреть сообщение
Или временный результат выражения 15950516170 хранится в int, а потом уже преобразуется в long long?
Именно так!
1
Dennis Ritchie
549 / 141 / 58
Регистрация: 27.07.2014
Сообщений: 2,446
25.01.2015, 14:13  [ТС] 4
Цитата Сообщение от korvin_ Посмотреть сообщение
У меня, кстати 7 выдает, т.к. переполнение знаковых типов — это UB, насколько я знаю.
А вы так напишите (должно получиться 2147483648):

dist = (long long) (x - xx) * (x - xx) + (y - yy) * (y - yy);

А если неправильный спецификатор поставить вместо lld в printf(), то получится -2147483648:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <math.h>
 
int main(void)
{
    int r, x, y, xx, yy;
    long long dist;
 
    scanf("%d%d%d%d%d", &r, &x, &y, &xx, &yy);
    dist = (x - xx) * (x - xx) + (y - yy) * (y - yy);
    printf("%d\n", (int) ceil(pow(dist, 0.5) / (2 * r)));
 
    return 0;
}
0
25.01.2015, 14:13
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.01.2015, 14:13

Почему происходит переполнение?
Помогите ... Dim Nr1 As Double Nr1 = 200 * 300 MsgBox Nr1Error

Почему происходит переполнение?
Только учусь паскалю так что имейте ввиду если не знаю чего-то элементарного. Вобщем вот код с...

Почему происходит переполнение стека?
Помогите понять почему компютер выдаёт мне стек оверфлов в этой рекурсии. Задание было такое: Даны...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.