Автор Тема: MMANA-GAL basic, версия 3.5.3  (Прочитано 58970 раз)

Оффлайн DL2KQ

  • Администратор
  • *****
  • Сообщений: 2493
  • Репутация: +257/-3
    • Просмотр профиля
Re: MMANA-GAL basic, версия 3.5.3
« Ответ #120 : 09 Декабря 2024, 11:19:58 »
Проблема локализована. В аттаче однопроводный файл bug_taper.maa, иллюстрирующий этот баг.

   Беда математическая.
   При делении таперированного (с отрицательным радиусом) провода на части в соотвтествии с таблицей Taper wire set есть предельно малый шанс (если две разные величины совпадут до 14 знака после запятой), что под знаком логарифма окажется 0.
   Поэтому разлетается разбиение провода на части и сегменты. См. в аттаченном файле bug_taper.maa: несмотря на установку источника w1c на View источник отображается со значительным смещением от центра. Это последствия неправильного деления таперированного провода.

  Исправлять этот баг сейчас мы не будем (может быть потом и только в PRO версии), потому что это довольно сложно (много связей и в нескольких местах).
  Вероятность пользователя влететь в этот баг ~10-14 (должны совпасть до 14 знака два разных числа). А если вдруг так "повезет", то чтобы выйти из этого бага  достаточно добавить очень маленькую величину (вроде 0,000001) в проблемной длине в таблице Taper wire set. Пример показан в аттаченном файле bug_taper_1.maa - это тот же самый файл, на котором был баг, но к длине 1,53 м добавлена одна миллионная метра. Всё работает корректно.
 

Оффлайн US6ISV

  • **
  • Сообщений: 4
  • Репутация: +0/-0
    • Просмотр профиля
Re: MMANA-GAL basic, версия 3.5.3
« Ответ #121 : 10 Декабря 2024, 11:32:38 »
Доброго времени.
Получается, что это наглядное подтверждение того, что шанс есть всегда :).
Позвольте только добавить, для тех кому еще так "повезет" ;) , при расчете появляется предупреждение типа -на ноль делить нельзя и программа виснет. Что естественно. Закрыть можно только через диспетчер.. .

Оффлайн DL2KQ

  • Администратор
  • *****
  • Сообщений: 2493
  • Репутация: +257/-3
    • Просмотр профиля
Re: MMANA-GAL basic, версия 3.5.3
« Ответ #122 : 16 Декабря 2024, 16:49:47 »
Поясню: это не баг в общепринятом смысле (т.е. не ошибка программиста и не заскок конкретной программы). Это принципиально неустранимое ограничение любых компьютеров.

В математике, какие бы два сколь угодно близких числа мы не взяли, между ними всегда есть еще другие числа. Т.е. числовая ось непрерывна в любом масштабе. А в компьютере не так. Он в принципе работает с дискретными числами. И если наше вычисленное число попадает между этими дискретами, то оно округляется до ближайшего значения сетки дискретизации.

 Числа одинарной (простой)  точности  с плавающей запятой, используемые в компьютерах, устроены так:
  - нормализованная часть (ряд цифр, что стоит перед множителем 10в какой-то степени, называемой смещением) описывается 24-мя двоичными разрядами. Известно, что десять двоичных разрядов это ~ три десятичных, т.к.  210 ≈ 103. Поэтому 24 двоичных разряда, это примерно 7 десятичных.
   - смещение (описывает степень в какую возводится  множитель для нормализованной части) - 8 двоичных разрядов. Т.е. от 0 до 255. Имея в виду, что нам нужны и отрицательные степени, в двоичной системе множитель может быть в диапазоне  от -127 до + 128. Продолжая иметь в виду, что  210 ≈ 103, получаем, что в десятичной системе смещение (т.е. степень десятки в множителе) будет от -38 до +38.
   То есть,  диапазон чисел простой точности ~  от  10-38 до 1038.  Диапазон колоссальный.  Но точность чисел в этом диапазоне oграничена 7...8 значащими десятичными цифрами.
  Пример. У нас есть число a=16777216. И где-то в результате вычислений мы получаем число b=16777217.  Но код этих чисел в компьютере будет совершенно одинаков! Потому что следующее число после 16777216, которое можно записать в виде числа одинарной точности будет 16777218. Дискрета равно двум цифрам последнего разряда.  Все что между будет автоматически округлено до ближайшего возможного значения.
  А теперь представьте, что в программе нам надо выполнить операцию 1/(b-a). Математически такая процедура допустима и даст внятный результат. Но у нас-то в компьютере получилось, что a=b (их коды одинаковы). И в знаменателе окажется 0. Программа вылетит с ошибкой деления на ноль
.

  Что-бы такие "подарки" случались пореже (но полностью их устранить невозможно принципиально) используются числа двойной точности с плавающей запятой (и в MMANA-GAL и в GAL-ANA используются именно такие). В них для нормализованной части числа отведены 53 бита. Это соответствует примерно 16 десятичным цифрам. Т.е. точность выше примерно в 109 раз. И во столько же раз ниже шанс нарваться на вышеописанную проблему. Но он никогда не исчезает.
   Пример. У нас есть число 40 737 488 355 328 000. В компьютере это число будет записано как 64 битовая величина. Но точно такую же запись (т.е. значение)  будет иметь и число 40 737 488 355 328 001. Эти числа для компьютера неотличимы..
   Кроме более точного описания нормализованной части, в числах двойной точности отведено больше бит для описания смещения. Что дает совершенно фантастический диапазон чисел двойной точности от  10-302 до 10302 (сравните: в наблюдаемой части Вселенной не более 1087 элементарных частиц).

   Числа двойной точности хотя и требуют больше ресурсов компьютера и большего времени вычислений, практически всегда дают точность гораздо  выше реально требуемой. Исключения составляют задачи когда длиннющие числа должны совпадать до 15...17 разряда,  а дискретизация приводит к их разнице (или наоборот, два числа отличаются на слишком малую величину, а дискретизация убивает эту разницу).
   
   С числами одинарной точности проблема дискретизации встречается чаще. Например, если вы видели в результатах каких-то (не наших) вычислений результат 3,4999999 вместо 3,5 – это оно: слишком много знаков, шаг дискретизации представления чисел в компьютере оказался грубоват.
« Последнее редактирование: 17 Декабря 2024, 00:02:02 от DL2KQ »