Страница 3 из 6

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 16:39:41
ARV
tonyk писал(а):Проблема потери точности, особенно в технике, совсем не надумана
а при чем тут потеря точности, если мы говорим о делении на 0? или вы считаете нормальным писать такие алгоритмы, которые ДОПУСКАЮТ ситуацию деления на ноль? а о фиксированной точке вообще речь не шла, если память и история темы не подводят...

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 16:44:36
WatchCat
вместо включения всех, кроме, можно оставить включенными все, но выключить один конкретный
Вчера на иностранном форуме попался диалог двух программистов,там один тоже хотел так выключить какую-то оптимизацию,а другой ему сказал что это так сделать не получится. Именно только включать по одному все нужные.
я точно не уверен, но вроде бы лучший кандидат на исключение - флаг -fcprop-registers. -Og -fno-cprop-registers
Это я в первую очередь вчера попробовал именно из-за "registers" в названии - не помогает.
Прямо хоть "тупым перебором" подбирать:(

Попробовал написать -О0 и добавить весь список для -O1 - регистровые переменные НЕ используются. То есть -O0 со списком от -O1 не эквивалентно указанию -О1.
А вот если написать -Og и весь тот же список с добавленным "no" перед опциями - то на большинство из них gcc ругается - говорит что нет такой формы опции с отрицанием. Так что похоже что нет отдельного флажка для регистровых переменных. Буду -О0 использовать. Тем более что на своих программах я не нашел отрицательного влияния на отладчик от -О0. Видимо ему "дополнительные проходы для сбора отладочной информации" не нужны - ее и так хватает.

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 17:39:14
Dimon456
Jack_A, при чем тут среда? Что дает среда?
Выхлоп один
avr-gcc version 9.2.0 (GCC)
Давайте сравним точность вычислений тремя методами.
Как вы хотите что бы я это сделал, умножил поделил прибавил, в цикле запустил, или еще как?

Добавлено after 48 minutes 55 seconds:
Что, ни кто не чего не предложил?
Вот вам 1 тест

Код: Выделить всё

23906/(0 ... 255)
Выхлоп (это найденные несоответствия дробной части)
Спойлерn - на что делили
m1 - ваш код
m2 - float
m3 - мой код

Код: Выделить всё

un_pac[0]	0x021E	
n	0x021E	0 
m1	0x021F	65535 
m2	0x0221	0 
m3	0x0223	999 
un_pac[1]	0x0225	
n	0x0225	5 
m1	0x0226	200 
m2	0x0228	200 
m3	0x022A	199 
un_pac[2]	0x022C	
n	0x022C	10 
m1	0x022D	600 
m2	0x022F	600 
m3	0x0231	599 
un_pac[3]	0x0233	
n	0x0233	20 
m1	0x0234	300 
m2	0x0236	300 
m3	0x0238	299 
un_pac[4]	0x023A	
n	0x023A	25 
m1	0x023B	240 
m2	0x023D	239 
m3	0x023F	239 
un_pac[5]	0x0241	
n	0x0241	40 
m1	0x0242	650 
m2	0x0244	650 
m3	0x0246	649 
un_pac[6]	0x0248	
n	0x0248	50 
m1	0x0249	120 
m2	0x024B	119 
m3	0x024D	119 
un_pac[7]	0x024F	
n	0x024F	80 
m1	0x0250	825 
m2	0x0252	825 
m3	0x0254	824 
un_pac[8]	0x0256	
n	0x0256	100 
m1	0x0257	60 
m2	0x0259	59 
m3	0x025B	59 
un_pac[9]	0x025D	
n	0x025D	125 
m1	0x025E	248 
m2	0x0260	248 
m3	0x0262	247 
un_pac[10]	0x0264	
n	0x0264	200 
m1	0x0265	530 
m2	0x0267	529 
m3	0x0269	529 
un_pac[11]	0x026B	
n	0x026B	250 
m1	0x026C	624 
m2	0x026E	624 
m3	0x0270	623 

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 17:52:10
tonyk
ARV писал(а):а при чем тут потеря точности, если мы говорим о делении на 0?
С точки зрения ошибок вычислений, это, по-сути, одно и то же.
ARV писал(а):или вы считаете нормальным писать такие алгоритмы, которые ДОПУСКАЮТ ситуацию деления на ноль?
Безусловно! Алгоритм должен быть устойчив к любым ошибкам, в том числе и деления на ноль. Например, вышел из строя АЦП и тебе приходит ноль, или очень маленькое число, которое в процессе промежуточных вычислений (особенно с плавающей точкой!) превратится в ноль, на который будет попытка деления. И что, твоя программа зависнет по по ошибке или выдаст несуразный результат?
ARV писал(а):а о фиксированной точке вообще речь не шла, если память и история темы не подводят...
Вопрос, заданный ТС:
WatchCat писал(а):Если я просто поделю одно на другое целочисленным делением (на Си) то получу число 5, что означает весьма существенную потерю
точности из-за малого числа значащих разрядов... Собственно и вопрос к присутствующим - Какие еще есть варианты решения этой задачки?... Так что если кто в этой теме хорошо разбирается - подскажите пожалуйста!
Так что и память тебя подводит, и знаний мало. Я предложил использовать вычисления с фиксированной точкой и выложил текст класса большого целого с динамическим наращиванием разрядности.

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 18:33:11
ARV
tonyk писал(а):С точки зрения ошибок вычислений, это, по-сути, одно и то же
ну так можно любые ошибки свести к ошибкам вычисления... несерьёзно так обобщать
tonyk писал(а):Алгоритм должен быть устойчив к любым ошибкам
да ладно! а т в своих проектах непрерsвный контроль ОЗУ при помощи CRC делаешь? а то ведь вдруг какое-нибудь нейтрино пролетит и ячейка ОЗУ сдохнет в одном бите...
tonyk писал(а):Так что и память тебя подводит, и знаний мало
на счет знаний спорить не буду, их и вправду немного... а вот на счет памяти - не соглашусь: не смотря на формальное родство фиксированной точки с целыми числами, речь о фиксированной точке не шла.

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 18:41:37
Dimon456
tonyk писал(а):с фиксированной точкой
у float фиксированной точки не может быть.
Да и наращивания разрядности смысла не имеет, ну не делится эта "штука" так как надо.
tonyk писал(а):выложил текст класса
еще бы тест выложил, тогда, ладно, поверим.

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 18:50:18
tonyk
ARV писал(а):ну так можно любые ошибки свести к ошибкам вычисления... несерьёзно так обобщать
Видимо, теорию не знаешь и практики работы со сложными вычислительными средствами нет. Просто почитай, сколько ошибок вычислений формирует математический сопроцессор твоего компа, может, тогда понятней станет, сколько ты упускаешь из рассмотрения. Кстати, в результате вычислений может получиться не число. :)))
ARV писал(а):да ладно! а т в своих проектах непрерsвный контроль ОЗУ при помощи CRC делаешь? а то ведь вдруг какое-нибудь нейтрино пролетит и ячейка ОЗУ сдохнет в одном бите...
Делаю непрерывное вычисление CRC для всех видов энергонезависимой памяти, в которых хранятся уставки и программа. Всё-таки уран плавил. Это требование у нас даже в ТЗ прописывается и все управляющие контроллеры его выполняют.
ARV писал(а):не смотря на формальное родство фиксированной точки с целыми числами, речь о фиксированной точке не шла.
Да ну! ТС просил способ повышения точности вычислений. Я предложил относительно простой способ решения с использованием арифметики с фиксированной точкой, которым пользовался на практике, но ты его даже не понял. Говорю же, с математикой у тебя плохо.

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 19:00:48
Dimon456
tonyk, вот дробная часть

