Evaluation tools

Калькулятор используется для вычисления строковых выражений. Используется, например, при чтении параметров из файла конфигурации или полей ввода. Калькулятор поддерживает основные арифметические операции и может расширяться произвольными функциями.

Калькулятор поддерживает следующие основные арифметические операции (в порядке убывания приоритета):

По умолчанию доступны два калькулятора: с вещественными и целыми числами, соответственно omni::calc::evalf() и omni::calc::evali(). Эти функции эквивалентны функциям стандартной библиотеки atof и atoi соответственно, но умеют выполнять простые арифметические операции (не содержат функций расширения).

Функции расширения

Калькулятор поддерживает расширение произвольными функциями. Пользовательская функция должна иметь следующий прототип:

 T user_func(T x) 

В выражении могут быть использваны два типа функций: префиксные и суффиксные. Суффиксные функции в основном используются для задания единиц измерения и соответствующего масштабирования. Например, выражение

"3.0 dB"

эквивалентно выражению

"dB2line(3.0)"

Аргумент префиксной функции всегда должен располагаться в скобках! Например:

"abs(-3.0)"

Для управления набором пользовательских функций используются следующие методы omni::calc::UserFuncTable::insert() и omni::calc::UserFuncTable::remove().

Использование калькулятора

Как уже было сказано выше, калькулятор можно использовать для преобразования пользовательского ввода (строки из конфигурационного файла или полей ввода диалога) в числа.

Например, нужно получить два параметра: время моделирования в секундах и частоту несущей в герцах. Для удобства пользователя мы можем ему позволить задавать эти значения разными вариантами:

  simulation_time = "120 min"
  carrier_freq = "2.4 MHz"

или

  simulation_time = "2*60 min"
  carrier_freq = "2400 KHz"

или

  simulation_time = "2 hour"
  carrier_freq = "2400000 Hz"

Для этого создаем два калькулятора: один будет вычислять время, а другой частоту. Можно, конечно, использовать и один калькулятор, но тогда пользователь получает возможность в поле ввода для времени ввести частоту (MHz, KHz, Hz) и наоборот.

  omni::calc::Calculator<double> calc_sec;
  omni::calc::Calculator<double> calc_Hz;

и добавляем соответствующие функции масштабирования

  calc_sec.suffix().insert("hour", omni::calc::Multiplier<double, 60*60>());
  calc_sec.suffix().insert("min",  omni::calc::Multiplier<double, 60>());
  calc_sec.suffix().insert("sec",  omni::calc::Multiplier<double, 1>());

  calc_Hz.suffix().insert("MHz", omni::calc::Multiplier<double, 1000000>());
  calc_Hz.suffix().insert("KHz", omni::calc::Multiplier<double, 1000>());
  calc_Hz.suffix().insert("Hz",  omni::calc::Multiplier<double, 1>());

готово, можно использовать эти калькуляторы для преобразования пользовательского ввода:

  std::string s_secs;
  std::cout << "simulation time [s]: ";
  std::cin >> s_secs;
  double x_secs = calc_sec(s_secs);

  std::string s_freq;
  std::cout << "carrier frequency [Hz]: ";
  std::cin >> s_freq;
  double x_freq = calc_Hz(s_freq);

Некоторые суффиксные функции не изменяют аргумента и служат исключительно для введения единицы измерения, например: Hz или sec.

В примере полностью пропущена обработка ошибок. В реальных программах, при вычислении выражения могут генерироваться исключения, которые неплохо было бы перехватывать.

Доступные калькуляторы

By default the following calculators are available:
Generated on Wed Jun 6 17:27:47 2007 for OMNI by  doxygen 1.5.2