|
OFF: У кого сколько получится: int i = 5; i = ++i + ++i; 🠗 (Asmody 04.08.2019 21:23) | ☑ | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0
ambrozii-fadeevich-s
02.08.19
✎
13:48
|
Смотрю - пошла мода на нестандартные вычисления. У кого сколько получится: int i = 5; i = ++i + ++i;
|
|||||||||||||||||||
47
y88
02.08.19
✎
14:48
|
(46) похоже так. Олипиадная задачка
|
|||||||||||||||||||
48
Йохохо
02.08.19
✎
15:00
|
(46) только вот "++(++5)=7 >> 7+7 = 14" это лишнее чтение, т.к. результат первой операции уже известен. и вообще боян и (45)
|
|||||||||||||||||||
49
bolobol
02.08.19
✎
15:01
|
(48) По запросу "UB" - яндекс выдаёт: ГИБДД - официальный сайт. Вы на что намекаете??
|
|||||||||||||||||||
50
trad
02.08.19
✎
15:04
|
(44)
inc(i)inc(i)+inc(i)+ 6 7 14 8 22 |
|||||||||||||||||||
51
ДенисЧ
02.08.19
✎
15:06
|
||||||||||||||||||||
52
Dionis Sergeevich
02.08.19
✎
15:06
|
Intellij idea выдает 13
|
|||||||||||||||||||
53
1Сергей
02.08.19
✎
15:07
|
(49) Undefined Behaviour
|
|||||||||||||||||||
54
Йохохо
02.08.19
✎
15:12
|
предиктед
|
|||||||||||||||||||
55
Конструктор1С
02.08.19
✎
15:20
|
double a = 1000000.0;
double b = 0.01; for (int i=1; i<=100; i++) a = a + b; System.out.println("a = " + a); сколько думаете будет? |
|||||||||||||||||||
56
bolobol
02.08.19
✎
15:30
|
(55) Слышал, что будет 42, долго считать тут
|
|||||||||||||||||||
57
Dionis Sergeevich
02.08.19
✎
15:33
|
(55) ну логично же что 1000001.0
|
|||||||||||||||||||
58
trad
02.08.19
✎
15:38
|
||||||||||||||||||||
59
mikecool
02.08.19
✎
15:44
|
вот из-за такого мозголомства и надо расписывать операции по строкам
|
|||||||||||||||||||
60
Конструктор1С
02.08.19
✎
15:47
|
(57) не-а
a = 1000001.0000000009 это распространенная багофича с числами с плавающей запятой |
|||||||||||||||||||
61
Dionis Sergeevich
02.08.19
✎
15:49
|
(60) а эта багофича с точки зрения логики как то объяснена?
|
|||||||||||||||||||
62
bolobol
02.08.19
✎
15:54
|
(61) Свободный ради-кал?
|
|||||||||||||||||||
63
Конструктор1С
02.08.19
✎
15:55
|
(61) х.з. Ну типа особенности работы с такими числами
|
|||||||||||||||||||
64
Провинциальный 1сник
02.08.19
✎
15:57
|
(19) Подавляющее большинство багов и уязвимостей в софте - именно тяжкое наследие языка Си. Писали бы на паскале - всё было бы стабильнее на порядок.
|
|||||||||||||||||||
65
Fish
02.08.19
✎
15:58
|
(64) А если бы на 1С, то стабильнее на 10 порядков :)
|
|||||||||||||||||||
66
Конструктор1С
02.08.19
✎
16:03
|
double a1 = 1000000.0;
double a2 = 100000.0; double b = 0.01; for (int i=1; i<=100; i++) { a1 = a1 + b; a2 = a2 + b; } System.out.println("a1 = " + a1); System.out.println("a2 = " + a2); _________________________________________ a1 = 1000001.0000000009 a2 = 100000.99999999948 вот такие пироги |
|||||||||||||||||||
67
bolobol
02.08.19
✎
16:11
|
(64) И тормознее на порядок порядков. Это не наследие Си - это сопроцессор математический
|
|||||||||||||||||||
68
Провинциальный 1сник
02.08.19
✎
16:15
|
(67) Не преувеличивайте. Софт, написанный на паскале (тот же QIP к примеру) не тормознее сишного. Си - это переносимый ассемблер, для написания ядер и драйверов. То, что его начали использовать не по назначению, огромная ошибка отрасли, которая аукается до сих пор..
|
|||||||||||||||||||
69
Глок 17
02.08.19
✎
16:15
|
(0) В уме считал по человеческой логике, получилось 13.
Проверил на компе, тоже получилось 13 13 |
|||||||||||||||||||
70
bolobol
02.08.19
✎
16:18
|
(68) Я писал программы и на том и на том - разница достигала х100 в производительности
|
|||||||||||||||||||
71
Провинциальный 1сник
02.08.19
✎
16:19
|
(70) А на ассемблере еще быстрее будет, если правильно написать.. это не аргумент. Всё зависит от конкретного компилятора и от примененного алгоритма.
|
|||||||||||||||||||
72
bolobol
02.08.19
✎
16:23
|
(71) А, ну если "не аргумент" и "от алгоритма"... тогда - "Ваша точка зрения ясна..." и бла-бла-бла- все дела
|
|||||||||||||||||||
73
Глок 17
02.08.19
✎
16:25
|
(71) Писал на ассемблере преобразователь частоты в 2/3 раза. Для считывания показаний датчика оборотов с мотора для передачи в тахометр при замене двигателя с 4х цилиндров на 6 цилиндров. Программа заняла 10 байтов, один цикл рассчетов выполнялся за 3 такта. Попробуй на паскале написать, сколько тактов займет
|
|||||||||||||||||||
74
Кирпич
02.08.19
✎
16:27
|
(70) между разными компиляторами Си тоже может быть разница х100
|
|||||||||||||||||||
75
Глок 17
02.08.19
✎
16:31
|
У кого получается не 13, вы как считали? Что за бредятина
|
|||||||||||||||||||
76
bolobol
02.08.19
✎
16:33
|
(75) "Всё не читал, но осуждаю"?
|
|||||||||||||||||||
77
Глок 17
02.08.19
✎
16:34
|
(76) По шагам расписываю:
i = ++i + ++i; 1. Считаем первое слагаемое: ++i = ++5 = 6. 6 записывается в i 2. Считаем второе слагаемое: ++i = ++6 = 7 3. Складываем оба слагаемых: 6 + 7 = 13 Куда проще? |
|||||||||||||||||||
78
Глок 17
02.08.19
✎
16:40
|
(26) >> Дело в том что инкремент записывается в одну и ту же ячейку памяти
Это ошибка. Результат двух выражений не должен записываться в одну и ту же ячейку памяти. Если бы компилятор так работал, то это был бы дичайший баг. |
|||||||||||||||||||
79
bolobol
02.08.19
✎
16:42
|
(77) То есть, всё-таки, "чукча не читатель"... в (46) и в (50) двумя вариантами описано явление 14-ти в ответ.
|
|||||||||||||||||||
80
Dionis Sergeevich
02.08.19
✎
16:44
|
(77) я думаю что тут дело в IDE - некоторые, вычисоив первое а++ запомнили значение, а не указатель, другие наоборот
|
|||||||||||||||||||
81
Глок 17
02.08.19
✎
16:45
|
(79) Так это ты чукча не читатель. Я же разжевал все подробно в (77). А в (46) вообще какой-то бред написан.
|
|||||||||||||||||||
82
Dionis Sergeevich
02.08.19
✎
16:46
|
В итоге в случае с заполненным значением 6 + 7, а с заполненной ссылкой а + а
|
|||||||||||||||||||
83
Глок 17
02.08.19
✎
16:46
|
(80) Не важно что ты запомнишь, указатель или значение. Сам подумай. Выполнилось выражение, его значение записалось в новую ячейку памяти. Выполнили то же самое выражение. С какого перепугу мы будем записывать новый результат в уже занятую ячейку, а не в новую?
|
|||||||||||||||||||
84
Dionis Sergeevich
02.08.19
✎
16:47
|
*запомненной
|
|||||||||||||||||||
85
Глок 17
02.08.19
✎
16:47
|
(82) Ссылки должно получиться две разных
|
|||||||||||||||||||
86
Глок 17
02.08.19
✎
16:48
|
++ это оператор, которые не только увеличивает значение переменной, но и ВОЗВРАЩАЕТ результат инкремента. Мы складываем не значения переменной i, а результаты, которые вернули два разных оператора инкремента.
|
|||||||||||||||||||
87
Dionis Sergeevich
02.08.19
✎
16:48
|
(83) дело в том что инкремент присваивает результат переменной, поэтому в указателе значение 7, а + а даст 14. А в случае работы со значениями - результат первого инкремента будет запомнен до второго инкремента
|
|||||||||||||||||||
88
Глок 17
02.08.19
✎
16:49
|
(87) Я заранее ответил на это чуть выше
|
|||||||||||||||||||
89
Глок 17
02.08.19
✎
16:50
|
(87) в указателе на i згачение 7. а в указателе на предыдущий результат выполнения значение 6
|
|||||||||||||||||||
90
Глок 17
02.08.19
✎
16:52
|
У (++i) и у (i) должны быть разные указатели. Иначе будет неправильный результат в виде 14.
|
|||||||||||||||||||
91
Глок 17
02.08.19
✎
16:53
|
Но по правилам хорошего программирования писать как в (0) конечно же запрещено на любом яп.
|
|||||||||||||||||||
92
Nyoko
02.08.19
✎
16:56
|
6+8=14
14 |
|||||||||||||||||||
93
Конструктор1С
02.08.19
✎
17:34
|
(92) а почему 8?
|
|||||||||||||||||||
94
Глок 17
02.08.19
✎
18:02
|
10 + 6 = 16
16 |
|||||||||||||||||||
95
v77
02.08.19
✎
18:31
|
(86) "++ это оператор, которые не только увеличивает значение переменной, но и ВОЗВРАЩАЕТ результат инкремента."
Это с сегодняшнего дня? Надо запомнить. |
|||||||||||||||||||
96
Глок 17
02.08.19
✎
18:36
|
(95) Лучше запомни если не можешь понять
|
|||||||||||||||||||
97
Глок 17
02.08.19
✎
18:40
|
The increment and decrement operators will add one (+1) or subtract one (-1), respectively, to their operand, and then return a value.
|
|||||||||||||||||||
98
v77
02.08.19
✎
18:41
|
(96) Ну я как бы понимаю, что 14 получится. Вот ты не можешь понять и выдумываешь какие то новые правила и отрицаешь реальность.
14 |
|||||||||||||||||||
99
Глок 17
02.08.19
✎
18:43
|
(98) Но ты не правильно понимаешь, поэтому не хочешь принять правила, и выдумываешь свои
|
|||||||||||||||||||
100
v77
02.08.19
✎
18:44
|
(97) но создатели компиляторов Си делают по своему. от бунтари :)
|
|||||||||||||||||||
101
Глок 17
02.08.19
✎
18:46
|
(100) не все, а только криворукие.
Выражение (0) нужно упростить для однозначности, чтобы даже v77 было понятно: i = 5; ++i; a2 = i; ++i; a2 = i; i = a1 + a2; |
|||||||||||||||||||
102
Глок 17
02.08.19
✎
18:47
|
Опечатка, в первом присвоении a1 вместо а2
|
|||||||||||||||||||
103
Глок 17
02.08.19
✎
18:48
|
Если выражение вызывает непонятки, его всегда нужно раскладывать. Тогда ошибок будет меньше
|
|||||||||||||||||||
104
v77
02.08.19
✎
18:49
|
(101) Криворукие это компиляторы GCC, Microsoft и Clang, я так понимаю. А какие тогда правильные компиляторы?
|
|||||||||||||||||||
105
Глок 17
02.08.19
✎
18:49
|
(104) Там где результат 13
|
|||||||||||||||||||
106
NorthWind
02.08.19
✎
18:58
|
(105) неверно ты разложил. Подвох в том, что сначала по правилам приоритета выполняются все i++, и только потом происходит сложение. В результате складывается не 7 и 6, а 7 и 7. А если сделать ++i + ++i + ++i, то будет уже 8 + 8 + 8 = 24... ну и так далее.
|
|||||||||||||||||||
107
Глок 17
02.08.19
✎
19:02
|
(106) Ну и откуда у тебя в первом слагаемом 7, если сначала мы получаем 6? Во втором получаем 7. Затем по логике мы должны сложить результаты предыдущих вычислений, а не то что сейчас хранится в переменной i. Ты просто пытаещься подогнать логику под сишный компилятор, из-за чего она страдает.
|
|||||||||||||||||||
108
Глок 17
02.08.19
✎
19:10
|
Вот аналог того что в (0):
(i = 6) + (i = 7) Какой результат будет у этого бредового выражения? |
|||||||||||||||||||
109
Глок 17
02.08.19
✎
19:12
|
Из первых скобок выползет результат 6, из вторых выползет 7, затем они сложатся, получится 13. В i будет записано 7, но нам пофиг что там, потому что мы складываем не i + i, а результаты операций в скобках.
|
|||||||||||||||||||
110
NorthWind
02.08.19
✎
19:35
|
(107) Нет. См. (35). Там пипец какая интересная табличка. Приоритетной операцией, причем с очень высоким приоритетом, являются прединкремент. Приоритет ВЫШЕ умножения и деления! Сначала, вперед всех остальных, в данном случае выполнятся они. Сколько их будет - столько и выполнятся. И только потом пойдет сложение уже над выполненными прединкрементами. Поэтому 7 + 7.
|
|||||||||||||||||||
111
v77
02.08.19
✎
19:47
|
Надо определиться сначала о каком языке речь. В Java и C# будет 13. В Си будет 14
|
|||||||||||||||||||
112
ДенисЧ
03.08.19
✎
20:39
|
||||||||||||||||||||
113
stopa85
03.08.19
✎
20:59
|
С++ даст 14, а вот ява или си шарп 13.
14 |
|||||||||||||||||||
114
Конструктор1С
04.08.19
✎
11:41
|
(113) таки, а почему вы предлагаете ровняться на плюсы?
|
|||||||||||||||||||
115
Фрэнки
04.08.19
✎
11:43
|
(114) скажу для поддержки разговора, что 1С платформа написана на С++ :-)
|
|||||||||||||||||||
116
NorthWind
04.08.19
✎
18:30
|
(114) а таки, собственно, почему бы и нет?
|
|||||||||||||||||||
117
Глобальный_
Поиск 04.08.19
✎
20:01
|
Чё за дебильный код? Почему+++++++19 а нельзя написать +20, это кстати сэкономит байты.
|
|||||||||||||||||||
118
Глобальный_
Поиск 04.08.19
✎
20:02
|
Инкреметы они оптимизируют.ну и пишите на ассемблере тогда
|
|||||||||||||||||||
119
Глобальный_
Поиск 04.08.19
✎
20:07
|
Когда количество библиотек в миллионы раз превышает количество кода , играться плюсами и пузырьками это удел преподов на первом курсе.
|
|||||||||||||||||||
120
Глобальный_
Поиск 04.08.19
✎
20:09
|
Выдохнул :)
|
|||||||||||||||||||
121
stopa85
04.08.19
✎
21:17
|
(114) не было бы плюсов, не было бы этой загадки. Она, кстати, очень важна для понимания языка.
|
|||||||||||||||||||
122
DrZombi
гуру
05.08.19
✎
06:54
|
10 :)
Другое |
|||||||||||||||||||
123
DrZombi
гуру
05.08.19
✎
06:54
|
(117) Видимо автору языка, было так интересней извращаться :)
|
|||||||||||||||||||
124
DrZombi
гуру
05.08.19
✎
06:55
|
+(122) Тут так то не описано, что за язык, что за математика... :)
|
|||||||||||||||||||
125
Провинциальный 1сник
05.08.19
✎
11:25
|
(110) При чем тут приоритет.. Даже со всеми приоритетами, когда мы выполняем сложение, мы по логике должны взять уже рассчитанный РАНЕЕ первый операнд (++i), а не пытаться его рассчитать ЕЩЕ РАЗ после второго(++i). И будет 13. Если компилятор С++ выдает 14 - это очередное подтверждение тезиса что Си - плохой язык.
13 |
|||||||||||||||||||
126
bolobol
05.08.19
✎
12:42
|
(125) Глупости, никаких "ещё раз" в примере нет. Есть две операции увеличения i _до_сложения.
|
|||||||||||||||||||
127
Провинциальный 1сник
05.08.19
✎
13:33
|
(126) ++i - это инкремент переменной и одновременно возврат этого увеличенного значения в вызывающее выражение. То есть, если в выражении ++i встречается дважды, то и вычислено оно будет дважды.. сначала от исходного значения, потом от уже вычисленного. И только потом сложены эти промежуточные результаты. И получается 13. Вообще не понимаю, как может быть 14.
|
|||||||||||||||||||
128
Smile 8D
05.08.19
✎
13:37
|
(106) Вы так уверенно рассуждаете, но выше в (46) уже написали, что ++i + ++i + ++i дает 22, а не 24, что можно проверить в компиляторе с++, на который так же давали выше ссылку. К сожалению, при 3х слагаемых правила уже работают по другому.
|
|||||||||||||||||||
129
Smile 8D
05.08.19
✎
13:44
|
(127) Не забывайте, что ++i прибавляет и возвращает значение в выражение, а i++ сначала возвращает, а затем уже прибавляет. И ваш негатив в сторону языков, в которых это используется, вызван скорее непониманием зачем эти механизмы были придуманы. Естественно, что пример из загадки искусственный, а инкременты реально используются обычно при вызовах из разных процедур\потоков, где требуется использовать текущее значение и параллельно его изменить.
|
|||||||||||||||||||
130
Провинциальный 1сник
05.08.19
✎
13:47
|
(129) Согласен, прибавляет и возвращает. Первый операнд 6 после инкремента, второй 7 после инкремента. Потом выполяем сложение. Получаем 6+7=13. Почему 14 то???
|
|||||||||||||||||||
131
Smile 8D
05.08.19
✎
13:51
|
(130) Ну про это уже выше написали, что приоритет у операции выше, чем у сложения, даже ссылку кидали. Вы же не возмущаетесь, что умножение выполняют раньше чем сложение.
А вот почему при 3х слагаемых логика меняется мне непонятно и не нравится) |
|||||||||||||||||||
132
Провинциальный 1сник
05.08.19
✎
13:56
|
(131) Так я не спорю о приоритетах! И рассуждаю именно в смысле того, что СНАЧАЛА делаем инкременты и возвращаем значения инкрементов, и только потом складываем. Но откуда 14?
|
|||||||||||||||||||
133
bolobol
05.08.19
✎
14:03
|
(132) Ещё один "нечитатель". Ранее всё по полочкам разложено было неоднократно. И ладно когда тролль только зарегистрированный делает вид что не видит...
|
|||||||||||||||||||
134
Провинциальный 1сник
05.08.19
✎
14:09
|
(133) Блин, ну ткните пальцем, ГДЕ разжовано? Читаю, вижу логичные предпосылки, потом бац - парадоксальный вывод.
|
|||||||||||||||||||
135
Провинциальный 1сник
05.08.19
✎
14:10
|
+(134) Откуда берется семерка в первом операнде???
|
|||||||||||||||||||
136
bolobol
05.08.19
✎
14:16
|
(135) в (46) и в (50) - двумя языками изложено
|
|||||||||||||||||||
137
Провинциальный 1сник
05.08.19
✎
14:17
|
А, понял. Если строить дерево вычисления выражения по приоритетам, то будет именно 13. Но если считать сишным способом "инкремент записывается в одну и ту же ячейку памяти, и в результате к тому моменту когда надо сложить два слагаемых, складывается в реальности уже 7 и 7, а не 7 и 6", тогда понятно. Но блин, символ в одном месте выражения и в другом - это НЕ ОДНА ячейка памяти, а узел в дереве расчета. А тут получается "дерево-мутант". Си - плохой язык.
|
|||||||||||||||||||
138
bolobol
05.08.19
✎
14:24
|
(137) Позволю себе не согласиться. Использование одной и той же переменной (й+й) не должно вызывать два чтения и два помещения в разные регистры для дальнейшего сложения. Именно из-за этого, программы на Си и работают в х100 раз быстрее альтернативно одарённых языков.
|
|||||||||||||||||||
139
Провинциальный 1сник
05.08.19
✎
14:45
|
На лурке тема разжована, оказывается это древний баянище)
http://lurkmore.to/%2B%2Bi_%2B_%2B%2Bi |
|||||||||||||||||||
140
Глок 17
05.08.19
✎
17:35
|
(110) Ты не понял. Понятно что инкремент имеет высокий приоритет. Но почему ты продолжаешь складывать 7 + 7, если результаты инкоементов нам дали два слагаемых: 6 и 7?
|
|||||||||||||||||||
141
Глок 17
05.08.19
✎
17:43
|
(138) >> Именно из-за этого, программы на Си и работают в х100 раз быстрее альтернативно одарённых языков.
Ага. Только выдают не тот результат, который нужен. Главное быстро :))) |
|||||||||||||||||||
142
Глок 17
05.08.19
✎
17:45
|
Чтобы выражение (0) правильно работало на Си, нужно его преобразовать:
int i = 5; int tmp = ++i; i = tmp + ++i; |
|||||||||||||||||||
143
stopa85
07.08.19
✎
19:16
|
(127) нет не правильно. В С++ операция ++i возвращает ссылку на объект (указатель на область памяти, где записано значение), а не копию объекта. Ты путаешь с java и c#.
Вот и получается, что по этому указателю в ОЗУ компьютера находится значение и увеличивается на 1. Потом оно находится еще раз и увеличивается на один еще раз. Потом складывается само с собой. Это нужно понимать. Это, что ли, философия языка. |
|||||||||||||||||||
144
ambrozii-fadeevich-s
09.08.19
✎
11:11
|
(139) Это намного древнее баянище.
(142) |
|||||||||||||||||||
145
ambrozii-fadeevich-s
09.08.19
✎
11:14
|
(142) Если правильно преобразовать, то получится не то, что ожидает среднестатистический интерпретатор
int i = 5; ++i; ++i; i = i + i; |
|||||||||||||||||||
146
ambrozii-fadeevich-s
09.08.19
✎
11:15
|
пятница же!
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |