Ардуинщики всех стран - объединяйтесь! В этом форуме, конечно.
Ответить

Прошу помочь разобраться - кто хуже в школе учился я или МК?

Вт фев 28, 2023 22:44:13

Столкнулся с интересным феноменом, ковыряя ардуину со сдвиговым регистром 74HC595: встроенная в среду функция возведения в степень (pow()) работает на мой взгляд некорректно. Потребовалось мне двоечку в степень n возводить, а само число в виде переменной оформлено, которой разные целые значения присваиваются. Но прикол в том, что если например 2^0 или 2^1 считаются правильно, то все остальное на 1 меньше ожидаемого результата, то есть 2^2=3, 2^3=7, 2^4=15 и т.д. Помучался я с этим немного, плюнул, сделал все через битовый сдвиг, но осадочек остался. Может кто сталкивался с подобным поведением?

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Вт фев 28, 2023 22:57:13

тип аргументов pow() - с плавающей запятой. результат тоже .Приведение к целому вполне может сделать на 1 меньше.

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Вт фев 28, 2023 23:09:54

тип аргументов pow() - с плавающей запятой. результат тоже .Приведение к целому вполне может сделать на 1 меньше.

Ну я так и понял - функция весьма кривая - как и все ардуиновское. Недавно хотел по быстрому с TM1628 разобраться используя библиотеки - исплевался от злости, а решения так и не нашел. Плюнул и внял способу RTFM - только после этого все получилось в лучшем виде. MAX5400 так же осваивал - под него вообще библиотек нет. Библиотеки это зло...

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Вт фев 28, 2023 23:20:11

Функция не кривая. У Вас неверное представление о машинных арифметических действиях с разными типами данных. Думаете, в других мк/языках/средах нет подобных нюансов? Ещё как есть.
И библиотеки не зло.

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 08:08:12

Martian писал(а):Думаете, в других мк/языках/средах нет подобных нюансов? Ещё как есть.


Еще как ! Иногда тратится очень много времени на поиски таких "чудес" :)

Исходно, процессор кроме как складывать, вообще ничего не умеет :)

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 08:14:31

Исходно, процессор кроме как складывать, вообще ничего не умеет :)
Не только процессор! Топикстартер тоже. Он, похоже, не знает, что возведение в (любую) степень делается через логарифм и экспоненту, а ожидает от МК лишь целочисленных умножений, суть многократных сложений. Плохо, видать, в школе учился...

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 09:40:15

Не знание не грех, грех нежелание учится.
Человек спросил, ему подсказали.

П.С. Я в школе плохо учился. Скучно было.

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 11:10:51

Неее, МК по Википедии учился.... Он и этого не знает...

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 12:39:13

Все мы, чего ни будь, да не знаем.
Форум для того и нужен, чтобы делится информацией, а не в школу отправлять:)

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 14:42:54

Мне тут недавно одну принцессу пытались подсунуть прорепетировать по математике. Никак не может выучить таблицу умножения... Ни привелегированный лицей, ни четверо репетиторов ничего поделать не смогли...

И я сразу отказался, когда выяснил, что она не сможет выучить эту таблицу просто по той причине, что она не знает, что такое умножение.
Просто не знает. А так же не знает, что такое сложение. И не узнает, поскольку не знает, что такое числа.
И ЗНАТЬ НЕ ЖЕЛАЕТ, ПОТОМУ ЧТО ЕЕ ВЫСОЧЕСТВУ ЭТО НАФИГ НЕ НУЖНО !!!

Хотите с ней поделиться какой-нибудь информацией ?

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 15:31:44

Чего то меня тут в лоток я смотрю усиленно натыкать пытаются. Однако: я беру два ЦЕЛЫХ БЕЗЗНАКОВЫХ ЧИСЛА формата uint16_t, одно из которых основание, второе показатель. Допустим основание = 2, показатель = 2. По всей логике формула счастья квадрат числа это число умноженное само на себя и выглядит это следующим образом: 2*2=4. Просто и верно.

Теперь ардуина:

uint16_t a = 2;
uint16_t b = 2;

uint16_t c = pow(a,b); // результат равен 3

В чем проблема?

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 15:41:38

я же сказал. pow() оперирует числами с плавающей запятой. Подсовывайте хоть строки, хоть цвет - будет выполнено приведение к числам с плавающей запятой. Арифметические операции над такими числами отличаются от тех, каким Вас обучали в школе. Да и само число уже будет не то. В итоге получите результат 3.99999999999999999999999, что при приведении к целому даст 3.
Либо работайте с соответствующими типами, как аргументов, так и результата, либо учитывайте нюансы приведения-округления к целочисленным типам. Например, добавляйте 0.5

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 16:36:10

Муркиз писал(а): Никак не может выучить таблицу умножения...


Я тоже не знаю таблицы умножения. Но двузначные числа множу в уме существенно быстрее тех кто знает :)

Муркиз писал(а): И не узнает, поскольку не знает, что такое числа.


Многие ли с ходу смогут объяснить, что такое числа ? :)

Да и девицы, они про другое :)

Martian писал(а):я же сказал. pow() оперирует числами с плавающей запятой. Подсовывайте хоть строки, хоть цвет - будет выполнено приведение к числам с плавающей запятой. Арифметические операции над такими числами отличаются от тех, каким Вас обучали в школе. Да и само число уже будет не то. В итоге получите результат 3.99999999999999999999999, что при приведении к целому даст 3.


Вроде все верно, но все же по правилам округления тут 4 должно быть, а не отсечение дробной... странно. Хотя я не спец по ардуино

Добавлено after 16 minutes 20 seconds:
Re: Прошу помочь разобраться - кто хуже в школе учился я или МК?
Возможно, к результату стоит применить какую либо функцию преобразования ? Чтобы по правилам?

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 16:45:28

Alexey1969, приведение к целочисленному типу, что и происходит у ТС, просто отбрасывает дробную часть. Вот если бы использовать округление, то тогда начнут работать правила всякие, а-ля к ближайшему целому, к меньшему, к большему и т.д.

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 16:48:27

Чего то меня тут в лоток я смотрю усиленно натыкать пытаются.
И правильно делают!
квадрат числа это число умноженное само на себя и выглядит это следующим образом: 2*2=4. Просто и верно. Теперь ардуина:
uint16_t a = 2;
uint16_t b = 2;
uint16_t c = pow(a,b); // результат равен 3
А при чём тут ардуина и при чём тут квадрат? Разве это она написала "pow(a,b)" ? Хотите квадрат? Тогда пишите 2*2. Хотите степень? Тогда не пишите 2*2. Степень — это ни разу не квадрат.
В чем проблема?
Я не знаю, в чём у вас проблема, но вот только что добавил в в свой проект на атмеге48 три ваших строчки и заказал delay(c)
uint16_t a = 2;
uint16_t b = 2;
uint16_t c = pow(a,b);
delay(c);
и вот что ардуина 1.8.13 мне накомпилировала:
ldi r22, 0x04 ; 4
ldi r23, 0x00 ; 0
ldi r24, 0x00 ; 0
ldi r25, 0x00 ; 0
rcall .-1574 ; 0x1c6 <delay>
Только не говорите, что в r22 лежит тройка. И заметьте, ардуина не стала поручать вычисления контроллеру, а преобразовала их в константу. Похоже, проблема-то не в ардуине, а в вашем неумении ею пользоваться. Ошибиться в трёх строчках...

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 17:19:48

Проблема в том, что округление по умолчанию производится простым отбрасывание дробной части. И если вычисленный результат хоть 1 в десять в минус 16 степени меньше 4, то ответ будет все равно 3.

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 19:24:33

я же сказал. pow() оперирует числами с плавающей запятой. Подсовывайте хоть строки, хоть цвет - будет выполнено приведение к числам с плавающей запятой. Арифметические операции над такими числами отличаются от тех, каким Вас обучали в школе. Да и само число уже будет не то. В итоге получите результат 3.99999999999999999999999, что при приведении к целому даст 3.
Либо работайте с соответствующими типами, как аргументов, так и результата, либо учитывайте нюансы приведения-округления к целочисленным типам. Например, добавляйте 0.5


Да это понятно, сама функция принимает как аргументы числа с плавающей запятой двойной точности. Дело не в том. Проблема в том, что мне нужно было всего лишь посчитать степени ЦЕЛЫХ ЧИСЕЛ. Речи о плавающей точке не было изначально, поэтому и удивился, что происходит такое округление - результат возведения в степень то принимает ЦЕЛОЧИСЛЕННАЯ переменная, естественно, если 2^2 функция pow считает как 3.99999 и так до бесконечности, после округления 4 мы никогда не получим. Но мне то нужна была работа с ЦЕЛЫМИ. Исходя из этого, если я не могу с помощью данной функции без костылей получить тот результат, который ожидается, имею полное право считать эту функцию ущербной. Никогда ею не пользовался, а тут потребовалось по быстрому бегущий огонек на трех регистрах сочинить для ребенка - решил его через степень двойки организовать от лени и на такие вилы напоролся. Программа примитивная до безобразия - считаем степень двойки от 0 до 23 и кормим три регистра результатом . Я даже delay в нее воткнул, ибо настолько все примитивно - казалось бы, ан нет - вилы с плавающей точкой приехали. И, прошу заметить, тот же инженерный калькулятор, при вводе целочисленных значений, целочисленные же и выдает, а не парит мозги с кучей девяток после запятой - наверное его создатели тоже в школе плохо учились...

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 20:10:34

Проблема в том, что мне нужно было всего лишь посчитать степени ЦЕЛЫХ ЧИСЕЛ.
Отнюдь! Проблема вовсе не в том. Вам вообще не нужно было считать степени. Никаких чисел. Бегущие огни делаются не на степенях, а на сдвиге.
потребовалось по быстрому бегущий огонек на трех регистрах сочинить для ребенка - решил его через степень двойки организовать от лени
Да не от лени, а от незнания! От того, что никогда не разрабатывали схем бегущих огней. Вот бы посмотреть на ваше возведение в степень на 155-й серии! Особенно, если основание, скажем, 3 или 5.
Программа примитивная до безобразия - считаем степень двойки от 0 до 23 и кормим три регистра результатом .
Она не примитивна (до безобразия), а крива до того же самого безобразия! Это всё равно, что забивать гвозди микроскопом. Для забивания гвоздей есть же неубиваемый инструмент — молоток, то бишь сдвиг. В отличие от возведения в степень он работает хоть влево, хоть вправо, и выполняется за одну машинную команду (в отличие от даже целочисленной степени, которой нужно умножение), да пусть бы даже за 4 команды, если мы берём длинное целое на 32 бита, это всё равно быстрее умножения и тем паче возведения в степень. А ещё по ходу сдвига очень удобно подкидывать на приёмный вход очередные биты, вплоть до закольцовывания, как это делалось в многочисленных схемах бегущих огней в 80-е годы. Ваша самая главная ошибка была сделана на этапе алгоритмизации, и тут ни ардуина, ни какой-нибудь ещё язык программирования ни при чём. Тем более, что на поверку-то оказалось, что ардуина операцию pow(2,2) в целых числах считает как 4. Не 3 и не 5, а ровно 4. Зачем было применять float, если нужен был целочисленный результат?

P.S.: А ещё сдвиг влево — это сложение числа с самим собой. Поэтому для вычисления последовательных степеней двойки от нуля до, скажем, 24, надо (можно в цикле) складывать число само с собой. 1+1=2, 2+2=4, 4+4=8, 8+8=16 и т.д. ещё 20 раз. Это тоже одна машинная команда, но она неповоротлива (сдвигает только влево) как кувалда. А на процессорах 8080 ещё и тяжела как кувалда, ибо за один машинный цикл сдвигает сразу 16-разрядное число. Посему мне непонятно желание забивать гвозди не молотком, не кувалдой, а именно микроскопом... Это не похоже на лень. Это что-то другое.

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 20:39:59

Блин, Женя, тебя не Краб часом покусал? Все тебе не то. А тебя не смутило ни разу, что для этой поделки еще и целая ардуина на 328 камне взята, когда тини 13 та же справилась бы без проблем, а еще 99,999999% времени тупо курила бездельничая. Я же написал, что все на сдвиге и сделал в итоге. Изначально было лениво, решил изъебнуться - результат удивил и обескуражил, поэтому и вопрос такой задал.Не пользовался я никогда этой функцией просто, а тут такой казус вышел. У этой задачи способов решения хренова туча, вплоть до перебора массива констант - дело то не в этом. Обработать переменную как надо и пнуть 3 байта через порт в сторону регистров это примитивная задача.

Добавлено after 5 minutes 45 seconds:
Re: Прошу помочь разобраться - кто хуже в школе учился я или МК?
И с чего ты вдруг решил, что я float использовал, если внезапно uint16_t был озвучен?
И, если не затруднит, продемонстрируйте пожалуйста код, в котором pow(2,2); без костылей результат 4 дает.

Re: Прошу помочь разобраться - кто хуже в школе учился я или

Ср мар 01, 2023 20:44:43

Viper_Snake писал(а):Исходя из этого, если я не могу с помощью данной функции без костылей получить тот результат, который ожидается, имею полное право считать эту функцию ущербной.
Нет. Эта функция изначально такая в Си. Просто надо как-то помнить язык, ну и в случае непонятных результатов всегда обращать в первую очередь внимание на типы. Сколько граблей поломано даже с простым знаковое-беззнаковое, когда по ошибке не то взято. А плавающая точка это всегда источник счастия...
Ответить