Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
1 / 1 / 0
Регистрация: 09.06.2012
Сообщений: 105

Изменение значения при приведении типов

17.12.2013, 22:19. Показов 2457. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет форумчане! Вот часть программы:
C#
1
2
3
u = 64000;
s = (short) u;
console.Writeline("s после присвоения 64000: " + u + "-- с потерей данных.");
Результат выполнения этого кода следующий:
s после присваивания 64000: -1536 -- с потерей данных.

Вопрос: откуда 1536? Это ведь не рандомно определяется, было бы глупо). Спасибо заранее)
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.12.2013, 22:19
Ответы с готовыми решениями:

FormatException не обработано при приведении типов
Надоело, просто жесть как надоело: err = Convert.ToInt32(hgg); ferrors = err; Ну что здесь не правильно? Студия...

Как вызвать метод дочернего класса при приведении типов?
Привет у меня есть класс (Батя) и парочка дочерних классов в классе Батя есть метод void Verefication, который унаследовали все его...

Почему при восходящем приведении типов вызывается метод класса потомка?
class T1 { public virtual void P() { Console.WriteLine(1); } } class T2 : T1 {

17
Администратор
Эксперт .NET
 Аватар для tezaurismosis
9674 / 4826 / 763
Регистрация: 17.04.2012
Сообщений: 9,664
Записей в блоге: 14
17.12.2013, 22:28
C#
1
2
3
4
5
int u = 32767;
short s = (short) u; // 32767
// ...
int u = 32768;
short s = (short) u; // -32768 - переполнение, переходим к нижней границе
64000 - 32768 = 31232; 31232 - 32768 = -1536.
0
1 / 1 / 0
Регистрация: 09.06.2012
Сообщений: 105
17.12.2013, 22:45  [ТС]
Цитата Сообщение от tezaurismosis Посмотреть сообщение
int u = 32768;
Если речь идет о нижней границе, то здесь не нужен минус?
Цитата Сообщение от tezaurismosis Посмотреть сообщение
64000 - 32768 = 31232; 31232 - 32768 = -1536.
А почему Вы два раза вычитаете нижнюю границу из присваемого значения?
0
Администратор
Эксперт .NET
 Аватар для tezaurismosis
9674 / 4826 / 763
Регистрация: 17.04.2012
Сообщений: 9,664
Записей в блоге: 14
17.12.2013, 22:55
У типа short верхняя граница: 32767, как только мы её переходим при приведении типов short принимает наименьшее возможное значение, т.е. -32768. По мере увеличения значения в int значение short тоже увеличивается
C#
1
2
3
4
5
6
7
8
int u = 32768;
short s = (short) u; // -32768
 
int u = 32769;
short s = (short) u; // -32767
 
int u = 32778;
short s = (short) u; // -32758
Цитата Сообщение от jammad621 Посмотреть сообщение
А почему Вы два раза вычитаете нижнюю границу из присваемого значения?
64000 - 32768 = 31232 : настолько мы переполнили short
31232 - 32768 = -1536, понятнее будет -32768 + 31232 = -1536 : после переполнения начинаем отсчёт с (-32768)
1
1 / 1 / 0
Регистрация: 09.06.2012
Сообщений: 105
17.12.2013, 23:42  [ТС]
tezaurismosis, Ок, не понял только, почему при подсчитывания величины, на которую мы переполнили short, мы вычитаем из присваемого значения именно нижнюю границу(32768), а не верхнюю(32767), что логичней вроде(сори если туплю)
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
17.12.2013, 23:52
Цитата Сообщение от jammad621 Посмотреть сообщение
почему при подсчитывания величины, на которую мы переполнили short, мы вычитаем из присваемого значения именно нижнюю границу(32768), а не верхнюю(32767), что логичней вроде(сори если туплю)
-->
По мере увеличения значения в int значение short тоже увеличивается
Мы не вычитаем нижнюю границу, мы к нижней границе(которая отрицательна) добавляем величину, на которую произошло переполнение.
1
1 / 1 / 0
Регистрация: 09.06.2012
Сообщений: 105
18.12.2013, 00:21  [ТС]
Так , то есть:
1) т.к. 64000>верхней границы(32767) переменной s присваивается значение нижней границы(-32768);
2) далее это значение увеличивается на 64000 >= s становится равным 31232;
Так? Тогда зачем еще что-то делать???
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
18.12.2013, 00:31
jammad621, помедитируйте на этот метод:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
        static void Main(string[] args)
        {
            short s = short.MaxValue - 5;
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(s);
                unchecked
                {
                    s++;
                }
            }
            Console.ReadKey();
        }
