В той строчке, что прокомментированна "<----- ВОТ ЗДЕСЬ ПРОИСХОДИТ!!!!" случается странная вещь — маленький байтик из 0x00 превращается в 0xFFFFFF<правильное значение байта>.
Чтобы совсем было инетересно, такое происходит только если вводимое значение больше 0xF
Пробовал использовать вместо char AnsiString, делал прямое преобразование типов через (char) но без толку.
На форуме не искал, потому что не знаю даже какую строку поиска использовать.
Здравствуйте, MTimur, Вы писали:
MT>Здравствуйте, b00tanik, Вы писали:
MT>Результат работы функции присваиваете int'у? Тогда зачем возвращаете char? MT>Если нет — тогда почему val не сделать char'ом?
B>В той строчке, что прокомментированна "<----- ВОТ ЗДЕСЬ ПРОИСХОДИТ!!!!" случается странная вещь — маленький байтик из 0x00 превращается в 0xFFFFFF<правильное значение байта>.
B>Чтобы совсем было инетересно, такое происходит только если вводимое значение больше 0xF
А как вы это смотрите? В выделенной строчке char в int не конвертируется.
Происходит распространение знакового бита: При конвертировании char в int значение char -1 (0xFF) превращается в значение 0xFFFFFFFF (-1 в int). Подробнее — гуглить по словам дополнительный код. Для исправления надо поменять char на unsigned char.
Здравствуйте, Fwiffo, Вы писали:
F>А как вы это смотрите? В выделенной строчке char в int не конвертируется. F>Происходит распространение знакового бита: При конвертировании char в int значение char -1 (0xFF) превращается в значение 0xFFFFFFFF (-1 в int). Подробнее — гуглить по словам дополнительный код. Для исправления надо поменять char на unsigned char.
Здравствуйте, 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;
Здравствуйте, MTimur, Вы писали:
MT>Криво, но работать будет, если проблема действительно в этой строке, в чем я сильно сомневаюсь. Мне не понятно как 1 байт превратился аж 4. Проблема скорее всего не в этой строке, а в той, где Вы результат функции присваиваете int'у. Покажите эту строку. MT>Byte = val & 0xFF;
Здравствуйте, b00tanik, Вы писали:
B>Здравствуйте, MTimur, Вы писали:
MT>>Криво, но работать будет, если проблема действительно в этой строке, в чем я сильно сомневаюсь. Мне не понятно как 1 байт превратился аж 4. Проблема скорее всего не в этой строке, а в той, где Вы результат функции присваиваете int'у. Покажите эту строку. MT>>Byte = val & 0xFF;
B>клиника... ничего не изменилось.... Вообще ничего
Покажите строку в которой Вы вызываете эту функцию.
Здравствуйте, b00tanik, Вы писали:
B>Здравствуйте, Fwiffo, Вы писали:
F>>А как вы это смотрите? В выделенной строчке char в int не конвертируется. F>>Происходит распространение знакового бита: При конвертировании char в int значение char -1 (0xFF) превращается в значение 0xFFFFFFFF (-1 в int). Подробнее — гуглить по словам дополнительный код. Для исправления надо поменять char на unsigned char.
B>Смотрю с помощью Watch в отладчите Borland C++
Хм. А печатать в консоль не пробовали? Может это багландовский отладчик такой одаренный? Непонятно почему он вместо одного байта показывает 4
Здравствуйте, MTimur, Вы писали:
MT>Здравствуйте, b00tanik, Вы писали:
MT>Результат работы функции присваиваете int'у? Тогда зачем возвращаете char? MT>Если нет — тогда почему val не сделать char'ом?
Нечто подобное встречал когдато давно в Delphi (он тогда еще был Borland)
Боролся с помощью отключения оптимизации в настройках компиляции.
Здравствуйте, 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) заставил меня забить тревогу и полезть в глубокую отладку...
Первым делом, конечно, начал грешить на нее, но она работает так, как и надо....
Если позволите оффтоп, то отладчик борландовский очень даже неплох
Здравствуйте, b00tanik, Вы писали:
B>Здравствуйте, Fwiffo, Вы писали:
F>>Хм. А печатать в консоль не пробовали? Может это багландовский отладчик такой одаренный? Непонятно почему он вместо одного байта показывает 4
B>К сожалению, работаю не с консолью, вывожу в RichEdit строку, полученную такой функцией
B>
B>Именно вывод этой функции(а выводила она много лишних F) заставил меня забить тревогу и полезть в глубокую отладку... B>Первым делом, конечно, начал грешить на нее, но она работает так, как и надо....
B>Если позволите оффтоп, то отладчик борландовский очень даже неплох
Проблема Ваша в этой строке B> returnstr=returnstr+" 0x"+tmpstr.IntToHex(what[i],0);
нужно или так
Здравствуйте, 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
Здравствуйте, b00tanik, Вы писали:
B>Здравствуйте, MTimur, Вы писали:
MT>>Покажите строку в которой Вы вызываете эту функцию.
B>Вообще эта функция вызывается внутри switch вот так:
B>причем sprintf() УЖЕ записывает в формат %c эту ненужную кучу F
Здравствуйте, 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)
Здравствуйте, 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 беззнаковым. Тогда компилятор правильно преобразует переменные.
Здравствуйте, MTimur, Вы писали:
MT>Это не помогает потому что Вы не обращаете внимание на типы данных. 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)
Ненене! Преобразование /*signed*/ char -> unsigned int приводит к расширению знакового разряда, а если не приводит — то выкиньте такой компилятор нафиг (он не соответствует Стандарту).
Корректный способ получить unsigned int — это (unsigned int)(unsigned char)what[0].
Ну или просто (unsigned char)what[0], а дальше он сам расширится до чего хотите — хоть до неотрицательного int, хоть до unsigned int.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, MTimur, Вы писали:
MT>>Это не помогает потому что Вы не обращаете внимание на типы данных. MT>>если what[0] у Вас 0xFF (-1), то
К>Ненене! Преобразование /*signed*/ char -> unsigned int приводит к расширению знакового разряда, а если не приводит — то выкиньте такой компилятор нафиг (он не соответствует Стандарту). К>Корректный способ получить unsigned int — это (unsigned int)(unsigned char)what[0]. К>Ну или просто (unsigned char)what[0], а дальше он сам расширится до чего хотите — хоть до неотрицательного int, хоть до unsigned int.
Ну так вроде я это и написал... Или я не совсем понимаю о чем Вы.
здесь what[0] и есть /*signed*/ char MT>> int a = what[0]; MT>>unsigned int b = what[0]; MT>>дадут результат: MT>>a = -1 = 0xFFFFFFFF (что у Вас и происходит) MT>>b = 255 = 0x000000FF (аналогичный результат получите, если наложите на a маску 0xFF)
Здравствуйте, b00tanik, Вы писали:
B>К сожалению, работаю не с консолью, вывожу в RichEdit строку, полученную такой функцией
Это называется — искусство грамотно задавать вопросы.
Если бы ты с самого начала привёл код, где ошибка проявляется, а не где она предположительно зарождается, было бы на 10 левых сообщений меньше
Потому что ошибка зародилась прямо в точке проявления
Кстати сказать, грабли детские и от этого особенно больные.
На расширении char до int / size_t / etc. основаны и ошибки вывода, и даже расстрелы памяти.
Например, мы захотели сделать табличную функцию
Здравствуйте, MTimur, Вы писали:
MT>Ну так вроде я это и написал... Или я не совсем понимаю о чем Вы.
MT>>> int a = what[0]; MT>>>unsigned int b = what[0];
Если what[0] — /*signed*/ char, то a=-1, b=(unsigned)-1=0xFFFFFFFF.
Если what[0] — unsigned char, то a=b=0x000000FF.
Как тебе удалось получить MT>>>a = -1 = 0xFFFFFFFF (что у Вас и происходит) MT>>>b = 255 = 0x000000FF (аналогичный результат получите, если наложите на a маску 0xFF)
это загадка из загадок.
А использовать unsigned char переменную — это
— тот же самый кастинг к unsigned char — только неявный (в месте, где она присваивается)
— не всегда возможно и не всегда корректно
char[] — как правило, строка. unsigned char[] — просто массив байтов.
Скажем, GetHex("hello") или GetHex(AnsiString("hello")) — в обоих случаях на входе именно строка. Можно, конечно, поплясать с бубном:
А смысл? Сперва создать себе сложности, потом героически их побороть.
Пусть уж лучше внутри GetHex корректно работает с байтами, получаемыми из символов.