подскажите как переместить символ
- Войдите на сайт для отправки комментариев
Пнд, 19/02/2018 - 12:41
подскажите пожалуста как переместить символ CHAR внутри массива
есть data[12] = {1,2,3,4,.,9,8,7,6,5,4,0} // 1234.9876540
мне надо переместить точку на 2 знака влево, чтобы получилось 12.349876540
дале его atof перевожу в флоат
просто если перевести в флоат сразу а потом /100 то с 5-6 знака после точки число плавает...
//и да, местным тролям просьба не флудить в теме.
пробовал посимвольно перпемещать
data[4]=data[3];
data[3]=data[2];
data[2]=".";
но тогда отваливается весь "хвост" после точки
на выходе получаю
12.000000000
есть data[12] = {1,2,3,4,.,9,8,7,6,5,4,0} // 1234.9876540
Точно есть? И компилируется? Прям вот эта строка у Вас компилируется? Какой компилятор?
Приведите, пожалуйста скетч цнликом, по правилам форума и в компилируемом виде. А то так непонятно, что именно Вы делаете и как Вам помочь.
есть data[12] = {1,2,3,4,.,9,8,7,6,5,4,0} // 1234.9876540
Точно есть? И компилируется? Прям вот эта строка у Вас компилируется? Какой компилятор?
нет, это я привел содержимое - программа большая и данные приходят с порта посимвольно, заносятся в чар массив
массив просто объявлен как char data[12];
Ну сделайте маленький скетч с массивом, чтобы понятно было, что Вам надо, а то так вообще хрен поймёшь, что у Вас есть и что нужно сделать.
пробовал посимвольно перпемещать
data[4]=data[3];
data[3]=data[2];
data[2]=".";
но тогда отваливается весь "хвост" после точки
Код выше должен работать. Если не работает - это только потому. что автор - Вы.
ЗЫ Если вам требуется флоат с точностью выше 5-6 знаков после запятой - очевидно. что у вас проблема в логике программы.
Если массив char то надо писать
одинарные ковычки
спасибо, сейчас попробую кавычки поменять
//у меня похоже плата помирает :( последние пару дней приходится по 5-10 раз прошивать, и только потом начинает работать :( то диодом L начинает быстро минать то он горит в пол яркости и плата вообще перестает определяться :(
Удалено. Не выспался.
UPD: Хотя не, выспался, у вас там массив 12 и цифр с точкой тоже 12 нет "конца строки"
массив объявлен как 12 символов
заполняется он из полученных с жпс данных - там 8-10 символов , 2 в запасе
ахахахах. спасиба, паржалъ. Вот чо 20 языков-то животворящих делают с людями....
Что значит в запасе? там конец строки сишной есть или нет, иначе ерунду получать будите.
void setup() { Serial.begin(9600); } void loop() { char data[13] = {'1','2','3','4','.','9','8','7','6','5','4','0'}; data[4] = data[3]; data[3] = data[2]; data[2] = '.'; Serial.println(data); delay(10000); }похоже, что урок 1+3 =540 остался невыученным
Что значит в запасе? там конец строки сишной есть или нет
Ну там компилятор может положить, может не положить. На всякий случай чуть-чуть запас сделан.
попробовал кавычки одинарные
Serial.print(data); Serial.print(":"); data[4]=data[3];data[3]=data[2];data[2]='.';Serial.print(data);lat=atof(data); Serial.println(lat);
приходит 5432.3347
уходит 54.323345
похоже, что урок 1+3 =540 остался невыученным
я понял, что +1 символ для чара надо
но как уже сказал - данных в массив заносится не более 10 символов, а массив объявлен как 12 символов
подскажите как посмотреть непечатные символы? я думаю, что там есть конец строк символ...
последние пару дней приходится по 5-10 раз прошивать, и только потом начинает работать
И почему это никого не удивляет? :))))))))))
я понял, что +1 символ для чара надо
но как уже сказал - данных в массив заносится не более 10 символов, а массив объявлен как 12 символов
этого мало. Надо еще в неиспользуемые символы ноль заносить.
вывести их на печать в Хекс
у флоат точность 6-7 знаков что вы хотите добиться переносом точки в строке? Для математических вычислений этого не достаточно.
я советую, и, думаю, многие с мной согласяца, включить показ warning в выводе компилятора. Проектировали его достатошно умные люди, поэтому на такие конструкции он будет потихоньку ругаца. Ну а ты внимательно читай, что он пишет, и внемли. И, если ты умеешь читать, канеш, 50% вопросов сами собой отсеюца.
у флоат точность 6-7 знаков что вы хотите добиться переносом точки в строке? Для математических вычислений этого не достаточно.
да понятно. что хочет добиться - ему GPS возвращает координаты. умноженные на 100. А он хочет градусы...
В GPS такой формат как раз для повышения точности. Эти данные не надо переводить в градусы - их так и надо использовать.
подскажите как посмотреть непечатные символы? я думаю, что там есть конец строк символ...
откуда там непечатные символы-то? - ваш парсер должен брать из сериала только цифры! - если туда попадает "конец строки" или еще что - значит код парсинга никуда не годится.
Serial.print("!----!"); Serial.print(data); Serial.print(":"); data[4]=data[3];data[3]=data[2];data[2]='.'; Serial.print(" ");Serial.print(data);lat=atof(data); Serial.print(" ");Serial.println(lat,6);
да формат ЖПС таков, что выводит 4 знака - минуты и секунды, а доли за точку убирает
но мне для вывода на 7ми сигментный индикатор удобнее точку ставить после минут.
хотя неверное вы правы - не надо мудрить и работать с исходными данными а точку ставить только в момент вывода на индикатор
спасибо что не затролили опять :)
но вопрос остается открытым - как перевести сичло из чар в флоат без потери точности на 4й знак
Serial.print("!----!"); Serial.print(data); Serial.print(" "); lat=atof(data); Serial.print(" ");Serial.println(lat,4);
но даже в таком виде получаю
как у вас так получается? - у меня ничего не меняет
если бы я знал как так получается....
вот весь скетч
/* $GPVTG Сообщение VTG передает текущее истинное направление курса (COG) и скорость относительно земли (SOG). * $GPRMC Сообщение RMC содержит данные о времени, местоположении, курсе и скорости, передаваемые навигационным GPS приёмником. * Контрольная сумма обязательна для этого сообщения, интервалы передачи не должны превышать 2 секунды. * Все поля данных должны быть подготовлены, пока ещё нет самих данных. Недействительные поля могут быть использованы, * пока данные временно не готовы. * */ #include <SD.h> //Load SD card library File LosGps; //Data object you will write your sesnor data to String fname=""; #include "LedControl_hwspi.h" LedControl lc = LedControl( A5, 2); const byte ByteTable[10] = { B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,B01111111,B01111011 };/*0,1,2,3,4,5,6,7,8,9*/ #include <SoftwareSerial.h> SoftwareSerial gps(A2, 255); /*таймера запуска*/ #define TM_100 100 #define TM_200 200 #define TM_500 500 #define TM_1000 1000 #define TM_10000 10000 unsigned long tm1,tm2=0; float dist = 0; //путь //char ch = 0; int cnt = 0; int csv = 0; int fix = 0; int res = 1; char data[12]; float spd,crs; float lat,lng,latd,lngd; int year, month, day, hour, minute, second; bool gps_valid; unsigned long tm=0; void setup() { Serial.println("GPS Logger V4"); /* l-2 дисплей*/ display_act(); /* SD */ pinMode(10, OUTPUT); //Must declare 10 an output and reserve it to keep SD card happy SD.begin(10); //Initialize the SD card reader Serial.begin(9600); gps.begin(9600); } void loop() { if(millis()-tm1 >= TM_1000){tm1=millis(); long disp_c = dist; for (int i=0; i<8; i++) { if(disp_c>0 || i==0) lc.setByte(0, i, ( ByteTable[(disp_c % 10)])); disp_c /= 10; } disp_c = spd; for (int i=0; i<3; i++) { if(disp_c>0 || i==0) lc.setByte(1, i, ( ByteTable[(disp_c % 10)])); disp_c /= 10; } disp_c = crs; for (int i=5; i<8; i++) { if(disp_c>0 || i==5) lc.setByte(1, i, ( ByteTable[(disp_c % 10)])); disp_c /= 10; } } if(gps.available()) { char ch=gps.read(); // Serial.print(ch); // simple parser, start with $ if(ch == '$') { cnt = 0; csv = 0; fix = 0; } else { data[cnt++] = ch; if(ch == ',') { data[--cnt] = 0; cnt = 0; csv++; if(csv == 1) { res = strcmp(data,"GPRMC"); if(res == 0) fix = 1; } // Assume N, E /* ,,tim,lat, ,lng, ,spd,crs,dat *//*tmpdt[2]*//*int year, month, day, hour, minute, second; */ if(fix == 1) { // Serial.print(": ");Serial.println(data); if(csv == 2) { hour=((data[0]-48)*10+(data[1]-48)); minute=((data[2]-48)*10+(data[3]-48)); second=((data[4]-48)*10+(data[5]-48)); } else if(csv == 3) {if(data[0]==65){ gps_valid=true;}else if(data[0]==86){gps_valid=false;}} else if(csv == 4) { Serial.print("!----!"); Serial.print(data); Serial.print(" "); lat=atof(data); Serial.print(" ");Serial.println(lat,4);} else if(csv == 6) {lng=atof(data); } else if(csv == 8) { spd=atof(data); } else if(csv == 9) { crs=atof(data); } else if(csv == 10){ day=((data[0]-48)*10+(data[1]-48)); month=((data[2]-48)*10+(data[3]-48)); year=((data[4]-48)*10+(data[5]-48)); } else if(csv == 11) {int i=0;fix = 0; Serial.print("Tim: "); Serial.print(hour);Serial.print(":");Serial.print(minute);Serial.print(":");Serial.println(second); if(gps_valid){ Serial.print("Lat: "); Serial.println(lat,6); Serial.print("Lon: "); Serial.println(lng,6); Serial.print("spd: "); Serial.println(spd); Serial.print("crs: "); Serial.println(crs); Serial.print("dist: "); Serial.println(dist); Serial.print("Dat: "); Serial.print(day);Serial.print(".");Serial.print(month);Serial.print(".");Serial.println(year);Serial.println("------------"); }else{Serial.println("GPS Sat NO SIGNAL");} /*************************************************/ if(fname==""){ fname=String(day)+"_"+String(hour)+"_"+String(minute)+".txt"; SD.exists(fname); LosGps = SD.open(fname, FILE_WRITE); LosGps.println(" <metadata>"); LosGps.println(" <author>ELITE</author>"); // LosGps.println(" <name>"+String(day)+"."+String(month)+"."+String(year)+" "+String(hour)+":"+String(minute)+"</name>"); LosGps.println(" </metadata>"); LosGps.close(); Serial.println(fname); }else{ if(latd!=lat || lngd!=lng){Serial.println("!!!!"); LosGps = SD.open(fname, FILE_WRITE); // LosGps.print("dts: "); LosGps.print(String(day)+"."+String(month)+"."+String(year)+" "+String(hour)+":"+String(minute)+":"+String(second)); LosGps.print(" "); LosGps.print("Lat: "); LosGps.print(lat,6); LosGps.print(" "); LosGps.print("Lon: "); LosGps.print(lng,6); LosGps.println(""); LosGps.close(); lngd=lng;latd=lat; } } /*************************************************/ } } } } } } //*********************************************************************************************************** float distance_between (float lat1, float long1, float lat2, float long2) { // returns distance in meters between two positions, both specified // as signed decimal-degrees latitude and longitude. Uses great-circle // distance computation for hypothetical sphere of radius 6372795 meters. // Because Earth is no exact sphere, rounding errors may be up to 0.5%. // Courtesy of Maarten Lamers float delta = radians(long1-long2); float sdlong = sin(delta); float cdlong = cos(delta); lat1 = radians(lat1); lat2 = radians(lat2); float slat1 = sin(lat1); float clat1 = cos(lat1); float slat2 = sin(lat2); float clat2 = cos(lat2); delta = (clat1 * slat2) - (slat1 * clat2 * cdlong); delta = sq(delta); delta += sq(clat2 * sdlong); delta = sqrt(delta); float denom = (slat1 * slat2) + (clat1 * clat2 * cdlong); delta = atan2(delta, denom); return delta * 6372795; } void display_act(){ lc.shutdown(0, false); //Устройство(7-ми сегментный дисплей) выводим из спящего режима lc.setIntensity(0,11);//Установить яркость дисплея на 8 (0..15) lc.clearDisplay(0);//Очистить дисплей lc.shutdown(1, false); //Устройство(7-ми сегментный дисплей) выводим из спящего режима lc.setIntensity(1,11);//Установить яркость дисплея на 8 (0..15) lc.clearDisplay(1);//Очистить дисплей }компилятор 1.9.0 beta
но вопрос остается открытым - как перевести сичло из чар в флоат без потери точности на 4й знак
Serial.print("!----!"); Serial.print(data); Serial.print(" "); lat=atof(data); Serial.print(" ");Serial.println(lat,4);
но даже в таком виде получаю
void setup() { Serial.begin(9600); } void loop() { char data[13] = {'1','2','3','4','.','9','8','7','6','5','4','0'}; data[4] = data[3]; data[3] = data[2]; data[2] = '.'; Serial.println(data); float v = atof(data); Serial.println(v, 8); delay(10000); }выполните его на ардуине и покажите результат
результат
12.349876540
Блин, не так давно здесь появлялся такой intrtrade. Как он здорово начинал! Нейронные сети, искусственный интеллект, ... а через некоторое время начал задавать вопросы как светодиод подключить.
Наш ТС уж не клон ли того intrtrad'а? Тоже ведь, сначала "информатик-аналитик", "два десятка языков", "выше университетского", а потом ... "как сложить 1+2", "число стало отрицательным", "не могу исправить ошибку компиляции", и вот дожили, что элементы массива местами поменять не можем.
Колись ТС - intrtrade - это ты?
1) есть нормальные форумчане, которые помогают и отвечают на порой даже казущиеся им глупые вопросы, спасибо им
2) есть форумчане, кторое отвечают и немного подкалывают, но и им спасибо
3) а есть форумные троли, которым что-то всё времямешаю, и они или на это тему переводят или просто флудят.
Ворота, я склоняюсь, что вы не относитесь ни к 1 ни ко 2 группе....
Ворота, я склоняюсь
Правильно: на колени, холоп!
вы не относитесь ни к 1 ни ко 2 группе....
Совершенно верно! И к третьей тоже не отношусь!
Да ладно. Потроллить немного можно, и даже полезно.
Но показывать своё превосходство, в пустяшном таком вопросе, целых полтора месяца - это уже просто неприлично. Прорываюсь в первую группу. ))
ELITE, не помогу, но просто объясню проблему.
Для начала, всё-таки, документация. Но не далеко - здесь же, на форуме, и совсем чуть-чуть.
В шапке страницы есть ссылка - "Программирование". Входим туда, и смотрим раздел "Типы данных". Не все конечно типы, а только интересующий нас float, ну и, допустим ещё long. Всё читать не обязательно, я ж обещал - чуть-чуть, только первый абзац, и там и там:
"Тип long хранит целые числа в диапазоне от -2,147,483,648 до 2,147,483,647. Переменная занимает 4 байта в памяти."
"Тип float хранит числа с плавающей запятой в диапазоне от -3.4028235E+38 до 3.4028235E+38. Переменная занимает 4 байта(!) в памяти."
Вот те и нифига себе. У типа float диапазон значений больше, на много порядков - а в памяти он занимает всё те же 4 байта? И куда оно всё лезет?
А потому что. Тип float не может хранить любое значение из указанного диапазона. Да и, вообще-то, никто не может - количество этих значений бесконечно. Поэтому приходится округлять, до ближайшего допустимого - что и видим.
Datak, так он не против округления, он справшивает, как сделать, чтобы при округлении было не менее 4-х знаков после запятой (вне зависимости от того, сколько - до зарятой).
Datak, так он не против округления, он справшивает, как сделать, чтобы при округлении было не менее 4-х знаков после запятой (вне зависимости от того, сколько - до зарятой).
не независимо, а весьма определенно
4 знака до и 4 после
или 2 до и 6 после
в обоих случаях менее 4 байт.
Да ладно. Потроллить немного можно, и даже полезно.
немного полезно, но если кроме тролинга ничего более нет на протяжении "всегда" - это уже диагноз...
не независимо, а весьма определенно
4 знака до и 4 после
или 2 до и 6 после
Слишком много хотите. float не обеспечивает такую точность.
в обоих случаях менее 4 байт.
Интересно, как Вы считали?
Интересно, как Вы считали?
Похоже он решил, что раз в 4-e байта long влезают 10-ти значные числа, то уж тут-то 8-ми значное точно влезет. Логика.
Так и напишите ж по-человечьи, что нельзя. А будет сопротивляться - в википедию его, или куда там ещё.. ))
https://ru.wikipedia.org/wiki/Число_одинарной_точности
Там так прямо и написано:
"Числа одинарной точности с плавающей запятой обеспечивают относительную точность 7-8 десятичных цифр.."
Цифр же. А до запятой они, или после - для этого формата не важно.
Причём, речь именно о гарантированной точности. К тому же относительной, то есть в процентах, а не в цифрах после запятой.
С цифрами может получиться ещё хуже. Если, например, округлять придётся значение 3.9999999999 до значения 4.0000000 - сами видите, вообще ни одной цифры не совпадает. Хотя, при этом, заявленная погрешность не превышена.
этому в университетах не учют.
я не знаю, как оно реализовано в С для ардуины, как ограниченной по числу ресурсов платформы, но считал , что погрешность касается только последнего (2х последних) знака в отведенном объеме памити для этого типа переменной
учитывая то, что в 4 байта влезает число 4 294 967 295 (или +- 2147483647) итого 10 знаков, при этом 9 из них любых
тем самым при 8 знаках - погрешность должна вписываться в 9 и 10й знаки, тем самым не мешать рассчетам до 8 знаков....
--------
отсюда вопрос к профи ардуины - как решить сложившуюся проблему для точных вычислений с правильным округлением для чисел в 8 знаков (4 или 6 после точки)
я пробовал добавлять 9й знак = 0, но это не дало сколь ко бы то нибыло положительного результата
остается видимо отказаться от флоата и поднимать число до целого
а у флоат скока бит под мантиссу отводится? нюшто все 32?
а у флоат скока бит под мантиссу отводится? нюшто все 32?
23 бита
http://www.softelectro.ru/ieee754.html
я не знаю, как оно реализовано в С для ардуины, как ограниченной по числу ресурсов платформы
Точно также как в любой другой платформе - в полном соответссвии со стандартом ISO/IEC 14882:2014
но считал , что
Если бы ты не "считал" а просто почитал устройство плавающих чисел (хоть сам стандарт, хоть любой учебник), то не выглядел бы сейчас идиотом и клоуном.
как решить сложившуюся проблему для точных вычислений с правильным округлением для чисел в 8 знаков (4 или 6 после точки)
Ответ: в рамках типа float, никак.
Пойми ты, наконец, плавающие типы не предназначены для точных вычислений. Например, там нелья (от слова никак) точно записать величину 0,1 - с одним единственным знаком после запятой. Вот нельзя и всё.
Надеюсь, ты не будешь возражать, что на этот раз я тебе по делу ответил?
Неприлично заявлять про 20 языков на уровне выше университетского, а потом спрашивать как 2+1 сложить.
Никто ТС не тянул павлиний хвост распушать, тем более, что под этим павлиньим хвостом оказалась обыкновенная куриная задница.
а у флоат скока бит под мантиссу отводится? нюшто все 32?
У информатиков-аналитиков с 20-ю языками? Да там все 128 не слабо!
Судя по всему, в этом универе не преподавали НИ ОДНОГО языка, поэтому я бы не скромничал, я бы говорил, что я ВСЕ языки знаю на уровне выше университецкого.
а у флоат скока бит под мантиссу отводится? нюшто все 32?
Ну, так, классику, слава Богу, даже Клапауций не запрещал:
«… а другой доказывал, что внутри земного шара имеется другой шар, значительно больше наружного. В сумасшедшем доме каждый мог говорить все, что взбредет ему в голову, словно в парламенте»
Ярослав Гашек. «Похождения бравого солдата Швейка», глава IV
Ворота я не говорил, что это точный тип
вот только что в паскале, что даже в Си шарпе 0.1+0.1=0.2000001 , и если откинуть всё дальше 1 знака после точки, что 0.1+0.1 таки и дадут 0.2 и никак иначе.
всёравно мне не понятнео, кто и главное зачем лобирует распространение Си и С++ ....и почему они упорно не хотят исправлять его недоработки , тормознутость и глючность....
------------
прошу завершить отступления от темы.
-------------
что вы можете предложить, как специалисты, в решении возникшей задачи
я вижу только вариант убрать точку и работать с целым числом.
вы можете подсказать, есть ли еще варианты решения? и какие?
Можно DUE взять там double двойной точности как положено.
Если на паскале возъмете тип single то получите результат один в один как на ардуино.
мошт, ты всётки про float(single) почитаешь маенька? Он что в паскале, что в шарпе и (о боже!) в С++ устроен одинаково, согласно стандарту. И этта, огласи уже название своего университета, чтоб мы, не дай Бог, своих детей туда случайно учица не отдали.