Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы с преобразованием типов данных в MinGW, Непонятные особенности MinGW 
:(
    Опции темы
AliensX
Дата 22.12.2008, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 22.12.2008

Репутация: нет
Всего: нет



Приветствую, уважаемые кодеры.

При написании некоторого приложения, используя компилятор MinGW 5.1.4, столкнулся с некоторой очень странной проблемой, для того, чтобы объяснить суть проблемы, приведу небольшой незамысловатый код:

Код


#include <stdio.h>
#include <iostream>

using namespace std;

int main() {

    int i = 210;
    char x = (char)i;

    cout << (int)x << endl;
    printf("%i", x);

}



Здесь мы имеем целочисленную переменную, которую используем в качестве кода символа для переменной x.
Далее мы обратно преобразуем получившейся символ в целочисленный тип.

Очевидно, что результатом выполнения данного кода должен быть результат
210
210
Однако, результат выполнения совсем другой:
-46
-46

Возможно, я просто что-то не понимаю, но идей по поводу как такое в принцепи может быть никаких нету, разве что оно как-то связано с текущей кодировкой.
Стоит отметить, что если использовать другие коды символов, например, 12, то результат выполнения получается правильным. Но 210 далеко не единственный код, при котором программа ведет себя некорректно.

Очень хочется услышать предположения знающих людей по этому поводу.
Спасибо.
PM MAIL   Вверх
KaraKum
Дата 22.12.2008, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



Вот в чём дело:
В числах со знаком (а это все числа, если специально не указать unsigned) самый старший бит отвечает за сам знак (либо плюс - либо минус), поэтому в char (которая величиной только 8 бит) остаётся только 7 бит на само число (таким образом char может представлять только числа от -127 до +128). Для преобразований меньших 128 - результат будет оставаться верным - дальше уже будет коверкаться, но не по обычной логике, потому что отрицательное число - это не само число с установленным самым старшим битом, а его дополнение (например, -1 - это не 10000001, а 11111111).
PM MAIL WWW   Вверх
AliensX
  Дата 22.12.2008, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 22.12.2008

Репутация: нет
Всего: нет



Цитата(KaraKum @ 22.12.2008,  13:06)
Вот в чём дело:
В числах со знаком (а это все числа, если специально не указать unsigned) самый старший бит отвечает за сам знак (либо плюс - либо минус), поэтому в char (которая величиной только 8 бит) остаётся только 7 бит на само число (таким образом char может представлять только числа от -127 до +128). Для преобразований меньших 128 - результат будет оставаться верным - дальше уже будет коверкаться, но не по обычной логике, потому что отрицательное число - это не само число с установленным самым старшим битом, а его дополнение (например, -1 - это не 10000001, а 11111111).

Премного благодарен за развернутый ответ!
Я в c++ новичок, раньше разрабатывал приложения только на PHP, где все преобразования за тебя делает язык.
На данный момент по стечению обстоятельств пришлось писать сетевую программу, которую на PHP разработать, конечно, можно, но, увы, там отсутствует многопоточность. Поэтому в спешке пришлось изучать c++. До сих пор некоторые вещи не ясны. А в сетевых программах часто приходится преобразовывать типы данных, там нужна большая точность, иначе, все полетит.
Очень прошу переделать код таким образом, чтобы можно было обратно получить заветный код символа.
Заранее спасибо!

-------------
Немного погодя...

Разобрался!smile
Стоило изменить операцию вот таким вот образом:

Код

unsigned char x = (unsigned char)i;


Как все стало работать так, как нужно! smile
Ещё раз спасибо за ответ! Сам бы догадался очень-очень не скоро.
Тему можно убивать smile

Это сообщение отредактировал(а) AliensX - 22.12.2008, 13:42
PM MAIL   Вверх
KaraKum
Дата 22.12.2008, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



Код

#include <stdio.h>
#include <iostream>

using namespace std;

int main() 
{
    int i = 33;
    unsigned char x = (unsigned char)i;

    cout << x << endl;
    printf("%c", x);
}


Программа будет печатать восклицательный знак в косноли в обоих функциях.
PM MAIL WWW   Вверх
UnrealMan
Дата 22.12.2008, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: нет
Всего: 32



Цитата(KaraKum @  22.12.2008,  13:06 Найти цитируемый пост)
В числах со знаком (а это все числа, если специально не указать unsigned) самый старший бит отвечает за сам знак (либо плюс - либо минус), поэтому в char (которая величиной только 8 бит) остаётся только 7 бит на само число (таким образом char может представлять только числа от -127 до +128). 

По правилам C++ char может быть и знаковым и беззнаковым. В VC++ есть опция, управляющая знаковостью char; насчёт MinGW не знаю.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | GNU toolchain | Следующая тема »


 




[ Время генерации скрипта: 0.0724 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.