Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSBasicCourse2ndedPodbelsky / CSBasicCourse2ndedPodbelsky.rtf
Скачиваний:
27
Добавлен:
22.03.2016
Размер:
11.9 Mб
Скачать

4.2. Особые ситуации в арифметических выражениях

Однако, и при допустимых преобразованиях существуют особые ситуации,

которые необходимо предусматривать. Например, если присваивать переменной

вещественного типа целое значение с очень большим количеством значащих цифр,

то младшие разряды числа могут быть потеряны.

Пример:

float x=12345678987654321L; // справа long

Переменная x получает значение 1.234568Е+16, - потеряны младшие

разряды.

При делении вещественных чисел существует опасность переполнения

"переполнение" , если порядок делимого отличается от порядка делителя на

слишком большую величину. В этом случае результат, независимо от конкретных

величин делимого и делителя, воспринимается исполняющей системой как

бесконечность (Infinity). Такое же значение получается при делении на нулевое

значение. Переполнение возможно и при других арифметических операциях.

Например, в результате выполнения следующего фрагмента программы:

float x=1E+24F;

Сonsole.Write("x="+(x*=x));

На консольный экран будет выведена строка:

х=бесконечность

Обратная переполнению ситуация – потеря значимости "потеря значимости"

возникает, когда получаемое значение слишком мало, и не может быть

представлено с помощью того количества разрядов (битов), которые выделяются

для значения соответствующего типа. В качестве примера рассмотрим следующий

фрагмент программы:

float x=1E-24F;

Сonsole.Write("x="+(x*=x));

Результат в этом случае нулевой:

х=0

В случае, когда и делитель, и делимое равны нулю, результат неопределённый,

и это фиксируется с помощью специального обозначения NaN (Not a Number - не

число). При выполнении следующих операторов:

float x=0.0f;

Сonsole.Write("0/0"+x/0);

Результат в консольном экране будет таким:

0/0= NaN

При решении вычислительных задач с помощью итерационных алгоритмов,

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

алгоритм приведён к виду

fi+1=fi+∆i; i=1,2,…

и ∆i по какому-либо закону убывает с ростом i, то предельная точность

достигается в том случае, когда ∆i становится пренебрежительно малой величиной

по сравнению с fi . В этом случае говорят, что достигнут машинный нуль

относительно величины fi.

Рассмотрим такую последовательность операторов:

double x=1000, y=1E-08;

Сonsole.Write("x+y="+(x+(y*=y)));

Сonsole.Write(" y="+y);

Результат выполнения:

x+y=1000 y=1E-16

В данном примере прибавление значения 1Е-16 к 1000 не изменило результата,

и 1Е-16 является машинным нулём "машинным нулём" относительно величины

1000. При необходимости можно ставить и решать задачу оценки максимального по

абсолютной величине значения машинного нуля относительно заданной величины ...

Если переменной типа decimal необходимо присвоить значение отличное от

целого, то его нужно представить в виде константы типа decimal. Целое значение

можно

присваивать

десятичной

переменной

"десятичной

переменной"

непосредственно. Следующий фрагмент программы (04_01.cs) иллюстрирует

некоторые особенности выражений с операндом типа decimal. (Напомним, что

десятичный литерал имеет суффикс m или M.)

static void Main()

{

decimal p = 193, d = 0.15431m, e = 1.231E-10M;

Console.WriteLine("p*d*e= " + (p * d * e));

float bp = 193F, bd = 0.15431F, be = 1.231E-10F;

Console.WriteLine("bp*bd*be= " + (bp * bd * be));

Console.WriteLine("1.0/3.0= " + (1.0/3.0));

Console.WriteLine("1.0m/3.0m= " + (1.0m / 3.0m));

}

Переменным p, d, e типа decimal и переменным bp, bd, bc типа float присвоены

одинаковые значения. Результаты одинаковых выражений с операндами разных

типов существенно различны по точности:

p*d*e= 0,000000003666143273

bp*bd*be= 3,666143E-09

1.0/3.0= 0,333333333333333

1.0m/3.0m= 0,3333333333333333333333333333

Соседние файлы в папке CSBasicCourse2ndedPodbelsky