Код: Выделить всё

1/8бит = 0,00390625
1/16бит = 0,0000152587890625
1/32бит = 0,00000000023283064365386962890625
Как бы ты там не наращивал - ошибка будет, ну не делится эта "штука" так как надо.
tonyk писал(а):относительно простой способ решения с использованием арифметики с фиксированной точкой
эта та длинная портянка?
У мну три строчки кода занимает.

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 19:05:56
WatchCat
Я предложил относительно простой способ решения с использованием арифметики с фиксированной точкой
Это тот огромный класс на плюсах - простой способ?
Я бы так не сказал. Конечно там где с ураном работают профессионалы такое вполне нормально,но не в домашне-радиолюбительской практике точно.
А еще использование плюсового класса скорее всего потащит за собой линковку в проект значительного дополнительного куска библиотечного кода.
Нет уж,я как-то тридцать лет плюсов избегал и дальше избегать буду. Тем более что никакой жутко серьезный заказчик со своими требованиями обязательно использовать С++ у меня над душой не стоит.
Так что насколько я понял из этой дискуссии,вариант с домножением на тысячу и приведением типа этой тысячи к long - мне вполне подойдет. В качестве плана Б - буду иметь в виду "деление с остатком".

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 19:07:47
Reflector
[uquote="ARV",url="/forum/viewtopic.php?p=4203282#p4203282"]да ладно! а т в своих проектах непрерsвный контроль ОЗУ при помощи CRC делаешь? а то ведь вдруг какое-нибудь нейтрино пролетит и ячейка ОЗУ сдохнет в одном бите...[/uquote]
Периодически кто-то пугает, что не размещайте вектора прерываний и т.д. в RAM - это же ненадежно, однако сейчас аппаратный контроль четности RAM обычное дело, в тех же STM32 оно было когда они еще по 30 центов продавались. Прилетело нейтрино, один бит RAM изменился и попадаем в соответствующий обработчик прерывания, так что да, нечто подобное есть и им пользуются. В более сложных мк и подход более продвинутый, они уже и двойные ошибки ловят...

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 19:54:46
AlexS4
>пугает, что не размещайте вектора прерываний
ну от подобных бед какраз вочдоги и джамп-ловушки между модулями.
а такто и флэш может повредиться...
как говорил наш преподаватель, сделать программу надежно работающую на неисправном компьютере для общего случая невозможно :)))

