mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-06 15:04:11 +00:00
Custom math expressions + bugfix harmonic mixing
This commit is contained in:
parent
49e0b901fd
commit
9614c9d850
97 changed files with 18173 additions and 11 deletions
112
Software/PC_Application/Traces/Math/parser/mpOprtPostfixCommon.cpp
Executable file
112
Software/PC_Application/Traces/Math/parser/mpOprtPostfixCommon.cpp
Executable file
|
|
@ -0,0 +1,112 @@
|
|||
#include <limits>
|
||||
#include "mpOprtPostfixCommon.h"
|
||||
|
||||
MUP_NAMESPACE_START
|
||||
|
||||
//-----------------------------------------------------------
|
||||
//
|
||||
// class OprtFact
|
||||
//
|
||||
//-----------------------------------------------------------
|
||||
|
||||
OprtFact::OprtFact()
|
||||
:IOprtPostfix(_T("!"))
|
||||
{}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
void OprtFact::Eval(ptr_val_type& ret, const ptr_val_type *arg, int)
|
||||
{
|
||||
if (!arg[0]->IsInteger())
|
||||
throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), GetIdent(), arg[0]->GetType(), 'i', 1));
|
||||
|
||||
int_type input = arg[0]->GetInteger();
|
||||
float_type input_long = float_type(input);
|
||||
|
||||
if (input < 0) {
|
||||
throw ParserError(ErrorContext(ecDOMAIN_ERROR, GetExprPos(),
|
||||
GetIdent()));
|
||||
}
|
||||
|
||||
float_type result = 1;
|
||||
for (float_type i = 1.0; i <= input_long; i += 1.0)
|
||||
{
|
||||
result *= i;
|
||||
|
||||
// <ibg 20130225/> Only throw exceptions if IEEE 754 is not supported. The
|
||||
// Prefered way of dealing with overflows is relying on:
|
||||
//
|
||||
// http://en.wikipedia.org/wiki/IEEE_754-1985
|
||||
//
|
||||
// If the compiler does not support IEEE 754, chances are
|
||||
// you are running on a pretty fucked up system.
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#endif /* _MSC_VER */
|
||||
if ( !std::numeric_limits<float_type>::is_iec559 &&
|
||||
(result>std::numeric_limits<float_type>::max() || result < 1.0) )
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif /* _MSC_VER */
|
||||
{
|
||||
throw ParserError(ErrorContext(ecOVERFLOW, GetExprPos(), GetIdent()));
|
||||
}
|
||||
// </ibg>
|
||||
}
|
||||
|
||||
*ret = result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
const char_type* OprtFact::GetDesc() const
|
||||
{
|
||||
return _T("x! - Returns factorial of a non-negative integer.");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
IToken* OprtFact::Clone() const
|
||||
{
|
||||
return new OprtFact(*this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
//
|
||||
// class OprtPercentage
|
||||
//
|
||||
//-----------------------------------------------------------
|
||||
|
||||
OprtPercentage::OprtPercentage()
|
||||
:IOprtPostfix(_T("%"))
|
||||
{}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
void OprtPercentage::Eval(ptr_val_type& ret, const ptr_val_type *arg, int)
|
||||
{
|
||||
|
||||
switch (arg[0]->GetType()) {
|
||||
case 'i':
|
||||
case 'f': {
|
||||
float_type input = arg[0]->GetFloat();
|
||||
*ret = input / 100.0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), GetIdent(), arg[0]->GetType(), 'f', 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
const char_type* OprtPercentage::GetDesc() const
|
||||
{
|
||||
return _T("x% - Returns percentage of integer/float.");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
IToken* OprtPercentage::Clone() const
|
||||
{
|
||||
return new OprtPercentage(*this);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue