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

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

24.01.2015, 19:59. Просмотров 918. Ответов 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)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.01.2015, 19:59
Ответы с готовыми решениями:

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

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

Переполнение при обращении к переменной Char
Делаю все по Подбельскому, но для своей программы, ничего не получается....

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

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

3
korvin_
2165 / 1654 / 320
Регистрация: 28.04.2012
Сообщений: 5,913
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
18318 / 12029 / 2506
Регистрация: 24.12.2010
Сообщений: 24,293
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
548 / 140 / 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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.01.2015, 14:13

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

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

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


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

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

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