>В более сложных мк и подход более продвинутый, они уже и двойные ошибки ловят...
при избыточности 1/8 на 128bit данных можно корректировать двойные и обнаруживать четверные ошибки внутри слова. что собственно в серверных мамках ecc модули и обеспечивают. Спасибо товарищу Хеммингу!)

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 20:22:19
tonyk
Dimon456 писал(а):Как бы ты там не наращивал - ошибка будет, ну не делится эта "штука" так как надо.
И да, и нет. Я отгонял математику во всех мыслимых режимах и видел, что результатов больше 70 (или 72, не помню) бит не бывает, поэтому спокойно задал начальную разрядность для чисел в 80 бит, чтобы не перекраивать память в процессе работы. Если будет нужно, могу сам задать любую разрядность чисел, хоть 40000 бит, а могу отдать на откуп классу в динамике подстраивать разрядность, что очень удобно при наладке. Так что можно промасштабировать и 1/32, и 1/32767. Конечный результат на регулятор выдаю в виде 16-ти битного числа с фиксированной точкой с двумя достоверными знаками, хотя имею честные 6.
WatchCat писал(а):А еще использование плюсового класса скорее всего потащит за собой линковку в проект значительного дополнительного куска библиотечного кода.
Концепция С++ как раз и заключается в том, что ты платишь только за то, что используешь. В примере, вроде, закоментарен вызов методов потокового ввода-вывода, поэтому никакого дополнительного кода из библиотек там нет и не будет.

Добавлено after 4 minutes 47 seconds:
Самое главное вы так и не просекли. Завтра понадобится вам 96-ти битная арифметика, и будете вы новые костыли выдумывать, ибо нет в Си типа данных с такой разрядностью. Нет, ну можно, конечно, вместо Атмеги взять 128-ми битный AIX... :))) Мне же достаточно будет написать просто #include "BigInt.h"

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 20:41:42
WatchCat
Концепция С++ как раз и заключается в том, что ты платишь только за то, что используешь.
Наверно от этого после начала внедрения плюсов на персоналках в 90е годы - весь софт сильно разжирен и затормозил.
Прямо очень заметно было когда борландовский плюсовый компилятор начал по рукам ходить в Питере.
Завтра понадобится вам 96-ти битная арифметика, и будете вы новые костыли выдумывать, ибо нет в Си типа данных с такой разрядностью. Мне же достаточно будет написать просто #include "BigInt.h"
Вот когда (и если!) понадобится - тогда я об этом и задумаюсь. У меня не промышленное изделие,в которое надо закладывать возможности дальнейшего "развития" с маркетинговыми целями - чтобы можно было продавать "новые" модели,отличающиеся прошивкой и дизайном корпуса. Так что сейчас я точно не буду разбираться с встраиванием скомпилированного плюсами модуля в свою программу на самом обычном,отчасти даже "устаревшем"(зато мне привычном) диалекте Си. Да, я знаю как такие штуки делать,но бороться с name mangling и правильным своевременным вызовом конструкторов/деструкторов сейчас совсем не хочется.
Мне еще с логикой работы программы повозиться предстоит - я же не от балды вопрос про вычисления задавал,а потому что эти вычисления собираюсь написать и отладить. Третий день уже собираюсь. Зато нашел древнюю аппноту с понятным примером как это надо писать - от Атмела,еще до объединения с Микрочипом.

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 21:55:29
ARV
tonyk писал(а):Всё-таки уран плавил.
а ты форумом не ошибся? ураноплавильщиков тут нет, кроме тебя, и ураноплавильные подходы тут вряд ли разумно применять

