RR2021 0 13 января Опубликовано 13 января · Жалоба в общем вот выделил вот кусочек кода где коэффициенту приравнивается 1 прибавляется 0.1 и получается 1.0000002 почему это происходит а главное что с этим делать ну если например надо циклически увеличивать коэффициент на 0.1 там со временем прилично набегает и расчёты кривые получаются Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1113 7 13 января Опубликовано 13 января · Жалоба 9 minutes ago, RR2021 said: почему это происходит потому что способ кодирования float не позволяет получить строго константу 0.1 12 minutes ago, RR2021 said: что с этим делать float это двоичная кодировка, переводите расчет с десятичной на двоичную математику. ну или увеличивайте точность переменных 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
engel65536 12 13 января Опубликовано 13 января · Жалоба 11 minutes ago, RR2021 said: что с этим делать ну если например надо циклически увеличивать коэффициент на 0.1 там со временем прилично набегает и расчёты кривые получаются Делаете циклическое увеличение целочисленного значения и на каждой итерации пересчитываете своё дробное значение из него. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 13 января Опубликовано 13 января · Жалоба Если важно точное значение, то умножьте оба числа на 10 (мысленно) и запишите int k_L = 10; k_L += 1; , а потом по месту применения в формуле поделите на 10. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RR2021 0 13 января Опубликовано 13 января · Жалоба всем спасибо! если записывать в int всё работает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1113 7 13 января Опубликовано 13 января · Жалоба 44 minutes ago, RR2021 said: всем спасибо! если записывать в int всё работает и как вам удалось записать в int 0.1? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 49 13 января Опубликовано 13 января · Жалоба 12 минут назад, 1113 сказал: и как вам удалось записать в int 0.1? Записать-то можно, вот что при считывании будет)))))))))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 13 января Опубликовано 13 января · Жалоба 20 minutes ago, 1113 said: и как вам удалось записать в int 0.1? если инкремент всегда кратен 0.1 и бОльшая точность не требуется, то проще перейти в целые числа и в таком виде хранить данные (х10). Т.е. инкремент на 0.1 будет значить +1, без всякой дробной части. Для удобства саму переменную можно назвать так, чтобы это отражалось в сути хранения в ней данных. Да, костыль, но вполне рабочий. Главное просто потом не запутаться ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 62 13 января Опубликовано 13 января · Жалоба On 1/13/2024 at 5:04 PM, 1113 said: потому что способ кодирования float не позволяет получить строго константу 0.1 Ну, не до такой же степени, что 0.1 превращается в 0.0000002. On 1/13/2024 at 4:54 PM, RR2021 said: в общем вот выделил вот кусочек кода где коэффициенту приравнивается 1 прибавляется 0.1 и получается 1.0000002 почему это происходит а главное что с этим делать ну если например надо циклически увеличивать коэффициент на 0.1 там со временем прилично набегает и расчёты кривые получаются Вы пишите одно, а в картинках приводите другое. У вас в отладчике не 1.0000002, а 1.1000002. И причем картинки, которые вы привели очень плохо читаются. Результаты вычисления очень тяжело разглядеть. Судя по отладчику, ваш k_L это float, а числа, которые вы присваиваете и прибавляете к k_L являются типом double !!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 43 13 января Опубликовано 13 января · Жалоба 2 hours ago, RR2021 said: приравнивается 1 прибавляется 0.1 и получается 1.0000002 Числа записаны не правильно. Прочитайте о том, как в С записываются числа с плавающей точкой и почему их надо записывать не так как у вас. Нет, их можно записывать так как на скриншоте, но тогда возникает вопрос, указанный в теме. Подсказка: обратите внимание, что в дизассемблере присутствует вызов преобразования float в double. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 14 января Опубликовано 14 января · Жалоба On 1/13/2024 at 5:28 PM, EdgeAligned said: Если важно точное значение, то умножьте оба числа на 10 (мысленно) и запишите int k_L = 10; k_L += 1; , а потом по месту применения в формуле поделите на 10. 23 hours ago, Forger said: если инкремент всегда кратен 0.1 и бОльшая точность не требуется, то проще перейти в целые числа и в таком виде хранить данные (х10). Т.е. инкремент на 0.1 будет значить +1, без всякой дробной части. Для удобства саму переменную можно назвать так, чтобы это отражалось в сути хранения в ней данных. Да, костыль, но вполне рабочий. Главное просто потом не запутаться ) Если идёт речь про МК, то лучше умножать на 65536. А у результата тупо откидывать младшее слово. Ну или делить на 65536. Так точнее будет и/или быстрее. Можно (если есть промежуточные сомножители-коэффициенты) сразу их выразить через данный числитель. (круглый) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 14 января Опубликовано 14 января · Жалоба 17 minutes ago, kolobok0 said: Если идёт речь про МК, то лучше умножать на 65536. а почему не 32768? Почему не 16384 и т.д. Я частенько применяю такой принцип - хранение в целых числах. Это и работает гораздо быстрее и нет подобных ошибок. Но стараюсь использовать величины кратные "трем нулям": 1/1000, 1/1000000 .... делая соотв. приписки к имени переменной: valueXXX_ms, timeXXX_ns и т.п. А заморачиваться как вы предлагаете с арифметикой умножения/деления на сдвигах (степени двойки) - для этого нужны наверно уж ооооочень веские причины и камень и код должны быть крайне убогими, раз приходится идти на такие отчаянные шаги ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 14 января Опубликовано 14 января · Жалоба 1 час назад, kolobok0 сказал: то лучше умножать на 65536 Хорошо, умножим. А сколько будет шаг приращения 0,1 * 65536? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 14 января Опубликовано 14 января · Жалоба 2 hours ago, EdgeAligned said: Хорошо, умножим. А сколько будет шаг приращения 0,1 * 65536? 0,1 - называется "одна десятая" - т.е. одна часть из десяти, т.е. разделите на десять. 3 hours ago, Forger said: ... и камень и код должны быть крайне убогими, раз приходится идти на такие отчаянные шаги ) 3 hours ago, Forger said: если Вы считаете, уход от погрешности и увеличение скорости работы - убожеством.... ээээээээээээ ну ок. убеждать в обратном не буду. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 14 января Опубликовано 14 января · Жалоба 33 minutes ago, kolobok0 said: если Вы считаете, уход от погрешности и увеличение скорости работы - убожеством.... да, если это не влияет положительно на выгоду от продаж, а влияет лишь на личное эго кодера, его потребность выпендрится на ровном месте, создать "непреодолимую" проблему на ровном месте и ее победоносно решать нет, если речь идет о много-много-тысячных партиях изделий, где цена камня играет важную роль в прибыли, где заранее посчитано, что, например, если уйти с обычной целочисленной арифметикой на двоичную (где умножение на сдвигах) ценой усложнения кода и даже ухода в ассемблер, то конечно это вполне нормальное решение у вас были проекты с много-много-тысячными партиями изделий? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться