Проблема с преобразованием типов
От: b00tanik  
Дата: 13.05.09 18:40
Оценка:
Здравствуйте! Среда Программирования Borland C++ 6.0, OS — Win7(En)

Для чтения одного байта, задаваемого в шестнадцатеричном формате использую следующий код:

Код:

char GetByte(AnsiString what= "#d"){
      char Byte=0;
      AnsiString InpD="",
                Caption="Entering "+what, Text="Enter "+what,
                 NotValid="Not valid "+what+" value";
      bool CorrFlag=false;
      int val=0;
      do{
        CorrFlag=true;
        InpD=InputBox(Caption.c_str(), Text.c_str(), "0x00");
        sscanf(InpD.c_str(),"0x%x", &val);
        if(val<0 || val>0xFF){
                Application->MessageBoxA(NotValid.c_str(), "Invalid", MB_OK | MB_ICONERROR);
                CorrFlag=false;
        } else {
                Byte = val; // <----- ВОТ ЗДЕСЬ ПРОИСХОДИТ!!!!
        }
      } while (InpD.Length()<=0 || !CorrFlag);
      return Byte;
}



В той строчке, что прокомментированна "<----- ВОТ ЗДЕСЬ ПРОИСХОДИТ!!!!" случается странная вещь — маленький байтик из 0x00 превращается в 0xFFFFFF<правильное значение байта>.

Чтобы совсем было инетересно, такое происходит только если вводимое значение больше 0xF

Пробовал использовать вместо char AnsiString, делал прямое преобразование типов через (char) но без толку.

На форуме не искал, потому что не знаю даже какую строку поиска использовать.

Есть идеи как это вылечить?
типы странности
Re: Проблема с преобразованием типов
От: MTimur  
Дата: 13.05.09 19:42
Оценка:
Здравствуйте, b00tanik, Вы писали:

Результат работы функции присваиваете int'у? Тогда зачем возвращаете char?
Если нет — тогда почему val не сделать char'ом?
Re[2]: Проблема с преобразованием типов
От: b00tanik  
Дата: 14.05.09 03:03
Оценка:
Здравствуйте, MTimur, Вы писали:

MT>Здравствуйте, b00tanik, Вы писали:


MT>Результат работы функции присваиваете int'у? Тогда зачем возвращаете char?

MT>Если нет — тогда почему val не сделать char'ом?

потому что может произойти переполнение типа.
Re: Проблема с преобразованием типов
От: Fwiffo Россия  
Дата: 14.05.09 10:22
Оценка:
Здравствуйте, b00tanik, Вы писали:


B>В той строчке, что прокомментированна "<----- ВОТ ЗДЕСЬ ПРОИСХОДИТ!!!!" случается странная вещь — маленький байтик из 0x00 превращается в 0xFFFFFF<правильное значение байта>.


B>Чтобы совсем было инетересно, такое происходит только если вводимое значение больше 0xF


А как вы это смотрите? В выделенной строчке char в int не конвертируется.
Происходит распространение знакового бита: При конвертировании char в int значение char -1 (0xFF) превращается в значение 0xFFFFFFFF (-1 в int). Подробнее — гуглить по словам дополнительный код. Для исправления надо поменять char на unsigned char.
Re[2]: Проблема с преобразованием типов
От: b00tanik  
Дата: 14.05.09 11:31
Оценка:
Здравствуйте, Fwiffo, Вы писали:

F>А как вы это смотрите? В выделенной строчке char в int не конвертируется.

F>Происходит распространение знакового бита: При конвертировании char в int значение char -1 (0xFF) превращается в значение 0xFFFFFFFF (-1 в int). Подробнее — гуглить по словам дополнительный код. Для исправления надо поменять char на unsigned char.


Смотрю с помощью Watch в отладчите Borland C++

Поменял. функция стала выглядеть так:
unsigned char GetByte(AnsiString what= "#d"){
      unsigned char Byte=0;
      AnsiString InpD="",
                Caption="Entering "+what, Text="Enter "+what,
                 NotValid="Not valid "+what+" value";
      bool CorrFlag=false;
      int val=0;
      do{
        CorrFlag=true;
        InpD=InputBox(Caption.c_str(), Text.c_str(), "0x00");
        sscanf(InpD.c_str(),"0x%x", &val);
        if(val<0 || val>0xFF){
                Application->MessageBoxA(NotValid.c_str(), "Invalid", MB_OK | MB_ICONERROR);
                CorrFlag=false;
        } else {
                Byte =  val;
        }
      } while (InpD.Length()<=0 || !CorrFlag);
      return Byte;
}

Но, к сожалению не спасло.... Проблема там где и была, там и осталась.... смотрю в сторону того, чтобы вручную производить нужное мне преобразование
Re[3]: Проблема с преобразованием типов
От: MTimur  
Дата: 14.05.09 12:07
Оценка:
Здравствуйте, b00tanik, Вы писали:

B>Здравствуйте, Fwiffo, Вы писали:


F>>А как вы это смотрите? В выделенной строчке char в int не конвертируется.

F>>Происходит распространение знакового бита: При конвертировании char в int значение char -1 (0xFF) превращается в значение 0xFFFFFFFF (-1 в int). Подробнее — гуглить по словам дополнительный код. Для исправления надо поменять char на unsigned char.


B>Но, к сожалению не спасло.... Проблема там где и была, там и осталась.... смотрю в сторону того, чтобы вручную производить нужное мне преобразование


Криво, но работать будет, если проблема действительно в этой строке, в чем я сильно сомневаюсь. Мне не понятно как 1 байт превратился аж 4. Проблема скорее всего не в этой строке, а в той, где Вы результат функции присваиваете int'у. Покажите эту строку.
Byte = val & 0xFF;
Re[4]: Проблема с преобразованием типов
От: b00tanik  
Дата: 14.05.09 12:27
Оценка:
Здравствуйте, MTimur, Вы писали:

MT>Криво, но работать будет, если проблема действительно в этой строке, в чем я сильно сомневаюсь. Мне не понятно как 1 байт превратился аж 4. Проблема скорее всего не в этой строке, а в той, где Вы результат функции присваиваете int'у. Покажите эту строку.

MT>Byte = val & 0xFF;

клиника... ничего не изменилось.... Вообще ничего
Re[5]: Проблема с преобразованием типов
От: MTimur  
Дата: 14.05.09 12:27
Оценка:
Здравствуйте, b00tanik, Вы писали:

B>Здравствуйте, MTimur, Вы писали:


MT>>Криво, но работать будет, если проблема действительно в этой строке, в чем я сильно сомневаюсь. Мне не понятно как 1 байт превратился аж 4. Проблема скорее всего не в этой строке, а в той, где Вы результат функции присваиваете int'у. Покажите эту строку.

MT>>Byte = val & 0xFF;

B>клиника... ничего не изменилось.... Вообще ничего


Покажите строку в которой Вы вызываете эту функцию.
Re[3]: Проблема с преобразованием типов
От: Fwiffo Россия  
Дата: 14.05.09 12:31
Оценка:
Здравствуйте, b00tanik, Вы писали:

B>Здравствуйте, Fwiffo, Вы писали:


F>>А как вы это смотрите? В выделенной строчке char в int не конвертируется.

F>>Происходит распространение знакового бита: При конвертировании char в int значение char -1 (0xFF) превращается в значение 0xFFFFFFFF (-1 в int). Подробнее — гуглить по словам дополнительный код. Для исправления надо поменять char на unsigned char.


B>Смотрю с помощью Watch в отладчите Borland C++


Хм. А печатать в консоль не пробовали? Может это багландовский отладчик такой одаренный? Непонятно почему он вместо одного байта показывает 4
Re[2]: Проблема с преобразованием типов
От: TimurSPB Интернет  
Дата: 14.05.09 12:43
Оценка:
Здравствуйте, MTimur, Вы писали:

MT>Здравствуйте, b00tanik, Вы писали:


MT>Результат работы функции присваиваете int'у? Тогда зачем возвращаете char?

MT>Если нет — тогда почему val не сделать char'ом?

Нечто подобное встречал когдато давно в Delphi (он тогда еще был Borland)
Боролся с помощью отключения оптимизации в настройках компиляции.
Make flame.politics Great Again!
Re[4]: Проблема с преобразованием типов
От: b00tanik  
Дата: 14.05.09 13:14
Оценка:
Здравствуйте, Fwiffo, Вы писали:

F>Хм. А печатать в консоль не пробовали? Может это багландовский отладчик такой одаренный? Непонятно почему он вместо одного байта показывает 4


К сожалению, работаю не с консолью, вывожу в RichEdit строку, полученную такой функцией

AnsiString GetHex(char what[], int much=128){
        AnsiString returnstr="";
        AnsiString tmpstr="";
        for (int i=0; i<much; i++){
             returnstr=returnstr+" 0x"+tmpstr.IntToHex(what[i],0);
        }
        return returnstr;
}


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

Если позволите оффтоп, то отладчик борландовский очень даже неплох
Re[3]: Проблема с преобразованием типов
От: b00tanik  
Дата: 14.05.09 13:20
Оценка:
Здравствуйте, TimurSPB, Вы писали:

TSP>Боролся с помощью отключения оптимизации в настройках компиляции.


Отключал так: Project->Options->Compiler->Code Optimization выбрал none.
Если все верно, то этот способ не помогает
Re[5]: Проблема с преобразованием типов
От: MTimur  
Дата: 14.05.09 13:21
Оценка:
Здравствуйте, b00tanik, Вы писали:

B>Здравствуйте, Fwiffo, Вы писали:


F>>Хм. А печатать в консоль не пробовали? Может это багландовский отладчик такой одаренный? Непонятно почему он вместо одного байта показывает 4


B>К сожалению, работаю не с консолью, вывожу в RichEdit строку, полученную такой функцией


B>
B>AnsiString GetHex(char what[], int much=128){
B>        AnsiString returnstr="";
B>        AnsiString tmpstr="";
B>        for (int i=0; i<much; i++){
B>             returnstr=returnstr+" 0x"+tmpstr.IntToHex(what[i],0);
B>        }
B>        return returnstr;
B>}
B>


B>Именно вывод этой функции(а выводила она много лишних F) заставил меня забить тревогу и полезть в глубокую отладку...

B>Первым делом, конечно, начал грешить на нее, но она работает так, как и надо....

B>Если позволите оффтоп, то отладчик борландовский очень даже неплох


Проблема Ваша в этой строке
B> returnstr=returnstr+" 0x"+tmpstr.IntToHex(what[i],0);
нужно или так

returnstr=returnstr+" 0x"+tmpstr.IntToHex(what[i] & 0xFF,0);


или лучше так

returnstr=returnstr+" 0x"+tmpstr.IntToHex((int)what[i],0);
Re[6]: Проблема с преобразованием типов
От: b00tanik  
Дата: 14.05.09 13:30
Оценка:
Здравствуйте, MTimur, Вы писали:

MT>Покажите строку в которой Вы вызываете эту функцию.


Вообще эта функция вызывается внутри switch вот так:


 unsigned char Byte1=0, Byte2=0;
        switch (CurrSelCom){
                case 0x44:
                {     // orl a,#d
                        Byte1=GetByte();
                        CurrCommand.sprintf("%c%c",0x44,Byte1);
                        break;
                }
// тут еще несколько case .....


причем sprintf() УЖЕ записывает в формат %c эту ненужную кучу F
Re[7]: Проблема с преобразованием типов
От: MTimur  
Дата: 14.05.09 13:35
Оценка:
Здравствуйте, b00tanik, Вы писали:

B>Здравствуйте, MTimur, Вы писали:


MT>>Покажите строку в которой Вы вызываете эту функцию.


B>Вообще эта функция вызывается внутри switch вот так:


B>причем sprintf() УЖЕ записывает в формат %c эту ненужную кучу F


фантастика...
какой результат sizeof(Byte1)?
Re[6]: Проблема с преобразованием типов
От: b00tanik  
Дата: 14.05.09 13:37
Оценка:
Здравствуйте, MTimur, Вы писали:

MT>нужно или так


MT>
MT>returnstr=returnstr+" 0x"+tmpstr.IntToHex(what[i] & 0xFF,0);
MT>


Вот это помогло, только интуиция моя подсказывает что где-то здесь подвох, потому что вот это:

MT>
MT>returnstr=returnstr+" 0x"+tmpstr.IntToHex((int)what[i],0);
MT>


Не помогает
Re[8]: Проблема с преобразованием типов
От: b00tanik  
Дата: 14.05.09 13:42
Оценка:
Здравствуйте, MTimur, Вы писали:

MT>фантастика...

MT>какой результат sizeof(Byte1)?

Как и у всех нормальных char он равен единице.....
Вы тоже надеялись на четверку?

Тут ниже было найдено решение, приводящее вывод в нужный вид... но баг не отменяющее.
Re[7]: Проблема с преобразованием типов
От: MTimur  
Дата: 14.05.09 13:46
Оценка:
Здравствуйте, b00tanik, Вы писали:

B>Здравствуйте, MTimur, Вы писали:


MT>>нужно или так


MT>>
MT>>returnstr=returnstr+" 0x"+tmpstr.IntToHex(what[i] & 0xFF,0);
MT>>


B>Вот это помогло, только интуиция моя подсказывает что где-то здесь подвох, потому что вот это:


MT>>
MT>>returnstr=returnstr+" 0x"+tmpstr.IntToHex((int)what[i],0);
MT>>


B>Не помогает


Это не помогает потому что Вы не обращаете внимание на типы данных.
если what[0] у Вас 0xFF (-1), то

         int a = what[0];
unsigned int b = what[0];


дадут результат:

a = -1 = 0xFFFFFFFF (что у Вас и происходит)
b = 255 = 0x000000FF (аналогичный результат получите, если наложите на a маску 0xFF)
Re[8]: Проблема с преобразованием типов
От: b00tanik  
Дата: 14.05.09 13:51
Оценка:
Здравствуйте, MTimur, Вы писали:

MT>если what[0] у Вас 0xFF (-1), то


MT>
MT>         int a = what[0];
MT>unsigned int b = what[0];

MT>


MT>дадут результат:


MT>a = -1 = 0xFFFFFFFF (что у Вас и происходит)

MT>b = 255 = 0x000000FF (аналогичный результат получите, если наложите на a маску 0xFF)

Большое спасибо за разъяснение. Решение найдено.
Re[9]: Проблема с преобразованием типов
От: MTimur  
Дата: 14.05.09 13:55
Оценка:
Здравствуйте, b00tanik, Вы писали:

B>Здравствуйте, MTimur, Вы писали:


MT>>если what[0] у Вас 0xFF (-1), то


MT>>
MT>>         int a = what[0];
MT>>unsigned int b = what[0];

MT>>


MT>>дадут результат:


MT>>a = -1 = 0xFFFFFFFF (что у Вас и происходит)

MT>>b = 255 = 0x000000FF (аналогичный результат получите, если наложите на a маску 0xFF)

B>Большое спасибо за разъяснение. Решение найдено.


На всякий случай уточню. Решение с маской — костыли. Правильный выход — сделайте массив what беззнаковым. Тогда компилятор правильно преобразует переменные.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.