(офк запустите и посмотрите вывод программы).
1
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
18.12.2013, 14:28
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от jammad621 Посмотреть сообщение
откуда 1536?
int представлен в памяти четырьмя байтами, а short — двумя.
Когда вы преобразовываете int в short, то все лишние старшие байты просто отбрасываются и результирующее значение будет образовано оставшимися младшими байтами.
В случае преобразования int (4 байта) в short (2 байта), будут отброшены старшие два байта.

Итак, число 64000 в формате int в двоичном виде имеет такой вид:
0000 0000 0000 0000 1111 1010 0000 0000

При преобразовании в short, размер которого равен двум байтам, старшие байты отбрасываются и используются только младшие два, так что значение приобретает такой вид:
1111 1010 0000 0000

Тип short является знаковым, значит он представлен в памяти дополнительным кодом, где самый старший бит указывает на знак числа (1 — отрицательное, 0 — положительное), а все последующие определяют собственно значение.

В получившемся представлении видно, что старший бит имеет значение 1, а значит число будет отрицательным.
В случае отрицательного числа значение высчитывается таким образом: из числа, полученного установкой максимального бита в единицу (как если бы оно было беззнаковое) вычитается число, образованное всеми оставшимися битами, и ставится знак минус.
На примере выше, из первого вычитается второе:
1000 0000 0000 0000 (32768)
0111 1010 0000 0000 (31232)
0000 0110 0000 0000 (1536)

Результат: 1536 со знаком минус или –1536.

Ну и для полноты картины: значение это инвертируется и к нему добавляется единица, получается вышеприведенная запись двоичного числа:
~0000 0110 0000 0000 + 1 = 1111 1001 1111 1111 + 1 = 1111 1010 0000 0000

Можно объяснить еще проще.
Беззнаковое число из двоичной системы переводится в десятичную по такой формуле:
https://www.cyberforum.ru/cgi-bin/latex.cgi?\sum_{i=0}^{n-1}({x}_{i}\times {2}^{i})
Где n — количество разрядов, i — текущий разряд, а x — значение текущего разряда.

На примере со значением 64000:
1111 1010 0000 0000 =

https://www.cyberforum.ru/cgi-bin/latex.cgi?1\times {2}^{15}+1\times {2}^{14}+1\times {2}^{13}+1\times {2}^{12}+1\times {2}^{11}+0\times {2}^{10}+1\times {2}^{9}+0\times {2}^{8}+0\times {2}^{7}+0\times {2}^{6}+0\times {2}^{5}+0\times {2}^{4}+0\times {2}^{3}+0\times {2}^{2}+0\times {2}^{1}+0\times {2}^{0}=

https://www.cyberforum.ru/cgi-bin/latex.cgi?32768 + 16384 + 8192 + 4096 + 2048 + 512 = 64000

Знаковое же число, представленное дополнительным кодом, переводится в десятичную систему счисления по такой формуле:

https://www.cyberforum.ru/cgi-bin/latex.cgi?-{x}_{n-1}\times {2}^{n-1}+\sum_{i=0}^{n-2}({x}_{i}\times {2}^{i})

Всё то же, но значению из старшего разряда присваивается знак минус.
Получаем:

https://www.cyberforum.ru/cgi-bin/latex.cgi?-1\times {2}^{15}+1\times {2}^{14}+1\times {2}^{13}+1\times {2}^{12}+1\times {2}^{11}+0\times {2}^{10}+1\times {2}^{9}+0\times {2}^{8}+0\times {2}^{7}+0\times {2}^{6}+0\times {2}^{5}+0\times {2}^{4}+0\times {2}^{3}+0\times {2}^{2}+0\times {2}^{1}+0\times {2}^{0}=

https://www.cyberforum.ru/cgi-bin/latex.cgi?-32768 + 16384 + 8192 + 4096 + 2048 + 512 = -1536
4
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
18.12.2013, 16:22

Не по теме:

kolorotur, насчет еще проще - это вряд ли. Вот то что доп.код - это инвертированный прямой код плюс единица намного проще для понимания...



