Loading...

Във форума е въведено ограничение, което позволява на потребителите единствено да разглеждат публикуваните въпроси.

Hristo_Penchev avatar Hristo_Penchev 389 Точки

Ushort целочислено делене

Здравейте,

Работя над задача 10 от глава 3 "Въведение в програмирането със C#":

  1. Напишете програма, която приема за вход четирицифрено число във формат abcd (например числото 2011) и след това извършва следните действия върху него:

-     Пресмята сбора от цифрите на числото (за нашия пример 2+0+1+1 = 4).

-     Разпечатва на конзолата цифрите в обратен ред: dcba (за нашия пример резултатът е 1102).

-     Поставя последната цифра, на първо място: dabc (за нашия пример резултатът е 1201).

-     Разменя мястото на втората и третата цифра: acbd (за нашия пример резултатът е 2101).

Като цяло задачата ми е ясня. Започнах да я пиша със следния код:

 

 class FourDigitNumber
    {
        static void Main()
        {
            System.Console.WriteLine("Please, enter a four digit number: ");
            ushort number = ushort.Parse(System.Console.ReadLine());
            ushort ones = number%10;

        }
    }

 

Извежда ми следната грешка:

 Cannot implicitly convert type 'int' to 'ushort'. An explicit conversion exists (are you missing a cast?) 

 

Интересно защо се получава така. В случая не виждам никакво конвертиране. Извършвам целочислено деление на променлива от типа ushort. Като задам int навсякъде, всичко е ОК.

Благодаря предварително!

Тагове:
0
Programming Basics
HPetrov avatar HPetrov 822 Точки

Трябва да го кастнеш към (ushort) защото числата по начало се пазят като int и чак вече като се присвоят към въпросната променлива се "cast-ват" към типа на променливата. Така че трябва да ти е ushort ones = (ushort)number % 10;

Един съвет от мен. Не се занимавай с byte short ushort и т.н. Ползвай си int и нагоре ако се налага ;)

0
Hristo_Penchev avatar Hristo_Penchev 389 Точки

Добре, след като променливата number е декларирана като ushort един ред по-нагоре, защо компютърът продължава по подразбиране да я приема като int? Логиката нещо ми се губи.

И каква е идеята на по-малките променливи от int по принцип? Да се товари по-малко паметта?

0
Yulia avatar Yulia 1346 Точки

Прегледах няколко теми, предложени от гугъл по въпроса и реално никъде не се обяснява логиката - защо по подразбиране резултата е int. В MSDN се казва единствено: "The following assignment statement will produce a compilation error, because the arithmetic expression on the right side of the assignment operator evaluates to int by default." Приеми го като аксиома :}

А идеята на този тип променливи е именно такава - да. Заделят по-малко памет при деклариране. Но за домашните и този курс няма какво да се тревожиш за паметта.

Моето предположение е, че се използват главно за съхраняване на някакви данни, без необходимост от математически операции върху тях. Например, ID-та в някоя база - ако се пазят номерата на хиляди обекта, всеки от номер ще заема по 16 бита, а не по 32 (за ushort), за което вече се вижда разликата, а да не говорим за някои огромни проекти.

Сигурна съм, че можеш да си решиш задачата де, но ако ти е любопитно, можеш да погледнеш тук, за да видиш други решения с различен подход (това е шеста задача от домашното за оператори)

0
Samuil.Petrow avatar Samuil.Petrow 1550 Точки

Според мен повечето оператори просто не са дефинирани за използване в/у типове по-малки от int и затова се превръщат към него, защото е първото "удобно", което би им свършило работа.

п.п: Пробвах в/у long и не е необходим каст, така че предполагам се подплатява твърдението до известна степен.

п.п2: То пък не е много сигурна проверка, защото най-вероятно не трябва каст, тъй като може да си запълни инта в лонг, така че дето вика Юлия, приеми го за вярно и не се занимавай повече ;д

0
BoYaN avatar BoYaN 336 Точки

