1629295403-b876e2087bddebea4bc9666fb2377a02 (846199), страница 11
Текст из файла (страница 11)
Объявление переменных-значений61Обратите внимание на сказанное о том, что действительное число можетиметь ненулевую дробную часть — т.е. число 1.5 является действительным также, как и число 1.0. Например, 1.0 + 0.1 = 1.1. Просто при чтении оставшейсячасти этой главы все время не забывайте о наличии точки.К счастью, С# прекрасно понимает, что такое действительные числа. Они могут бытьс плавающей точкой и с так называемым десятичным представлением. Гораздо болеераспространена плавающая точка.Объявление переменной с плавающей точкойПеременная с плавающей точкой может быть объявлена так, как показано в следующем примере:floatf=1.0;После того как вы объявите переменную как f l o a t , она остается таковой при всехестественных для нее операциях.В табл.
3.2 рассматриваются использующиеся в С# типы с плавающей точкой. Всепеременные этих типов — знаковые (т.е. не существует такой вещи, как переменнаяс плавающей точкой, не способная представлять отрицательные значения).Вы можете решить, что тип f l o a t — это тип по умолчанию для переменных с {плавающей точкой, но на самом деле типом по умолчанию является d o u b l e .Если вы не определите явно тип для, скажем, 12.3, С# сделает его d o u b l e .Столбец точности в табл. 3.2 указывает количество значащих цифр, которые можетпредставлять такая переменная. Например, 5/9 на самом деле равно 0.555...
с бесконечной последовательностью пятерок. Однако переменная типа f l o a t имеет точность неболее 6 цифр, что означает, что все цифры после шестой могут быть проигнорированы. IТаким образом, 5/9 , будучи выражено в виде f l o a t , может выглядеть как0 . 5555551457382Не забывайте, что все цифры после шестой пятерки ненадежны.На самом деле тип f l o a t имеет 6.5 значащих цифр. Дополнительные полцифры получаются из-за того, что точность представления чисел с плавающей точ82кой связана с такой функцией, как 10'°. Впрочем, вряд ли это должно сильновас интересовать.То же число 5/9 может выглядеть при использовании типа d o u b l e следующим образом:0.55555555555555557823Тип d o u b l e имеет 15-16 значащих цифр.62Часть II.
Основы программирования в С#Числа с плавающей точкой в С# по умолчанию имеют точность d o u b l e , такчто применяйте везде тип d o u b l e , если только у вас нет веских причин поступить иначе. Однако используете ли вы d o u b l e или f l o a t — все равноваша программа будет считаться программой, работающей с числами с плавающей точкой.Более точное п р е о б р а з о в а н и е т е м п е р а т у рВот как выглядит формула преобразования температур в градусах Фаренгейта в градусы Цельсия при использовании переменных с плавающей точкой:dCelsius =(dFahr - 3 2 . 0 )*(5.0 / 9 .
0 ) ;На прилагаемом к книге компакт-диске имеется d o u b l e - в е р с и я программыпреобразования температур C o n v e r t T e m p e r a t u r e W i t h F l o a t .Приведенный далее пример показывает результат работы программы ConvertTemperatureWithFloat:Введите т е м п е р а т у р у в г р а д у с а х Ф а р е н г е й т а : 1 0 0Температура в г р а д у с а х Ц е л ь с и я р а в н а : 3 7 . 7 7 7 7 7 7 7 7 7 7 7 7 8Press Enter to t e r m i n a t e . . .Ограничения п е р е м е н н ы х с п л а в а ю щ е й т о ч к о йВы можете захотеть использовать переменные с плавающей точкой везде и всегда,раз уж они так хорошо решают проблему усечения.
Да, конечно, они используют немного больше памяти, но ведь сегодня это не проблема? Но дело в том, что у чисел с плавающей точкой имеется ряд ограничений.ПеречислениеНельзя использовать числа с плавающей точкой для перечисления. Некоторые структуры С# должны быть подсчитаны (1, 2, 3 и т.д.). И всем известно, что числа 1.0, 2.0, 3.0можно применять для подсчета количества точно так же, как и 1, 2, 3, но С# ведь этогоне знает.
Например, при указанной выше точности чисел с плавающей точкой откуда С#знать, что вы не сказали в действительности 1.000001?Находите ли вы эту аргументацию убедительной или нет — но вы не можете использовать числа с плавающей точкой для подсчета количества.Сравнение чиселВы должны быть очень осторожны при сравнении чисел с плавающей точкой. Например, 12.5 может быть представлено как 12.500001.
Большинство людей не волнуюттакие мелкие добавки в конце числа, но компьютер понимает их буквально, и для С#12.500000 и 12.500001 — это разные числа.Так, если вы сложите 1.1 и 1.1, вы можете получить в качестве результата 2.2 или2.200001. И если вы спросите: "Равно ли значение dDouv l e v a r i a b l e . 2.2?", то можетеполучить совсем не тот ответ, который ожидаете. Такие вопросы вы должны переформулировать, например, так: "Отличается ли абсолютное значение разности d D o u v l e V a r i able и 2.2 менее чем на 0.000001?", другими словами, равны ли два значения с некоторой допустимой ошибкой.Глава 3. Объявление переменных-значений63Процессоры Pentium используют небольшой трюк, который несколько снижает ушзанную неприятность,— при работе они применяют специальный формаав котором для числа с плавающей точкой выделяется 80 бит.
При округлении тако|го числа к 64-битовому почти всегда получается результат, который вы ожидаете.Скорость вычисленийПроцессоры х86, использующиеся на старых компьютерах под управление]!Windows, выполняли действия над целыми числами существенно быстрее, чем над чис|лами с плавающей точкой. В настоящее время эта проблема так остро не стоит.Отношение скоростей работы процессора Pentium III при простом (пожалуй, слиш]ком простом) тесте, состоящем в 300000000 сложений и вычитаний целых чисел и чисемс плавающей точкой, оказалось равным примерно 3 к 1. То есть вместо одного сложешяd o u b l e можно сделать три сложения i n t .
(Вычисления с применением умноженияи делений могут привести к другим результатам.)Ограниченность диапазонаВ прошлом переменные с плавающей точкой могли представлять значительно больший диапазон чисел, чем целые. Сейчас диапазон представления целых чисел существвенно вырос — стоит вспомнить о типе l o n g .Даже простой тип f l o a t способен хранить очень большие числа, но числазначащих цифр у него ограничено примерно шестью. Например, 1 2 3 4 5 6 7 8 9Fозначает то же, что и 1 2 3 4 5 6 0 0 0 F . (О том, что такое F в приведенных загансях, вы узнаете немного позже.)Как уже объяснялось в предыдущих разделах, и целые, и десятичные числа имеютсвои недостатки.
Переменным с плавающей точкой присущи проблемы, связанные с вопросами округления из-за недостаточной точности представления, целые переменные немогут представлять числа с дробной частью. Бывают ситуации, когда совершенно необходимо иметь возможность получить лучшее из обоих миров, а именно числа, которые:•S подобно числам с плавающей точкой, способны иметь дробную часть;Sподобно целым числам, должны представлять точные результаты вычислений —т.е. 12.5 должно быть равно 12.5, и ни в коем случае не 12.500001.К счастью, в С# есть такой тип чисел, называющийся d e c i m a l . Переменная типа2828d e c i m a l в состоянии представлять числа от 10" до 10 — вполне достаточный диапазон значений! И все это делается без проблем, связанных с округлением.О б ъ я в л е н и е п е р е м е н н ы х т и п а decimalПеременные типа d e c i m a l объявляются и используются так же, как и переменныедругих типов:64Часть II. Основы программирования в С#decimal m l ;decimal m2 = 1 0 0 ;decimal m3 = 100M;//////ХорошоЛучшеИдеальноОбъявление ml выделяет память для переменной ml без ее инициализации.
Пока выне присвоите значение этой переменной, оно будет неопределенным. В этом нет особойпроблемы, так как С# не позволит вам использовать переменную без начального присвоения ей какого-либо значения.Второе объявление создает переменную т2 и инициализирует ее значением 100. В этойситуации неприятным моментом оказывается то, что 100 имеет тип i n t . Поэтому С# вынужден конвертировать i n t в d e c i m a l перед инициализацией. К счастью, С# понимает,чего именно вы добиваетесь, и выполняет эту инициализацию для вас.Лучше всего использовать такое объявление, как объявление переменной тЗ с константой 10ОМ типа d e c i m a l . Буква М в конце числа указывает, что данная константаимеет тип d e c i m a l , так что никакого преобразования не требуется.Сравнение д е с я т и ч н ы х , ц е л ы х ч и с е ли чисел с п л а в а ю щ е й т о ч к о йСоздается впечатление, что числа типа d e c i m a l имеют лишь одни достоинства и лишены недостатков, присущих типам i n t и d o u b l e .
Переменные этого типа обладаютшироким диапазоном представления и не имеют проблем округления.Однако у чисел d e c i m a l есть свои неприятности. Во-первых, поскольку они имеютдробную часть, они не могут использоваться в качестве счетчиков, например, в циклах, о которых пойдет речь в главе 5, "Управление потоком выполнения".Вторая проблема не менее серьезна, и заключается в том, что вычисления с этим типом чисел гораздо медленнее, чем с простыми целыми числами или даже с числамис плавающей точкой. В уже упоминавшемся тесте с 300000000 сложений и вычитанийработа с числами d e c i m a l примерно в 50 раз медленнее работы с числами i n t .
Это отношение становится еще хуже для более сложных операций. Кроме того, большинствоматематических функций, таких как синус или возведение в степень, не имеют версийдля работы с числами d e c i m a l .Понятно, что числа типа d e c i m a l наиболее подходят для финансовых приложений, гдеисключительно важна точность, но само количество вычислений относительно невелико.Логичен ли логический tnun?И наконец, о переменных логического типа. Тип b o o l имеет только два значения —true и f a l s e . Это не ш у т к а — целый тип переменных придуман для работы толькос двумя значениями.Ранее программисты на С и С++ использовали нулевое значение переменнойтипа i n t для обозначения f a l s e и ненулевое — для обозначения t r u e .