Добавлено через 2 минуты
На вики по-моему кстати неправильно написано. У них ноль знаковый, тогда как ноль знаковый только для действительных чисел, а для целых - он один. Поэтому прямой код единицы - 1, а дополнительный - 1111 1111.
Проверка -1 + 1 = 0,
0000 0001 + 1111 1111 = 1| 0000 0000 = 0
0
18.12.2013, 16:26

Не по теме:

Цитата Сообщение от Psilon Посмотреть сообщение
Вот то что доп.код - это инвертированный прямой код плюс единица намного проще для понимания...
Как по мне, так наоборот.
Единственная разница между знаковым и беззнаковым типом: отрицательное значение старшего разряда при конвертировании в десятичную СС.
Ну, на то там и два объяснения, да еще и ссылка на вики — чтобы всем понятно было :)

0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
18.12.2013, 16:30
kolorotur, так я и говорю - на вики ошибка. Хотя их там много на всевозможные темы, но давать для объяснения ссылку с ошибкой плохо. Там написано, например, что доп. код для 1 это 1, и обратный код для 1 это тоже 1, что полный бред.

Добавлено через 1 минуту
kolorotur, число может совпадать со своим дополнительным кодом (например, int.MinValue), но вот с обратным - никогда.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
18.12.2013, 16:31
Цитата Сообщение от Psilon Посмотреть сообщение
на вики ошибка.
Не, там все правильно.
Единица как в обратном представлении, так и в прямом, будет выглядеть как единица.
"Обратное представление" — не значит отрицательное значение. Это значит представление числа в памяти в виде twos-complement.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
18.12.2013, 16:32
kolorotur, я понял, что они имели ввиду. Но это бред по-моему. Тогда можно говорить, что компьютер использует только числа в доп.коде, т.к. по их представлениям множество положительных прямых, обратных и доп. кодов совпадают.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
18.12.2013, 16:35
Ну зачем сразу бред?
Положительные коды — да совпадают, и это хорошо.
Всякие обратные, прямые да дополнительные коды придумывают для представления именно отрицательных значений.
Потому пусть положительные совпадают, бог с ними.

Опять же, "обратный" — не значит инвертированный. Это значит "инвертированный, когда значение отрицательное, а когда положительное — нормальный"
0
1 / 1 / 0
Регистрация: 09.06.2012
Сообщений: 105
18.12.2013, 19:27  [ТС]
Всем спасибо за ответы, но никто не ответил на вопрос: если верхняя граница short равна 32767, а присваиваем мы число 64000, то переполняется переменная ведь на 64000-32767=31233, так?и следовательно после прибавления к нижней границе получается -32678+31233=-1535, а не 1536. Что я упускаю(сори за тупые, наверное, вопросы)?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
18.12.2013, 20:37
jammad621, минимальное значение -32768, максимальное: 32767
0
1 / 1 / 0
Регистрация: 09.06.2012
Сообщений: 105
19.12.2013, 00:25  [ТС]
Psilon, насчет минимального опечатался, максимальное написал правильно. Так почему?

Добавлено через 3 часа 46 минут
Аааа, понял внезапно , нам ведь нужно прибавить сначала единицу , чтобы перейти к нижней границе, и следственно к нижней границе мы прибавляем не 31233, а 31232. Всем спасибо, сори за мои нубские вопросы, только учусь пока что) Всем плюсики) Можно закрывать.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.12.2013, 00:25
Помогаю со студенческими работами здесь

Необработанное исключение типа "System.FormatException" при приведении типов
Не работает с double double prais; private void F() { switch(cBox.SelectedIndex) { ...

О приведении типов и классов
Читая про приведение типов из msdn наткнулся на фразу Этого я, признаюсь, не понял. Производные классы имеют все те же поля и методы,...

Нахождение ошибки в наследовании и приведении типов
имеется рабочий код на с++, пыталась переделать его в С#, возникают ошибки,которые я не в состоянии сама исправить. Буду безумно...

Куда деваются байты при приведении типов?
Всем доброго времени суток... Т.к. основной проект на c++, то пишу сюда... Непонятки с приведением типов, объясните пожалуйста... ...

Изменение значения указателя при преобразовании типов
Есть класс Child, унаследованный от класса Parent. Наследование обычное, а не множественное. И Parent, и Child имеют виртуальные функции....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru