Числа с плавающей точкой в качестве индексов

Предположим, что матрица А имеет размер 2 х 2, Для того чтобы обратиться к элементам матрицы, могут применяться как жестко заданные в тексте програм­мы индексы, так и значения, вычисляемые динамически в ходе ее выполнения, в том числе нецелые, как показано ниже:

-->А =  testmatrix("hilb", 2)

А =

4.     - 6.

6.        12.

-->А( 2,   [1.0  1.1  1.5  1.9] )

ans =

6.     -  6.     -  6.     - 6.

Этот пример демонстрирует, что все значения 1.0, 1.1, 1.5 и 1.9 округляются до 1, как при использовании функции int, округляющей дробные значения в сторону 0. Например, результатом каждого следущего вызова: int (1.0),int (1.1), int (1.5) и int (1.9) - будет значение 1, а выражения int (-1.0), int (-1.1), int (-1.5) и int (-1.9) возвращают число -l.

Заметим, что округление происходит в соответствии с особенностями рабо­ты функции int, а не floor, которая в отличие от int отрицательные значения округляет в меньшую сторону. В самом деле, предположим, что А представляет матрицу 4х4, например, созданную в результате вызова А = testmatrix ("hilb”, 4). Функция triu (А,к) возвращает верхнюю треугольную часть переданной ей матрицы А, лежащую выше k-ой диагонали. Команды triu(A, -1), triu(A, int (-1.5)) и trioi(А,-1.5) возвращают один и тот же результат, в то время как инструк­ция triu(A,f loor (-1.5)) эквивалентна triu(A, -2).

Такое поведение может показаться странным, но способствует единообразию языка Scilab. Действительно, при обращении к элементам матрицы с исполь­зованием переменных в качестве индексов, чаще всего типом переменной будет являться число с плавающей точкой. В этом случае конверсия происходит по­средством функции int. Следующий фрагмент иллюстрирует сказанное:

-->i = 2

 i =

2.

— >j  = 1

 j =

1.

—>A(i, j)

ans =

- 6.

Обратите внимание, что в этот примере переменные i и j имеют тип с плава­ющей точкой.

Иногда использование чисел с плавающей точкой в качестве индексов может приводить в неожиданным результатам, например:

-->ones(1,1) ans =

1.

-->ones(l,   (1   -  0.9)   * 10) ans = []

При отсутствии ошибок округления, обусловленных конечной разрядностью представления чисел в памяти компьютера, значение выражения (1 — 0.9) * 10 равнялось бы 1, и в приведенном примере мы получили бы матрицу 1 х 1. Однако в действительности команда ones (1, (1-0 .9) *10) возвращает пустую матрицу, так как в результате округления числа (1 — 0.9) * 10 с использованием функции int получаем 0:

-->int((l  - 0.9)   * 10) ans = 0.

Как уже было сказано, причиной тому являются ошибки двоичного представления дробных чисел в результате двоичное представление числа 1-0.9 несколько меньше 0.1, а будучи умноженным на 10, несколько меньше 1, вчём позволяет убедиться следующий пример:

-->format(25)

 -->1  - 0.9

ans =

0.0999999999999999777955

 -->(1 -  0.9)   * 10

ans =

0.9999999999999997779554

На практике, при вычислении индексов, не следует применять числа, ко­торые не имеют точного представления в форме с плавающей точкой. В част­ности, точные результаты дают обычные арифметические операции с целыми числами в пределах интервала [—252, 252].

© vse-o-scilab

Сделать бесплатный сайт с uCoz