Как сравнить 2 числа?

Zummer
Offline
Зарегистрирован: 25.11.2019

Имеется 2 числа,оба могут находиться в диапазоне от 880 до 1080,как их сравнить по разрядно?

например 2 десятичных числа-1011 и 1010,мы то отличие видим,что в разряде единиц цифры отличаются,а в разрядах десятков,сотен и тысяч одинаковые,а как программно определить равны ли разряды единиц,десятков,сотен и тысяч отличаются или нет?

b707
Offline
Зарегистрирован: 26.05.2017

Zummer пишет:

Имеется 2 числа,оба могут находиться в диапазоне от 880 до 1080,как их сравнить по разрядно?

очевидно, что числа надо разбить на разряды - то есть 880 это будет 0-8-8-0, а 1080 -1-0-8-0 - и каждый разряд сравнить отдельно. Это и будет "поразрядно"

Zummer
Offline
Зарегистрирован: 25.11.2019

Сделал так,но работает не корректно

unsigned  int freq=1011,freqOld=1010;
byte c=0,d = 0;
c = freqOld/ 1000;d =  freq / 1000;
    if(c!=d){не равны разряд тысячных} 
   c = ( freqOld% 1000 ) / 100;d = ( freq% 1000 ) / 100;
    if(c!=d){не равны разряд сотых}
   c = ( freqOld% 100 ) / 10;d = ( freq% 100 ) / 10;
    if(c!=d){не равны разряд десятых}
   c = freqOld% 10;d = freq% 10;
    if(c!=d){не равны разряд единиц}
 




 

b707
Offline
Зарегистрирован: 26.05.2017

Zummer пишет:

работает не корректно

а конкретнее?

Zummer
Offline
Зарегистрирован: 25.11.2019

Так вроде и сделал-разряды разбил,но!

1011 и 1010-показывает разницу,а вот 1010 и 1011-не показывает!мистика

Это мне надо для приемника на RDA5807 и дисплея ILI9341,частота на дисплее 880-1080 (точка искуственная),при перестройке частоты на 1 приходиться перерисовывать все значение частоты,например была 1011,стало 1010,это занимает много времени,быстрее понять в каком разряде изменилось значение и отрисовать только этот разряд,да и помех приему меньше

Zummer
Offline
Зарегистрирован: 25.11.2019

Вот подпрограмма вывода на дисплей-

void  Frequence()
{
//Tft.drawNumber(freqOld, 0, 90, 12, BLACK);freqOld=freq; Tft.drawNumber(freq, 0, 90, 12, BLUE);
   unsigned  int  c=0,d = 0;
//https://robotclass.ru/tutorials/arduino-dynamic-led-indication/
   itoa(freq, buffer, 10);Tft.drawString(buffer, 60, 0, 5, BLUE);
   c = freqOld/ 1000;d =  freq / 1000;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 0, 90, 12, BLACK);freqOld=freq;sprintf(buffer,"%01d",d);Tft.drawString(buffer, 0, 90, 12, BLUE);} 
   c = ( freqOld% 1000 ) / 100;d = ( freq% 1000 ) / 100;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 80, 90, 12, BLACK);freqOld=freq;sprintf(buffer,"%01d",d);Tft.drawString(buffer, 80, 90, 12, BLUE);}
   c = ( freqOld% 100 ) / 10;d = ( freq% 100 ) / 10;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 160, 90, 12, BLACK);freqOld=freq;sprintf(buffer,"%01d",d);Tft.drawString(buffer, 160, 90, 12, BLUE);}
   c = freqOld% 10;d = freq% 10;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 240, 90, 12, BLACK);freqOld=freq;sprintf(buffer,"%01d",d);Tft.drawString(buffer, 240, 90, 12, BLUE);}
   freqOld=freq;
}

 

b707
Offline
Зарегистрирован: 26.05.2017

почему 1010 и 1011 не показывает разницы - не вижу, но в целом у вас в логике ошибка. Подумайте, как будет работать ваш код, если разница будет не в одной цифре, а в двух, например 1010 и 1009

Zummer
Offline
Зарегистрирован: 25.11.2019

если числа 1010 и 1009,то есть на экране частота 1010,и она сменилась на 1009,то как я хочу-

сравниваем тысячные-одинаковые,не перерисовываем

сравниваем сотые-одинаковые,не перерисовываем

сравниваем десятки-отличаются,стираем 1 и рисуем 0

сравниваем единицы-отличаются,стираем 0 и рисуем 9

 

 

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

XOR

Zummer
Offline
Зарегистрирован: 25.11.2019

Спасибо!нашел ошибку,лишние freqOld=freq; в сравнениях!!!

Zummer
Offline
Зарегистрирован: 25.11.2019

Вот так теперь

byte x;
unsigned  int freq=1011,freqOld=9999,c,d;

void  Frequence()
{
    c = freqOld/ 1000;d =  freq / 1000;x=0;if(c!=d){tft_razrjad();}
    c = ( freqOld% 1000 ) / 100;d = ( freq% 1000 ) / 100;x=80;if(c!=d){tft_razrjad();}
    c = ( freqOld% 100 ) / 10;d = ( freq% 100 ) / 10;x=160;if(c!=d){tft_razrjad();}
    c = freqOld% 10;d = freq% 10;x=240;if(c!=d){tft_razrjad();}
  freqOld=freq;
}

void tft_razrjad()
{
    sprintf(buffer,"%d",c);//стираем число в разряде
    Tft.drawString(buffer,x, 90, 12, BLACK);
    sprintf(buffer,"%d",d);//пишем новое число в разряде
    Tft.drawString(buffer, x, 90, 12, BLUE);
  }


Тему можно закрыть!еще раз огромное спасибо!

b707
Offline
Зарегистрирован: 26.05.2017

использование глобальных переменных внутри функции - плохой стиль

Zummer
Offline
Зарегистрирован: 25.11.2019

так?

void  Frequence()
{
  int c,d;
  //тестовое отображение частоты
  sprintf(buffer,"freq=%01d",freqOld );Tft.drawString(buffer, 60, 0, 4, BLACK);sprintf(buffer,"freq=%01d",freq );Tft.drawString(buffer, 60, 0, 4, BLUE);
  c = freqOld/ 1000;d =  freq / 1000;x=0;if(c!=d){tft_razrjad(c,d);}
  c = ( freqOld% 1000 ) / 100;d = ( freq% 1000 ) / 100;x=80;if(c!=d){tft_razrjad(c,d);}
  c = ( freqOld% 100 ) / 10;d = ( freq% 100 ) / 10;x=160;if(c!=d){tft_razrjad(c,d);}
  c = freqOld% 10;d = freq% 10;x=240;if(c!=d){tft_razrjad(c,d);}
  freqOld=freq;
}

void tft_razrjad(int val0,int val1)
{
  sprintf(buffer,"%d",val0);//стираем число в разряде
  Tft.drawString(buffer,x, 90, 12, BLACK);
  sprintf(buffer,"%d",val1);//пишем новое число в разряде
  Tft.drawString(buffer, x, 90, 12, BLUE);
}

 

b707
Offline
Зарегистрирован: 26.05.2017

Во-первых, так вообще работать не будет - buffer потеряли.

Ну и кроме того, касаемо стиля стало еще хуже - теперь в процедуре Frequence() куча глобальных параметров, описанных непонятно где и используемых "втемную". Уж лучше прежний вариант верните :)

sadman41
Offline
Зарегистрирован: 19.10.2016

Если надо сравнивать не числа, а символы в строке, то я бы так и поступил (хоть это и неизящно): законвертил два числа в две ASCIIZ строки и пробежался по ним циклом. Символ не совпадает - перерисовываем.

Zummer
Offline
Зарегистрирован: 25.11.2019

b707 по мне так в посте 5 для меня нагляднее,там норм?

void  Frequence()
{
  int  c=0,d = 0;
 c = freqOld/ 1000;d =  freq / 1000;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 0, 90, 12, BLACK);sprintf(buffer,"%01d",d);Tft.drawString(buffer, 0, 90, 12, BLUE);} 
   c = ( freqOld% 1000 ) / 100;d = ( freq% 1000 ) / 100;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 80, 90, 12, BLACK);sprintf(buffer,"%01d",d);Tft.drawString(buffer, 80, 90, 12, BLUE);}
   c = ( freqOld% 100 ) / 10;d = ( freq% 100 ) / 10;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 160, 90, 12, BLACK);sprintf(buffer,"%01d",d);Tft.drawString(buffer, 160, 90, 12, BLUE);}
   c = freqOld% 10;d = freq% 10;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 240, 90, 12, BLACK);sprintf(buffer,"%01d",d);Tft.drawString(buffer, 240, 90, 12, BLUE);}
   freqOld=freq;
}

 

b707
Offline
Зарегистрирован: 26.05.2017

Zummer пишет:

b707 по мне так в посте 5 для меня нагляднее

ну и оставьте. Это я уже придираться стал. Главное работает

 

Zummer
Offline
Зарегистрирован: 25.11.2019

оставил так,еще раз спасибо!

void  Frequence()
{
   int  c=0,d = 0;
   c = freqOld/ 1000;d =  freq / 1000;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 0, 90, 12, BLACK);sprintf(buffer,"%01d",d);Tft.drawString(buffer, 0, 90, 12, BLUE);} 
   c = ( freqOld% 1000 ) / 100;d = ( freq% 1000 ) / 100;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 80, 90, 12, BLACK);sprintf(buffer,"%01d",d);Tft.drawString(buffer, 80, 90, 12, BLUE);}
   c = ( freqOld% 100 ) / 10;d = ( freq% 100 ) / 10;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 160, 90, 12, BLACK);sprintf(buffer,"%01d",d);Tft.drawString(buffer, 160, 90, 12, BLUE);}
   c = freqOld% 10;d = freq% 10;
    if(c!=d){sprintf(buffer,"%01d",c);Tft.drawString(buffer, 240, 90, 12, BLACK);sprintf(buffer,"%01d",d);Tft.drawString(buffer, 240, 90, 12, BLUE);}
   freqOld=freq;
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Мой вариант (для обдумывания):

void showFrequency(uint16_t _newFrequency) {
   static char oldFreqStr[0x06];
   char newFreqStr[0x06];
   uint8_t  charNo = 0x00;
   uint16_t printPos = 0x00;


   snprintf(newFreqStr, sizeof(newFreqStr), "%5u", _newFrequency);
   while (newFreqStr[charNo]) {
     if (newFreqStr[charNo] != oldFreqStr[charNo]) {
        // .drawChar() is exist?
        Tft.drawChar(oldFreqStr[charNo], printPos, 90, 12, BLACK);
        Tft.drawChar(newFreqStr[charNo], printPos, 90, 12, BLUE);
     }
     printPos += 80;
     charNo++;
   }
  // char-to-char copy can be done in the while() loop
  memcpy(oldFreqStr, newFreqStr, sizeof(oldFreqStr));
}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

А у меня частоты тоже целыми хранятся, дак я их абычна так вывожу

uint16_t Freq = 1007;    // 100.7 частота радио Uniton в Н-ске
Serial << Freq/10 << '.' << Freq%10;

из 870 - 1080  делает 87.0 - 108.0

Zummer
Offline
Зарегистрирован: 25.11.2019

А просто рисую точку и все,никаких лишних вычислений,каждый разряд имеет свое знакоместо на дисплее

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Zummer пишет:

А просто рисую точку и все,никаких лишних вычислений,каждый разряд имеет свое знакоместо на дисплее

В частном случае использования семисегментника для отображения - да, метод годный. Но не всегда используется семисегментник ;) И поэтому дополнительные вычисления делать приходится (например, шрифты могут использоваться пропорциональные, а не моноширинные).

Zummer
Offline
Зарегистрирован: 25.11.2019

DIYMan пишет:

Zummer пишет:

А просто рисую точку и все,никаких лишних вычислений,каждый разряд имеет свое знакоместо на дисплее

В частном случае использования семисегментника для отображения - да, метод годный. Но не всегда используется семисегментник ;) И поэтому дополнительные вычисления делать приходится (например, шрифты могут использоваться пропорциональные, а не моноширинные).

какой семисегментник? вы тему читали? дисплей ILI9341! и зачем для точки выделять знакоместо 72*96 пикселей (шрифт 6*8 ,увеличение в 12 раз) пикселей мне не понятно...нарисовал искуственно точку и забыл

Tft.drawString(buffer, 80, 90, 12, BLUE);

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Zummer пишет:

какой семисегментник? вы тему читали? дисплей ILI9341! и зачем для точки выделять знакоместо 72*96 пикселей (шрифт 6*8 ,увеличение в 12 раз) пикселей мне не понятно...нарисовал искуственно точку и забыл

Tft.drawString(buffer, 80, 90, 12, BLUE);

В любом случае, семисегментник или нет - это частный случай. Шрифты - бывают разные. Например, в библиотеке UTFT - они моноширинные, в других библиотеках - есть пропорциональные. Во втором случае, "нарисованная искусственно" точка по фиксированным координатам, при использовании пропорционального шрифта - может вызвать эффект визуальной "разорванности". Именно поэтому я и написал - это конкретно частный случай, великолепно заточенный либо под семисегментник (моноширинный шрифт однозначно), либо - под моноширинный шрифт на TFT-дисплее.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Я чего-то не понимаю. Если есть желание сравнить два числа, то надо вычесть из одного другое.  Если сравнивать по разрядно, то такая-же петрушка. Выделить разряды каждого и вычесть из одного другое.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Что же касается получения значения определённого разряда числа - то вот, навскидку, вариант, без кучи if и использования pow. Запустить можно здесь: http://cpp.sh/37krb

// Example program
#include <iostream>
#include <string>
using namespace std;

int getRank(int num, int rank)
{
    int k = 1;
    for(int i=0;i<rank;i++)
    {
        k *= 10;
    }
    
    int k2 = k/10;
    if(!k2)
    {
        k2 = 1;
    }
    
    return num%k/k2;
}

int main()
{
  int i1 = 1234;
  
  
  cout << getRank(i1,1) << '\n';
  cout << getRank(i1,2) << '\n';
  cout << getRank(i1,3) << '\n';
  cout << getRank(i1,4) << '\n';
  cout << getRank(i1,5) << '\n';
}

Как посчитать кол-во разрядов числа - тоже мог бы подсказать, но из палаты не выпускают.

Zummer
Offline
Зарегистрирован: 25.11.2019

DIYMan пишет:
И дисплей ILI9341 - тут совершенно не в дырочку, что такому дураку, как вы - безусловно, не понять. 

как не в дырочку? пост http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/kak-sravnit-2-chisla#comment-508117 ,это ваши семисегментники не в тему

не хотел вам грубить,просто вы достали с этой точкой,которая только у вас  вызывает чувство "разорванности"

Извините!

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Zummer пишет:

DIYMan пишет:
И дисплей ILI9341 - тут совершенно не в дырочку, что такому дураку, как вы - безусловно, не понять. 

как не в дырочку? пост http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/kak-sravnit-2-chisla#comment-508117 ,это ваши семисегментники не в тему

не хотел вам грубить,просто вы достали с этой точкой,которая только у вас  вызывает чувство "разорванности"

Извините!

Строго говоря - я пишу не только для вас. В том числе и для людей, которые понимают, что контроллеров TFT-дисплеев - множество, а не только ILI9341. В том числе - для людей, которые понимают, что инструменты для вывода информации на дисплей, включая библиотеки и шрифты - могут использоваться разные. И именно поэтому я упомянул, что ваше решение - только частный случай, и объяснил, почему.

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

Zummer
Offline
Зарегистрирован: 25.11.2019

Еще возник вопрос,не по теме-тачскрину,здесь задавать или плодить еще темы?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Zummer пишет:

Еще возник вопрос,не по теме-тачскрину,здесь задавать или плодить еще темы?

Какой контроллер тачскрина - для начала?

Zummer
Offline
Зарегистрирован: 25.11.2019

У меня только сама панель тачскрина от дисплея SPFD5408 ,без контроллера,в файле "TFTv2.h"  есть строки-

#define YP A2   // must be an analog pin, use "An" notation!
#define XM A1   // must be an analog pin, use "An" notation!
#define YM 14   // can be a digital pin, this is A0
#define XP 17   // can be a digital pin, this is A3

Также в примере программы "POINT" есть библиотека "#include <SeeedTouchScreen.h>",ее я нашел https://github.com/Seeed-Studio/TFT_Touch_Shield_V2 ,будет ли работать? если заработает то можно отказаться от кнопок,тогда вообще будет красота!

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Тач - резистивный, ничего не мешает попробовать, тем более - есть с чего начать. Вот тут нашёл статейку, там про ваш тачскрин, похоже: https://misc.ws/2013/11/08/touch-screen-shield-for-arduino-uno/

На форуме тоже мелькало: http://arduino.ru/forum/apparatnye-voprosy/deshevyi-tft-24-displei-na-spfd5408

Также похоже, что указанная вами библиотека от SeedStudio тоже подойдёт.

Zummer
Offline
Зарегистрирован: 25.11.2019

К сожалению ILI9341 с тачскрином и TSC2046 стоит в другом проекте,если здесь тач не заработает придется выдернуть оттуда контроллер

Попробую подключить тач без контроллера,спасибо!

Zummer
Offline
Зарегистрирован: 25.11.2019

Работает!!! огромное спасибо!

только подправил 

#define TS_MINX 185    //лево
#define TS_MAXX 1750   //право
#define TS_MINY 270     ////верх
#define TS_MAXY 1770 //низ

#define YP A2   // must be an analog pin, use "An" notation!
#define XM A3   // must be an analog pin, use "An" notation!
#define YM 5    // can be a digital pin, this is A0
#define XP 6    // can be a digital pin, this is A3

 

Zummer
Offline
Зарегистрирован: 25.11.2019

Пока так,осталось добавить часы и термометр

(120 28 это координаты нажатия на тач,для отладки)