Математика Ардуино
- Войдите на сайт для отправки комментариев
Пнд, 07/01/2019 - 13:03
Потребовалось мне несколько математических функций для расчетов. Решил использовать имеющуюся в IDE библиотеку math.h. Проверил - всё вроде считает, но дернуло проверить на точность (когда-то давно так программируемые калькуляторы проверялись). Собственно схема проверки простая - вычисляется косинус (или любая тригонометрическая функция) большого угла, выраженного в радианах, и сравнивается с "эталоном". В качестве аргумента выбрал 123456789. Заодно выводится число пи (оно есть в библиотеке) и опять сравнивается с эталонным. Вывожу 9 знаков в сериал мониторе. Запустил маленький скетчик
double double__x = 123456789.0 ; void setup() { Serial.begin(9600); Serial.print("cos double__x = "); Serial.println (cos (double__x), 9 ); // returns cosine of x Serial.print("Pi = "); Serial.println (M_PI, 9 ); // returns PI } void loop() { // put your main code here, to run repeatedly: }
cos double__x = -0.278581023
Pi = 3.141592741
и сравнил с вычислениями виндосовского калькулятора. Вот результаты калькулятора. Косинус: 0,14025968153390962995065549327877. ПИ:3,1415926535897932384626433832795.
Лезу в файл math.h и вижу:
/** The constant \a pi. */
#define M_PI 3.14159265358979323846 /* pi */
Полностью совпадает с тем, что выдал калькулятор, а в выводе в сериал ошибка в 7-м знаке после запятой. О вычислении косинуса вообще молчу.
Где ошибка и как правильно считать не могу разобраться.
Неудачный тестовый пример. Вы слишком большую точность от типа double (здесь он же float) хотите - 9 знаков. Он не умеет столько. Вот здесь пишут 6-7 знаков всего http://arduino.ru/Reference/Float Выведите на печать само double__x без всяких форматов - всё сами увидите. А несколько радиан для косинуса - вот и совсем непохожий результат. Ну и пи только до соответствующего знака стоит сравнивать.
Неудачный тестовый пример. Вы слишком большую точность от типа double (здесь он же float) хотите - 9 знаков. Он не умеет столько. Вот здесь пишут 6-7 знаков всего http://arduino.ru/Reference/Float Выведите на печать само double__x без всяких форматов - всё сами увидите. А несколько радиан для косинуса - вот и совсем непохожий результат. Ну и пи только до соответствующего знака стоит сравнивать.
Ну, хорошо, а для кого в библиотеке пи до 20-го знака?
Ну, хорошо, а для кого в библиотеке пи до 20-го знака?
наверно для тех, кто уверен, что "чем больше знаков - тем точнее"
Например, для Arduino Due тип double не 4-х, а 8-байтовый.
https://gcc.gnu.org/wiki/avr-gcc#Type_Layout
В avr-GCC нет типа double. Весь твой пример - нормально посчитан на float. ;))))))))
;))))) пичалько! ;))))))))
в math.h: #define M_PI 3.14159265358979323846
в Aduino.h: #define PI 3.1415926535897932384626433832795
Вопрос "на кой хрен нужна эта точность?", остается.
Для подавляющего большинство реальных механизмов хватает точности логарифмической линейки - т.е. три значащих цифры.
Ну, хорошо, а для кого в библиотеке пи до 20-го знака?
наверно для тех, кто уверен, что "чем больше знаков - тем точнее"
Ну не надо так то. Для любой системы есть свои ограничения. Косинус с большИм аргументом может оказаться большой ошибкой и привести к последствиям, если не знать ограничений. А здесь ошибка уже в первом знаке.
Да и непонятно откуда берутся "хвосты" после 7 знака. Сейчас отправил в сериал 13 знаков после запятой, получил 13 знаков:
Ну, хорошо, а для кого в библиотеке пи до 20-го знака?
Предположим, у нас есть кругдый участок диаметром 100 метров +/- 20см.
Если мы знаем пи с точностью 31 знак после запятой, мы сможем рассчитать длину забора намного точнее, чем при 20 знаках. Это позволит нам правильно заказать кол-во рулонов сетки.
Вы вывели в сериал само Ваше число double__x ? Вы поняли, почему там не 123456789.0 ?
Почитайте что-нибудь про двоичное представление вещественных чисел. Не любое число можно точно сохранить в вещественном формате. Вам и выводится приближенное представление.
Ну, хорошо, а для кого в библиотеке пи до 20-го знака?
Это универсальная константа и для 8-байтового double и для больших (по объёму памяти) чисел.
По поводу же косинуса - нормальное накапливание ошибки. Слыхали про то, как американцы под 30 человек убитыми потеряли из-за накапливаюзщейся ошибки в прошивке "Патриотов". Ото ж.
Да и непонятно откуда берутся "хвосты" после 7 знака. Сейчас отправил в сериал 13 знаков после запятой, получил 13 знаков:
Блин! Чукча не читатель?
Я УЖЕ написал, что НЕТ В avr-gcc ТИПА DOUBLE.
Он совпадает с float, то есть 32 бита. Вот чего непонятного я написал?????
Точно нужно тест на психические отклонения при регистрации проводить.
С желаетмой тобой точность в 64 бита СЧИТАТЬ НА АРДУИНО МОЖНО ТОЛЬКО НА СТОРОННИХ библиотеках.
(может капсом дойдет ???)
Да и непонятно откуда берутся "хвосты" после 7 знака. Сейчас отправил в сериал 13 знаков после запятой, получил 13 знаков:
Блин! Чукча не читатель?
Я УЖЕ написал, что НЕТ В avr-gcc ТИПА DOUBLE.
Он совпадает с float, то есть 32 бита. Вот чего непонятного я написал?????
Точно нужно тест на психические отклонения при регистрации проводить.
С желаетмой тобой точность в 64 бита СЧИТАТЬ НА АРДУИНО МОЖНО ТОЛЬКО НА СТОРОННИХ библиотеках.
(может капсом дойдет ???)
Вы специально стараетесь нахамить незнакомому Вам человеку? Я Вас обидел чем-то? Будьте поспокойнее.
Ну, хорошо, а для кого в библиотеке пи до 20-го знака?
Это универсальная константа и для 8-байтового double и для больших (по объёму памяти) чисел.
По поводу же косинуса - нормальное накапливание ошибки. Слыхали про то, как американцы под 30 человек убитыми потеряли из-за накапливаюзщейся ошибки в прошивке "Патриотов". Ото ж.
Спасибо за ответ. Да, я знаю, что в косинусе ошибка накапливается, поэтому и проверял. А по поводу ПИ были у меня программы (не для ардуино, конечно), где ПИ вычислялось как 4*atan(1). Здесь попробовал и началось...
Вы специально стараетесь нахамить незнакомому Вам человеку? Я Вас обидел чем-то? Будьте поспокойнее.
Я один, "вы"-кать не нужно ;)))).
Я неспокоен потому, что уже ответил, а обсуждение продолжается. Могу спокойнее объяснить, но мне кажется, что разжевывание, как для даунов, оскорбляет собеседника юольше, чем грубость.
В avr-gcc, а это именно тот компилятор, который применается в Ардуино ИДЕ, не реализован 64 битный double, ссылку на документацию для подтверждения я отправил в первом, вежливом посте.
Это означает, что объявляя double переменную, она все равно живет как флоат. И все вычислени - как флоат. Если ты перепишешь свой пример с объявлениями "флоат", то получишь именно такой вывод, как получил с дабл.
Вот смотри, что печатает ардуина:
то есть видишь ли ты, как изменилось число 1234567789.0? И косинус посчитан с накапливающейся ошибкой.
Константа указана единообразно для всех реализаций. Это же просто исходник от libc.
====================
Мне кажется, что такое разжевывание унизительно для тебя. После моего первого ответа все это и так понятно, нет? Сорри, но не я тебя таким обидчивым воспитал.
Вы специально стараетесь нахамить незнакомому Вам человеку? Я Вас обидел чем-то? Будьте поспокойнее.
Я один, "вы"-кать не нужно ;)))).
Я неспокоен потому, что уже ответил, а обсуждение продолжается. Могу спокойнее объяснить, но мне кажется, что разжевывание, как для даунов, оскорбляет собеседника юольше, чем грубость.
В avr-gcc, а это именно тот компилятор, который применается в Ардуино ИДЕ, не реализован 64 битный double, ссылку на документацию для подтверждения я отправил в первом, вежливом посте.
Это означает, что объявляя double переменную, она все равно живет как флоат. И все вычислени - как флоат. Если ты перепишешь свой пример с объявлениями "флоат", то получишь именно такой вывод, как получил с дабл.
Вот смотри, что печатает ардуина:
то есть видишь ли ты, как изменилось число 1234567789.0? И косинус посчитан с накапливающейся ошибкой.
Константа указана единообразно для всех реализаций. Это же просто исходник от libc.
====================
Мне кажется, что такое разжевывание унизительно для тебя. После моего первого ответа все это и так понятно, нет? Сорри, но не я тебя таким обидчивым воспитал.
Да что Вы так переживаете-то? Я уже давно, еще до Вашего вмешательства, понял и про синус и про косинус и про float. Так что не стОило так уж разжевывать и волноваться.
По моему это уже стоит сделать классикой:
http://arduino.ru/forum/programmirovanie/vyvod-float-na-serial-monitor#c...
Хотел я на Ардуино попробовать одну программу, которую еще в 2011 написАл для ПК.
Бегать с ноутбуком и телескопом не очень удобно. Поэтому было желание переложить на Ардуино. Но посмотрев на исходники, понял, что не потянет оно, даже с упрощенными формулами. Там несколько важных констант требуют более 6 знаков после запятой. Вот и вся история вопроса о точности вычислений.
Для смартфона есть программы, но они только для вычисления звездного времени, а тут всё, включая координаты объектов. Достал телескоп и наводи куда надо. Там же отдельная база данных по кооодинанам объектов и мест наблюдения. А для смартфона я программ не пишу. Хотел, но старый уже. В этом году 69 стукнет(((
Если не делаешь секрета из кода, то мне лет меньше - 49 и с переносом кода на Андроид я помогу задаром. Мне и самому интересно, а ты мне телескоп посоветуешь для начала - до 50 т.р что-нибудь, а то жена убъет ;))). Почта - мой ник на жмейле.
У меня исходники на VB. Годится?
А телескоп я никому не советую - дорогая игрушка. На пару-тройку сезонов, а потом будет на полке. Тем более самое интересное на небе зимой, когда холодно и смотреть нЕгде - около больших городов небо засвечено, облачность почти постоянная. Осенью еще можно, даже с конца августа, но сыро - телескоп потеет на природе. В общем одни неприятности. Сам телескоп с монтировкой - это только начало, потом пойдут окуляры, линзы, призмы, фильтры переходники всякие, желание заняться астрофотографией. Кукла барби с Кеном. Ну, как-то так. А лучше всего потусоваться на астрофорумах для начала. Я бы посоветовал от себя начать с обычного бинокля с небольшим увеличением - для созвездий. Если увлечет, то дальше можно думать.
Для смартфона есть программы, но они только для вычисления звездного времени, а тут всё, включая координаты объектов. Достал телескоп и наводи куда надо. Там же отдельная база данных по кооодинанам объектов и мест наблюдения. А для смартфона я программ не пишу. Хотел, но старый уже. В этом году 69 стукнет(((
Поэтому было желание переложить на Ардуино. Но посмотрев на исходники, понял, что не потянет оно, даже с упрощенными формулами. Там несколько важных констант требуют более 6 знаков после запятой. Вот и вся история вопроса о точности вычислений.
На ардуине можно хоть до 20 знаков после запятой считать. Прсто медленнее будет. Какая конкретно точность нужна и какие функции нужны?
а в какой-нибудь опенофис для андроида формул навтыкать? вроде несложно (если формулы знать).
Да, ребята, спасибо ничего страшного. Все это от лени как всегда. Если есть бумажка с координатами объектов, то можно только со звездным временем на смартфоне.
Если кому-нибудь интересна тема астрономии и программирования, рекомендую эту книгу (качать с CD). Есть программы на СИ.
Четырёхбайтовый float даёт 6 знаков и не больше.
Аккуратные подсчеты показывают несколько иное. (разумеется, если речь идет о десятичных знаках)
У меня исходники на VB. Годится?
А телескоп я никому не советую - дорогая игрушка. На пару-тройку сезонов, а потом будет на полке. Тем более самое интересное на небе зимой, когда холодно и смотреть нЕгде - около больших городов небо засвечено, облачность почти постоянная. Осенью еще можно, даже с конца августа, но сыро - телескоп потеет на природе. В общем одни неприятности. Сам телескоп с монтировкой - это только начало, потом пойдут окуляры, линзы, призмы, фильтры переходники всякие, желание заняться астрофотографией. Кукла барби с Кеном. Ну, как-то так. А лучше всего потусоваться на астрофорумах для начала. Я бы посоветовал от себя начать с обычного бинокля с небольшим увеличением - для созвездий. Если увлечет, то дальше можно думать.
1. Про VB, мне все равно. Знаешь ли старую байку про Вяч. В. Ива'нова, великого лингвиста? Как-то Комо Иванова спросили: "А сколько языков Вы знаете?". Вячеслав Всеволодович замялся на мнгновение и уверенно ответил: "Все".
Про себя с таким пафосом не скажу... но все-же. ;)))))
2. Я в МО живу в частном доме. Проблемм с небом не имею. Как-то с женой, по спонтанному решению, сели в машину и поехали в Норвегию, на Норд-кап (самая северная точка Европы, очень далеко за полярным кругом), в феврале 2014, ловить северное сияние ;))) на старой ржавой праворульной Мазде. Зато было весело. (если у читателя недопонимание про визы возникнет, то длинный шенген был давно открыт, просто садись и рули). Ошибку сделал - небо чише дальше от моря. Надо было в Альту ехать, а не на Магерёйю. Чуть-чуть было сияния, но мало совсем - пурга, и луна яркая мешала сильно засветкой.
И бинокль и труба есть, и Юпитер я в трубу смотрю, а хочу и спутники его разглядеть. Вот просто и поинтересовался, что можно посоветовать за небольшие деньги - до 50 т.р.?
Хотел я на Ардуино попробовать одну программу, которую еще в 2011 написАл для ПК.
Бегать с ноутбуком и телескопом не очень удобно. Поэтому было желание переложить на Ардуино. Но посмотрев на исходники, понял, что не потянет оно, даже с упрощенными формулами. Там несколько важных констант требуют более 6 знаков после запятой. Вот и вся история вопроса о точности вычислений.
2. Если все лень и хочется именно double, то такие имеются в Arduino Due или Stmduino.
3. Если хочется именно double и AVR, можно поискать соответствующие библиотеки. Если уж на intel8080 с его 2 МГц и 0.5 MIPS были 8-байтовые с плавающей точкой, то уж на 16 МГц AVR при 16 MIPS это в случае единичных вычислений не должно быть непростительно медленно.
В общем, не рассматриваю ситуацию как тупиковую. Но в любом случае, Вам бы разобраться, как хранятся числа в компьютере, чтобы правильно спланировать работу и не наделать глупых ошибок.
Аккуратные подсчеты показывают несколько иное. (разумеется, если речь идет о десятичных знаках)
Да, кто б спорил - то? Вот только пользоваться уверенно можно именно 6-ю, а не 7.2 знаками :)
// offtop
float в ардуино это тема :))))))) только в millis () и годен
Аккуратные подсчеты показывают несколько иное. (разумеется, если речь идет о десятичных знаках)
Да, кто б спорил - то? Вот только пользоваться уверенно можно именно 6-ю, а не 7.2 знаками :)
Ну, если Вам так удобнее - пользуйтесь двоичными, я не возражаю.
А чем я, по-вашему, пользуюсь? Ж8( )
Не знаю, я как-то даже не думал об этом. Пользуйтесь, на здоровье, чем Вам удобно :)
Неудачный пример я конечно в программировании новичок , но совершенно точно могу вам сказать с металлопрокатом никогда нельзя быть уверенным , к примеру в 6 метровой трубе может оказаться от 6100мм до 5750мм а про рабицу я вообще боюсь представить , так что программирование вам тут не поможет ))))