hex в char сравнить с dec

Тема в разделе "Arduino & Shields", создана пользователем ELITE, 3 апр 2018.

  1. ELITE

    ELITE Гик

    в общем столкнулся с задачей сравнить 16ти ричное число полученное строкой с десятичным числом
    но так и не нагуглил нормального решения

    что выходит:
    1) преобразовать десятичное число в строку в 16 ричном представлении через itoa а потом сравнивать или посимвольно или itoa оба числа обернуть...

    2) преобразовать строку в 16йти ричное число через sscanf

    итого 1й вариант за 3 операции +450 б кода
    2й вариант + 2000 б кода....

    както совсем не весело :(

    может есть простое и адекватное решение как например сравнить char[]={'A','3','\0'} с int = 125
     
  2. DIYMan

    DIYMan Guest

    ELITE нравится это.
  3. ELITE

    ELITE Гик

    выходит 3 вариант решения задачи
    ------
    Код (C++):
     char tmp[3]; tmp[0]=nmea[len-4]; tmp[1]=nmea[len-3]; tmp[2]='\0';
                int tmi = 0;
                tmi=strtol(tmp,0,16);
             //   Serial.println(tmp);Serial.println(tmi);
                if(tmi==heshfix){ /*проверка хеша строки/**///Serial.println("hesh VIN!!!!");
    Скетч использует 3868 байт (1%) памяти устройства. Всего доступно 253952 байт.
    Глобальные переменные используют 666 байт (8%) динамической памяти, оставляя 7526 байт для локальных переменных. Максимум: 8192 байт.
    -------
    Код (C++):
    char tmp[3]; tmp[0]=nmea[len-4]; tmp[1]=nmea[len-3]; tmp[2]='\0';
              int tmi = 0;
              sscanf( tmp , "%x" , &tmi); //+2кб
             //   Serial.println(tmi);

                if(tmi==heshfix){ /*проверка хеша строки/**///Serial.println("hesh VIN!!!!");
    Скетч использует 4874 байт (1%) памяти устройства. Всего доступно 253952 байт.
    Глобальные переменные используют 666 байт (8%) динамической памяти, оставляя 7526 байт для локальных переменных. Максимум: 8192 байт.
    ----------
    Код (C++):
     char tmp[5];itoa(heshfix,tmp,16);    //  Serial.println(tmp);
         
             if(atoi(nmea+(len-4))==atoi(tmp)){ /*проверка хеша строки/**///Serial.println("hesh VIN!!!!");
    Скетч использует 3276 байт (1%) памяти устройства. Всего доступно 253952 байт.
    Глобальные переменные используют 664 байт (8%) динамической памяти, оставляя 7528 байт для локальных переменных. Максимум: 8192 байт.
     
  4. ELITE

    ELITE Гик

    да уж... без проверки имеется "Скетч использует 3172 байт "
    3й вариант самый "легкий" и на itoa+2 atoi сжирает 100кб но чтото мне кажется, он не корректен в корне и сравнивает только числа, а если попадется значение из символов ( типа AF) то будет ошибка...

    вариант с strtol +800 байт кода... :(
     
  5. DIYMan

    DIYMan Guest

    Напиши свою, лёгкую реализацию, не вопрос. Там делов-то - на 15 минут ;)
     
  6. Asper Daffy

    Asper Daffy Иксперд

    Т.е. сначала мы преобразуемым число в строку и кладём в tmp. А потом, тут же, эту строку (tmp) преобразуем обратно в число, чтобы сравнить с чем-то там.

    Вы ... простите .... приверженец нетрадиционных удовольствий?
     
  7. ELITE

    ELITE Гик

    я не сильно программист, вот поэтому и спросил, как можно это реализовать более легким способом
     
  8. Asper Daffy

    Asper Daffy Иксперд

    Тебе уже говорили как можно, но ты ведь не слушаешь. У тебя проблема не с этим кодом. ВСЕ коды. которые ты публикуешь, выглядят как горячечный бред.

    Решить это можно так: взять нормальную книгу, читать её и разбирать все примеры. Разбирать, запускать (пробовать поменять и снова запускать), чтобы никаких вопросов вообще не осталось. И вот тогда, после полугода таких занятий, начинать что-то писать.

    Проблему ты можешь решить так, а а не вопросами на форуме.
     
    DIYMan нравится это.
  9. DetSimen

    DetSimen Guest

    На, неуч
    Код (C++):
    int32_t HexStrToInt32(char *instring)
    {
        byte len = strlen(instring);
        if  (len==0) return 0;

        instring = strupr(instring);

        int32_t result = 0;

        for (byte i = 0; i < 8; i++)   // только первые 8 цыфар влезуть в uint32
        {
            char ch = instring[i];
            if (ch == 0) break;

            result <<= 4;

            if (isdigit(ch))
             result = result | (ch - '0');
              else result = result | (ch - 'A' + 10);
        }
        return result;
    }
     
     
    ELITE нравится это.
  10. ELITE

    ELITE Гик

    извините, но не вижу ответа на поставленный вопрос

    использовать strtol - это не самое оптимальное в плане размера кода

    да, можно сделать массив сопоставления и математически формировать число - но это расход озу- а это хочется избежать

    да послать почитать 100500 книг - это самый простой ответ... с таким подходом зачем вообще форум держать - написать вместо форума - идите читайте книги и норм
     
  11. ELITE

    ELITE Гик

    Огромное спасибо!
     
  12. ELITE

    ELITE Гик

    а зачем strupr ?
    зачем строго верхний регистр?
     
  13. ELITE

    ELITE Гик

    byte len = strlen(instring);
    if (len==0) return 0;
    можно опустить, проверка ведь на пустую строку
     
  14. DetSimen

    DetSimen Guest

    я бы от так оставил. Небезопасно, канеш, зато быстро и грязно.

    Код (C++):

    int32_t HexStrToInt32(const char *instring)
    {
        int32_t result = 0;

        if ( instring ) {

            for (byte i = 0; i < 8; i++)   // только первые 8 цыфар влезуть в uint32
            {
                char ch = toupper(instring[i]);
                if (ch == 0) break;

                result <<= 4;

                if (isdigit(ch))
                    result = result | (ch - '0');
                else result = result | (ch - 'A' + 10);
            }
        }

        return result;
    }
     
     
    Последнее редактирование модератором: 4 апр 2018
    ELITE нравится это.
  15. ELITE

    ELITE Гик

    Serial.println(HexStrToInt32('F'));
    дает
    -44
    30
    -109
    19
    -152
    -25
    -175
    -47
    27
    -112
    16
    -155
    -28
    -178
    -49
    24

    Serial.println(HexStrToInt32('5'));
    дает -40
     
  16. ELITE

    ELITE Гик

    Serial.println(HexStrToInt32("55"));
    дает
    85
    5B = 91
     
  17. DetSimen

    DetSimen Guest

    Ну всё правильно, 0х55 = 85 десятичное
    ну и 0х5В = 91 сатвецтвенно
     
  18. Asper Daffy

    Asper Daffy Иксперд

    Ну, вот я ж про тоже.

    Пока у тебя не наберётся ума понять, что это единственный хороший совет, который тебе можно дать, так и будешь оставаться посмешищем и форумным дурачком, и будешь побираться Христа ради за каждой строчкой кода.

    Твой выбор - тебе жить.
     
    DIYMan нравится это.
  19. DetSimen

    DetSimen Guest

    ах, Клапа, прости.
     
  20. DIYMan

    DIYMan Guest

    Помнится, в далёком 2002 году, когда я ещё тусил на RSDN.ru и был там по совместительству модером форума "Исходники" (который сам там и открыл), закинул я общественности задачку на тренировку мозгов, а именно - самописную реализацию atoi для строкового представления чисел в HEX. Так, жвачка, не более. Вот одна из реализаций, где кучу всего учитывается (префиксы, знаки и т.п.):
    Код (C++):
    int hexatoi(const char* str)
    {
      if(!str) return 0;

      int v = 0; // аккумулятор
      bool n = false; // негатив
      char c = *(str++); // пригодится

      // ожидаем пробелы
      while(c == ' ' || c == '\t') c = *(str++);
      if(!c) return 0;

      // ожидаем знак
      // на мой взгляд, так эффективнее, чем громоздить n = (...) ? (...) : (...)
      if(c == '-') { n = true; c = *(str++); }
      else if(c == '+') c = *(str++);
      if(!c) return 0; // В принципе, эту проверку можно опустить. Но она быстрая, облегчит жизнь маломало

      // ожидаем префикс
      // а если это просто 0, то и бог с ним. Не жалко
      if(
        c == '0' &&
        (((c = *(str++)) == 'x') || (c == 'X'))
      ) c = *(str++);

      // ожидаем цифры
      // кто не верит оптимизатору, пусть напишет 55 вместо 'A'-10...
      while(
        (с >= '0' && c <= 'f') && // оптимизирующая проверка - для быстрого отсечения неправильных символов
        ( // повторные проверки c>='0',c<='f' оставлены "для наглядности" (или если убрать оптимизирующую)
          (c >= '0' && c <= '9') && (v <<= 4, v += (c - '0'       ), true) ||
          (c >= 'A' && c <= 'F') && (v <<= 4, v += (c - ('A' - 10)), true) ||
          (c >= 'a' && c <= 'f') && (v <<= 4, v += (c - ('a' - 10)), true)
        )
      ) c = *(str++);

      return n ? -v : v;
    }
     
    ELITE и DetSimen нравится это.