Здравей,

въпросът ти е интересен и намерих нещо, което може би обяснява защо ushort променливите ги приема като int.

В MSDN / Language Independence and Language-Independent Components , пише че в .NET всеки език си е независим, но има тъй наречените CLS-compliant types, които са общите типове данни във всеки език.

Останалите, към които спада и ushort (UInt16), се водят Non-compliant type и имат "алтернативи"(CLS-compliant alternative) от CLS-compliant types и вероятно затова ти ги приема, като int32.

Не знам дали това е наистина причината, но звучи логично и обяснява "симптома", който се получва.

Поздрави

0
Hristo_Penchev avatar Hristo_Penchev 389 Точки

Благодаря ви за отговорите. Бояне, нещо не мога да разбера. Ако CLS не разбира ushort, не би трябвало да го ползваме изобщо?

На мен ми хрумна друго логично обяснение. Представете си, че вместо " ushort ones = number%10 " бях задал:

ushort ones = number*1000. Тогава ushort щеше да прелее. Явно заради това когато вкарваме математически изрази, атоматично се презастрахова, конвертирайки резултата към int, освен ако изрично не зададем по-малък тип, като по този начин си поемем "отговорността" за евентуални бъгове.

Юлия, благодаря за решението. И аз използвах същия подход при решаване на задачата. Чудя се дали не можем някак да го направим и със стрингове. Вкарваме стринг от клавиатурата, присвояваме четирите символа от стринга на char променливи и ги местим. А за сбора, обръщаме някак си char в int. Но май ще стане доста сложно. Трябва да се помисли.

 

 

0
BoYaN avatar BoYaN 336 Точки

CLR (Common Language Runtime)-a си го разбира, но представянето на unsigned типовете е различно от signed, заради стандартизацията (Common Language Specification).

Възможните им стойности са по-големи от тези на signed. При signed първия бит, отляво надясно, държи стойността на знака( + - ), докато при unsigned този бит определя стойността.

short signed 16-bit (65,536 possible values, from -32,768 to 32,767) ushort unsigned 16-bit (65,536 possible values, from 0 to 65,535)

Така стойност по-голяма от 32767 при unsigned 16bit не може да се конвертира до същия тип signed 16bit  и затова се представя като по-голям тип 32bit, за да може да се вмести без загуба.

Както и обратното от signed не може да конвертираш директно до unsigned, защото няма как да се представи в случай, че е отрицателно.

Unsigned типовете са, така да кажем, изкуствено пресъздадени в C# и VB. Например в Java няма unsigned типове.

Не мога много добре да обяснявам, но се надявам да си схванал какво имам предвид.

0
Yulia avatar Yulia 1346 Точки

Hristo_Penchev, сега виждам, че е станала някаква грешка в линка, който дадох по-горе. Редактирах го, но ще пусна линковете пак: Това е официалната тема за домашното: https://softuni.bg/forum/questions/details/228 

А тук има повече решения: https://softuni.bg/forum/questions/details/181/  Има я решена и със стрингове - аз поне така я писах :}

0
dsmilyanov avatar dsmilyanov 237 Точки

Харесва ми каква дискусия се получи за един дребен ushort. :D

Колега, нямаш проблеми в променливата number. Като си я създал като ushort, тя си е ushort. Проблема ти идва на следващия ред като ползваш "number % 10". Десятката така написана се взима за int. Трябва просто да каст-неш десятката към ushort и трябва да работи.

Т.е. в един момент искаш да вземеш резултата от делението на ushort със int (съответно number и 10), което няма как да стане. Иначе съм съгласен, както са написали колегите по-горе - ползвай за домашните int, ако мислиш, че int-a ще прехвърли ползвай long или BigInteger. 

1
aslv1 avatar aslv1 304 Точки

Отговорът е толкова прост smile :

Не може да се кастне неявно от int към ushort, защото в int може да има отрицателни числа, а в ushort - не може!

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.