в частности, примерно за 30 лет активного программирования, в том числе на PC, исключения по делению на 0 у меня были только в студенческие годы, да и то буквально несколько раз. а в МК вообще никогда не ловил проблем из-за некорректных вычислений.
tonyk писал(а):Кстати, в результате вычислений может получиться не число
не может :))) NaN - это тоже число, из битиков :)))
Reflector писал(а):Прилетело нейтрино, один бит RAM изменился и попадаем в соответствующий обработчик прерывания
который тоже поврежден предыдущим нейтрино... и, естественно, не отрабатывает из-за этого... паранойя никогда до добра не доводила :)))
AlexS4 писал(а):сделать программу надежно работающую на неисправном компьютере для общего случая невозможно
тут ураноплавильщик недавно доказывал, что не только можно, но и нужно! программа должна работать правильно всегда, невзирая на любые ошибки, неисправности и вообще на выключенном МК :))) не уверен, но подозреваю, что и на непрошитом тоже...
tonyk писал(а):Завтра понадобится вам 96-ти битная арифметика, и будете вы новые костыли выдумывать
уран в пятерочку завезут по дешевке? никому из здесь присутствующих, даже такому гуру, как Reflector, никогда не понадобится такая арифметика... во всяком случае в контексте pet-проектов, т.е. любительстве, о чем мы тут все (кроме тебя) и говорим

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 22:04:33
WatchCat
никому из здесь присутствующих, даже такому гуру, как Reflector, никогда не понадобится такая арифметика...
Ну с некоторой вероятностью тут могут пастись какие-нибудь студенты-дипломники или аспиранты,которым может потребоваться что-нибудь в лабораторных экспериментах померить и посчитать. А больших денег на оборудование у них нет,так что вполне могут паять и программировать сами. Или это вообще может быть темой дипломной/научной работы - создание такого измерителя. Так что то,что профессионал поделился здесь примером кода промышленного уровня - это не плохо. Молодым будет с чего брать пример. А то ведь вообще на каком-нибудь php написать могут или там яваскрипте.

Re: Правильное выполнение арифметических операций?

Добавлено: Чт мар 24, 2022 22:42:10
ARV
ладно, не буду спорить, тема очень важная. я тут как раз часы делаю, пожалуй, надо применить 72-разрядный счетчик для секунд, а то ведь что за часы, если в секундах 32-й знак после запятой может быть некорректным... правда на индикаторе секунд вообще не будет, но зато внутри-то будет чики-чики!

Re: Правильное выполнение арифметических операций?

Добавлено: Пт мар 25, 2022 10:11:07
Dimon456
Тема может быть и важная, но арифметика с фиксированной точкой это не float и printf sprintf и тп. уже так просто не скормить.
Возникает вопрос - для чего?

Re: Правильное выполнение арифметических операций?

Добавлено: Пт мар 25, 2022 10:16:43
ARV
Dimon456 писал(а):вопрос - для чего?
так было же сказано, для чего: уран плавить!

Re: Правильное выполнение арифметических операций?

Добавлено: Пт мар 25, 2022 10:35:24
WatchCat
[uquote="Dimon456",url="/forum/viewtopic.php?p=4203490#p4203490"]Тема может быть и важная, но арифметика с фиксированной точкой это не float и printf sprintf и тп. уже так просто не скормить.
Возникает вопрос - для чего?[/uquote]
Например для регулятора какого-нибудь параметра.
Получаем значение регулируемого параметра с АЦП, а дальше его надо сравнить с предустановленным значением и разность
умножить на "коэффициент усиления цепи обратной связи", и записать в регистр таймера,формирующего ШИМ. Из АЦП приходит целое число,в таймер пишется тоже целое. Электрическая аналогия - обратная связь в импульсных БП. Там обычно на выходе стоит резисторный делитель и с него сигнал подается на вход усилителя ошибки. Как раз деление и умножение.
Сразу отвечу на вопрос почему не сделать простой аналоговый регулятор - например потому что параметр должен меняться или по заданному закону во времени или в зависимости от каких-то внешних событий.

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

А насчет printf - так в микроконтроллерных поделках как правило вывод на индикатор не через printf делается. Разве что для отладочного вывода в uart может быть надо,но туда можно и просто hex выводить - это же не для пользователя цифры,а автор программы разберется. Или можно отделить целую часть от дробной и каждую отдельно скормить в printf. Не так уж и много это вычислений,для отладочной версии - вполне приемлимо.

Re: Правильное выполнение арифметических операций?

Добавлено: Пт мар 25, 2022 11:08:53
ARV
WatchCat писал(а):в микроконтроллерных поделках как правило вывод на индикатор не через printf делается
ну, это, как я понимаю, просто традиция неприятия printf... я для себя её сломал давно, и в случаях, когда результат важнее размера прошивки, использую printf и для ЖКИ тоже