Точность чисел в Матлабе

stm2383383

В последнее время стал доставать "глюк" матлаба следующего характера. Почему-то у некоторых чисел иногда появляются крошечные довесочки в виде дальнего (10-20) знака после запятой. Это очень мешает нормально работать в матлабе.
Объясню на примере:
X = 2014.4; % координата искомой точки в матрице
X_start = 2010;% координата первой точки в матрице
dn = 0.1; % величина шага между точками матрицы
nX = (X - X_start)/dn+1; % номер точки в матрице с заданной координатой
A = A(:,:,nX);

Пример ищет число в матрице по заданной координате. Здесь X задается непостредственно в пограмме, X_start и dn считываются из текстового файла, где они записаны в виде "2010" и "0.1"
То есть все числа заданы явно, без всяких долгих вычислений, и всегда округлены до десятых. Тем не менее, почему-то nX не всегда выдает целое число. Ну, то есть, при некоторых X все нормально, а при некоторых отказывается работать. Причем, если я посчитаю вручную, каким должно быть nX и вычту из полученного результата nX, который выдал матлаб, то получается очень маленькая разница, порядка -10...-20 степени.
Если выполнить round(nX то все работает как надо.
Самое неприятное, что такая ситуация возникает уже не в первый раз. И это очень раздражает.
Вопрос: это у меня матлаб так криво настроен, или есть еще какие-то тонкости, о которых я не знаю?
P.S. Вариант вводить переменные заданного вида (типа int) не хотелось бы. Так как основной "фишкой" матлаба считаю его незамороченность по мелким вещам, позволяющим получить результат.

Vlad128

dn = 0.1; % величина шага между точками матрицы
число 0.1 не представимо точно в виде конечной дроби в двоичной СС. В двоичной системе это периодическая дробь 0.0(0011). Вроде бы факт известный. Так что "до десятых" еще ничего не значит. Можешь проверить, 0.3 + 0.3 + 0.3 == 0.9 и удивиться. Это тоже следствие этих эффектов. Вообще, пользование числами с плавающей точкой — это отдельный скилл, которому в двух словах не научишь :(
Есть фундаментальный документ разряда «без бутылки не разберешься, а с бутылкой тем более»: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.ht...
Есть и более популярное изложение, но тут чуть меньше инфы (не обсуждются подлости оптимизатора):
http://randomascii.wordpress.com/2013/02/07/float-precision-...
Тут надо читать не саму статью по ссылке, а идти с начала по оглавлению.

stm2383383

Можешь проверить, 0.3 + 0.3 + 0.3 == 0.9 и удивиться.
Ах, вот оно что!
Сейчас начинаю припоминать, что все "глюки" были связаны с десятой долей числа.
Спасибо. Значит буду округлять принудительно.

kapello07

А round не помогает?

stm2383383

А round не помогает?
Если выполнить round(nX то все работает как надо.

kapello07

Если используешь число, получаемое из нецелочисленных вычислений для индексации массива, всегда используй round дополнительно. Это матлаб просто развращающая программа, которая отучает от контроля за типом переменных. В обычных языках у тебя или тип integer, который не позволит тебе делать дробные действия или double, real, extended и т.д. которые не позволят сделать индексацию даже если в них будет число целее целого.

stm2383383

Ну, скажем, не всегда проблема с индексацией массива. Иногда подобная ошибка возникала при поиске числа в массиве. Проблема-то понятна. Теперь просто буду изначально составлять код с учетом этого.
А вот на счет высказывания:
Это матлаб просто развращающая программа, которая отучает от контроля за типом переменных.
я возражу. Матлаб, в отличие от C, Java и прочих языков, направленных на создание конечных программ, с которыми работают другие люди, создан для научных вычислений. БОльшинство программ, которые я прогаю в матлабе, одноразовые. Надо мне какую-то фишку с массивом данных сделать, быстренько запрогал, получил результат, и забыл.
Фишки типа оптимизации кода, повышения производительности, контроль за памятью и т.п. отодвигаются на второй план. Так как в большинстве случаев нормального компа за глаза хватит для выполнения поставленных задач даже в самом неоптимальном виде. Поэтому я не вижу веских причин заморачиваться с типом числа в подобных ситуациях.
P.S. я не хочу принизить возможности матлаба в создании серьезных приложений. Для этого есть куча возможностей. В том числе и изменение типа числа. Но мне они не особо нужны.

seregaohota

бери шаг 1/8 или любую конечную дробь в 2чной системе. Или бери Maple вместо Матлаба, он считает в дробях если надо или в числах с любым заданным числом знаков после десятичной точки

stm2383383

Или бери Maple вместо Матлаба
Проще round добавлять, чем новую систему учить :)

stm7543347

C, Java и прочих языков, направленных на создание конечных программ, с которыми работают другие люди
:hah: :lam: :mog:

stm7543347

Это, а Матлаб ведь должен уметь в рациональные числа, ня?

stm2383383

Это, а Матлаб ведь должен уметь в рациональные числа, ня?
Вроде умеет, но мне нафиг не нужно, поэтому даже не пробовал ни разу.
Оставить комментарий
Имя или ник:
Комментарий: