0 / 0 / 0
Регистрация: 18.09.2010
Сообщений: 21
|
|
1 | |
неправильный результат арифмет. операции09.07.2013, 19:55. Показов 5286. Ответов 18
Метки нет (Все метки)
функция
long long raznost (long a, long b) { return a-b; } Возвращает неправильный результат при a=-2147483648; b=2147483647 Дизасм IAR выдает приблизительно такое: subs r0,r0,r1 asrs r1, r0, #31 результат в регистрах r1, r0. IAR 5.30, от уровня оптимизации не зависит, камень stm32F100xxx. Кто нибудь сталкивался с такой проблемой!?
0
|
09.07.2013, 19:55 | |
Ответы с готовыми решениями:
18
Неправильный результат арифметической операции Неправильный результат Неправильный результат Неправильный результат запроса |
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
09.07.2013, 20:17 | 2 |
Сообщение от bikyr
0
|
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
|
|
09.07.2013, 20:21 | 3 |
А ежели вместо long-ов написать явно sykned long?
0
|
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
|
|
09.07.2013, 20:26 | 4 |
В IAR должна быть настройка еще как интерпретировать типы без явного указания знаковости/беззнаковости. И по дефолту там таки unsykned, вродь.
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
|
|
09.07.2013, 20:39 | 5 |
Код вроде генерит правильный, должен вернуть 1: long(0x8000000)-long(0x7FFFFFF)=long(0x00000001), преобразование типов потом идёт. Нет?
Если вам надо получить -4294967295 - пишите (long)a-b упс... (long long)a-b
0
|
0 / 0 / 0
Регистрация: 06.06.2011
Сообщений: 2,514
|
|
09.07.2013, 20:40 | 6 |
а вроде и не должен.
результат a-b имеет тот же тип что и а, то есть long, в который результат не влазит, и только потом уже приводится к long long для возврата. return (long long)a - b
0
|
0 / 0 / 0
Регистрация: 18.09.2010
Сообщений: 21
|
|
09.07.2013, 21:42 | 7 |
Не имеет значения как писать sykned long или просто long результат один и тот же.
Ассемблер генерирует не правильный код (см. первый мой пост в теме).
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
|
|
09.07.2013, 22:38 | 8 |
Код правильный. Единицу возвращает?
Пишите, как сказал _pv - вот тогда вернёт миллионы.
0
|
0 / 0 / 0
Регистрация: 01.02.2011
Сообщений: 300
|
|
09.07.2013, 22:43 | 9 |
В Keil возвращает 1.
0
|
0 / 0 / 0
Регистрация: 18.09.2010
Сообщений: 21
|
|
09.07.2013, 22:47 | 10 |
Сообщение от oomomstir
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
|
|
09.07.2013, 23:18 | 11 |
Правила такие: результат сложения двух long чисел - это long. То же самое будет и на большом компе, и при написании не на Си, а, к примеру, на Паскале, Яве, C#. Чай, не бейсик какой - компилируемый язык, тип данных определяется на момент компиляции, а не на момент вычисления.
Для понимания выпишите типы данных всех аргументов и промежуточных результатов: a: long b: long a-b: long return value: long long Со сложением/вычитанием на такие грабли новички (недавно освоившие Си - возможно, после интерпретируемых языков) редко наступают, обычно если ожидается длинная сумма/разность, то и хотя бы одно из слагаемых такое. Вот с умножением - таки да :-)
0
|
0 / 0 / 0
Регистрация: 18.09.2010
Сообщений: 21
|
|
09.07.2013, 23:23 | 12 |
не знал о таком правиле
0
|
0 / 0 / 0
Регистрация: 18.09.2010
Сообщений: 21
|
|
09.07.2013, 23:25 | 13 |
какое-то оно странное и далеко не очевидное
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
|
|
09.07.2013, 23:34 | 14 |
Оно совершенно очевидное. Попробуйте придумать хоть какую-нибудь альтернативу этому правилу (но помните, что на момент компиляции значения a и b неизвестны - только типы данных).
А знать такие вещи необходимо. Это азы, расписанные в любой книжке по C для начинающих.
0
|
0 / 0 / 0
Регистрация: 18.09.2010
Сообщений: 21
|
|
10.07.2013, 01:07 | 15 |
Сообщение от oomomstir
Но только компилятор, что настолько туп, и не может сам сам сообразить, если я требую вернуть значения long long то необходимо перед выполнением операции вычитания преобразовать типы переменных в long long для получения правильного результа и сгенерировать такой код: asrs r2, r0, #31 asrs r3, r1, #31 subs r0, r0, r1 sbcs r1, r2, r3 а не генерить хрень subs r1, r0, r1 asrs r1 r0, #31
0
|
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
|
|
10.07.2013, 01:25 | 16 |
какую хрень ему пишут - такую он и генерит
0
|
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
|
|
10.07.2013, 01:30 | 17 |
Сообщение от DOOMSDOY
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
|
|
10.07.2013, 01:32 | 18 |
Не может.
Во первых, несоответствие стандарту. Тип результата определяется типом аргументов - это аксиома. И люди, которые привыкли к такому поведению - будут очень удивлены самодеятельностью компилятора. Во вторых, это сложно. А си давно разработан, тогда сложно не делали. Но даже в современных языках с навороченным выводом типов (хаскель), если известен тип аргументов - тип результата выведет по ним. В третьих, неоднозначность. Если бы вы вместо long long взяли double и написали бы a/b - какое деление выбирать компилятору? Ну и главное - если программеру нужен результат длиннее, он просто приводит тип одного из аргументов, как предложили я и _pv.
0
|
0 / 0 / 0
Регистрация: 18.09.2010
Сообщений: 21
|
|
10.07.2013, 01:49 | 19 |
Спасибо всем откликнувшимся за советы по существу и не очень по существу:)
0
|
10.07.2013, 01:49 | |
10.07.2013, 01:49 | |
Помогаю со студенческими работами здесь
19
Неправильный результат деления Выводит неправильный результат Неправильный результат формулы Неправильный результат факториала Неправильный результат умножения Выводит неправильный результат Неправильный результат char Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |