Калькулятор поддерживает следующие основные арифметические операции (в порядке убывания приоритета):
По умолчанию доступны два калькулятора: с вещественными и целыми числами, соответственно 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.
В примере полностью пропущена обработка ошибок. В реальных программах, при вычислении выражения могут генерироваться исключения, которые неплохо было бы перехватывать.