jcxz 234 20 января Опубликовано 20 января · Жалоба 23 минуты назад, RR2021 сказал: не всем повезло учится в школах, где в начальных классах преподают разные системы счисления, и то как в двоичном коде представляются float, то что вам повезло очень за вас рад. а у меня всё по простому было Здесь не нужно знание систем счисления. Достаточно только владеть 4-мя базовыми арифметическими операциями. В моём коде выше ничего кроме них и не используется. А "двоичное представление float" - это вообще к чему? И какое оно имеет отношение к вычислениям выше? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RR2021 0 20 января Опубликовано 20 января · Жалоба 5 минут назад, Forger сказал: ну, коли дальше идет работа с дробью, то ухожу во float на время расчетов но исходные данные, особенно инкременты/декременты предпочитаю хранить в целых числах, т.е. "убрать из уравнения" хотя бы источник накопления ошибки ) ну пока что я тоже к такому методу пришёл, совета лучше пока не увидел Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 20 января Опубликовано 20 января · Жалоба 1 минуту назад, RR2021 сказал: ну пока что я тоже к такому методу пришёл, совета лучше пока не увидел Да уж совет просто "супер". Особенно для CPU без FPU. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 20 января Опубликовано 20 января · Жалоба 7 minutes ago, RR2021 said: совета лучше пока не увидел дык, оно всегда приятно, когда простые задачи решаются не менее простыми и очевидными решениями без "магических" чисел и бессмысленной "гуру"-оптимизации на абсолютно ровном месте )) 1 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 20 января Опубликовано 20 января · Жалоба 29 минут назад, Forger сказал: и бессмысленной "гуру"-оптимизации на абсолютно ровном месте )) Да уж... ведь "миллион мух не могут ошибаться". Если они куда-то летят, то видимо там что-то вкусное лежит. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 20 января Опубликовано 20 января · Жалоба 5 minutes ago, jcxz said: "миллион мух не могут ошибаться" А вот и "традиционное" хамство, ожидаемо. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RR2021 0 20 января Опубликовано 20 января (изменено) · Жалоба 2 часа назад, jcxz сказал: ...и таким образом - дважды прибавил ошибку преобразования. На кой??? На кой это надевание трусов через голову? У вас процессор - с FPU или нет? Если с FPU, то почему просто не делать всё во float? Если процессор без FPU, то почему не сдвинуть точку в любую удобную для вычислений позицию 2^n (как советовал выше kolobok0), и не проводить все вычисления в fixed point? Ведь элементарно же все операции можно в fixed point сделать: u32 x = (u32)(458.5 * (1u << 22)); //формат: uq10.22 u32 y = (u32)(385.3 * (1u << 22)); //формат: uq10.22 ... x += (u32)(0.1 * (1u << 22)); //формат: uq10.22 ... u32 result = (u32)(((u64)x << 22) / y); //формат: uq10.22 Здесь у x, y и result точка находится в позиции 1<<22. Но можно выбрать и любую другую, удобную для вычислений позицию точки. Кроме того - в разных местах кода позиция точки может быть разной. Оптимальная позиция точки выбирается исходя из диапазона значений аргументов, диапазона промежуточных и конечных результатов и требуемой точности вычислений. Математика начальных классов школы. PS: Именно отсюда видно - почему во многих случаях оптимальнее позицию точки держать в двоичных разрядах, а не в десятичных. О чём я писал выше. И от чего у некоторых персонажей так подгорало. (458.5 + 0.1) / 385.3 = 1,190241370360758 Берём ваш код uint32_t x = (uint32_t)(458.5 * (1u << 22)); //формат: uq10.22 uint32_t y = (uint32_t)(385.3 * (1u << 22)); //формат: uq10.22 x += (uint32_t)(0.1 * (1u << 22)); uint32_t result = (uint32_t)(((uint64_t)x << 22) / y); result равен 0x004C2CEA первые 10 бит дают 1 а оставшиеся 22 это 0b 00 1100 0010 1100 1110 1010 или 0хC2CEA или в десятичной 797 930 и как это интерпретировать или представить в виде 0,190241370360758 ну т.е. то что после точки ? Изменено 20 января пользователем RR2021 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 20 января Опубликовано 20 января · Жалоба 1 час назад, RR2021 сказал: не всем повезло учится в школах, где в начальных классах преподают разные системы счисления, В любой школе преподают знания от простого к сложному. И системы счисления - это то самое "простое", основы программирования. Если бы вас обучали программированию - вы начинали бы с изучения систем счисления. Если вы учились самостоятельно - вы ошибочно пропустили изучение этого раздела и практика вам показывает, что изучить их нужно. Если вы хотите развиваться в этой области, разумеется. Обижаетесь вы совершенно напрасно. Вам с совершенно благими намерениями предлагают удочку вместо рыбы, чтобы в будущем вы без посторонней помощи могли решить более сложную задачу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 20 января Опубликовано 20 января · Жалоба 17 минут назад, RR2021 сказал: uint32_t result = (uint32_t)(((uint64_t)x << 22) / y); result равен 0x004C2CEA первые 10 бит дают 1 а оставшиеся 22 это 0b 00 1100 0010 1100 1110 1010 или 0хC2CEA или в десятичной 797 930 и как это интерпретировать или представить в виде 0,190241370360758 ну т.е. то что после точки ? Просто возьмите в руки калькулятор и посчитайте: 0x004C2CEA/2^22 = 1.19024133682250977 Т.е. - получилось что и должно. PS: Что такое Q-формат и как в нём работать - почитайте хотя-бы wiki: https://en.wikipedia.org/wiki/Q_(number_format) PPS: И ещё раз повторю: Так действовать имеет смысл только на CPU без FPU, и/или если нужна высокая скорость вычислений. Имеет ли ваш CPU FPU - Вы так и не написали. PPPS: В некоторых случаях даже на CPU с аппаратным FPU вычисления в fixed-point могут быть быстрее, чем во float. Или давать более точный результат (так как мантисса float = всего 24 бита, а в fixed-point она имеет длину 31 или 32 бит (для int/unsigned int ARM) и легко расширяется до бОльших величин если нужно). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RR2021 0 20 января Опубликовано 20 января (изменено) · Жалоба 19 минут назад, jcxz сказал: Имеет ли ваш CPU FPU - Вы так и не написали. нет не имеет , у меня gd32f103rc Изменено 20 января пользователем RR2021 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 20 января Опубликовано 20 января · Жалоба 1 минуту назад, RR2021 сказал: нет не имеет , у меня gd32f103rc Тогда тем более советую изучить Q-формат. Даже если производительность сейчас не особо важна - потом пригодится. Там нет ничего сложного. Когда разберётесь, увидите насколько он эффективен. PS: Если производительность кода не важна, можно конечно просто работать с float или double в режиме программной эмуляции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 20 января Опубликовано 20 января · Жалоба 1 час назад, RR2021 сказал: нет не имеет , у меня gd32f103rc Изменено 47 минут назад Что-то мне подсказывает, что переход в double будет дешевле делений/умножений/приведений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 61 20 января Опубликовано 20 января · Жалоба почему в калькуляторах таких проблем не возникает ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 75 20 января Опубликовано 20 января · Жалоба 31 minutes ago, dimka76 said: почему в калькуляторах таких проблем не возникает ? в bcd считают http://files.righto.com/calculator/TI_calculator_simulator.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 61 20 января Опубликовано 20 января · Жалоба On 1/20/2024 at 5:26 PM, _pv said: в bcd считают Понятно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться