📄 lb_maths.cpp
字号:
void FuncOpCode::IntLong(CStack& aStack,COplRuntime&, CFrame*)
// Double to long integer
{
TInt32 res;
if (Math::Int(res,aStack.PopReal64())<0)
User::Leave(KErrOverflow);
aStack.Push(res);
}
void FuncOpCode::Ln(CStack& aStack, COplRuntime& , CFrame* )
{
User::LeaveIfError(Math::Ln(*aStack.StackPtr().Real,*aStack.StackPtr().Real));
}
void FuncOpCode::Log(CStack& aStack, COplRuntime& , CFrame* )
{
User::LeaveIfError(Math::Log(*aStack.StackPtr().Real,*aStack.StackPtr().Real));
}
void FuncOpCode::Pi(CStack& aStack, COplRuntime& , CFrame* )
{
aStack.Push(KPi);
}
void FuncOpCode::Rad(CStack& aStack, COplRuntime& , CFrame* )
{
TRealX arg(aStack.PopReal64());
User::LeaveIfError(arg.DivEq(TRealX(KRadToDeg)));
aStack.Push(TReal64(arg));
}
void FuncOpCode::Rnd(CStack& aStack, COplRuntime& aRuntime, CFrame* )
{
aStack.Push(Math::FRand(aRuntime.Seed()));
}
void FuncOpCode::Sin(CStack& aStack, COplRuntime& , CFrame* )
{
User::LeaveIfError(Math::Sin(*aStack.StackPtr().Real,*aStack.StackPtr().Real));
}
void FuncOpCode::Sqr(CStack& aStack, COplRuntime& , CFrame* )
{
User::LeaveIfError(Math::Sqrt(*aStack.StackPtr().Real,*aStack.StackPtr().Real));
}
void FuncOpCode::Tan(CStack& aStack, COplRuntime& , CFrame* )
{
User::LeaveIfError(Math::Tan(*aStack.StackPtr().Real,*aStack.StackPtr().Real));
}
void FuncOpCode::Val(CStack& aStack, COplRuntime& , CFrame* )
{
TLex lex(aStack.PopString());
lex.SkipSpaceAndMark();
TReal result;
if (lex.Val(result)<0)
User::Leave(KErrArgument);
aStack.Push(result);
}
#pragma warning ( disable : 4706) // assignment within conditional expression
TReal* ptrList(TInt& count,CStack& aStack,COplRuntime& aRuntime)
/*
Point to a list of doubles, whether on the stack or in an array.
Byte at IP is 0 for an array or else the count of arguments on the stack for a list.
If an array is passed, the stack contains an 'OPL left-side reference' which, for a variable
or array is
{
TUint8 flag; // zero for a normal variable
TAny *ptr; // address of the variable or array
}
*/
{
if (!(count=aRuntime.IP8()))
{ // it's an array
count=aStack.PopInt16(); // count on stack for array
aStack.PopInt16(); // throw away field flag
TInt16* ret=(TInt16*)aStack.PopPtr(); // ptr to array
if (count<=0 || count>*(ret-1)) // array count 16-bits before ptr
User::Leave(KOplErrSubs);
return (TReal *)ret;
}
else
{
TReal* ret=aStack.StackPtr().Real;
TStackPtr stackPtr;
stackPtr.Real = ret + count;
aStack.SetStackPtr(stackPtr);
return ret;
}
}
#pragma warning ( default: 4706)
void FuncOpCode::Max(CStack& aStack, COplRuntime& aRuntime, CFrame* )
{
TInt count;
TReal* list=ptrList(count,aStack,aRuntime);
TReal result=OplUtil::GetFloat(list++);
for (TInt ii=(count-1);ii;ii--)
{
TReal val=OplUtil::GetFloat(list++);
if (result<val)
result=val;
}
aStack.Push(result);
}
void FuncOpCode::Mean(CStack& aStack, COplRuntime& aRuntime, CFrame* )
{
TInt count;
TReal* list=ptrList(count, aStack, aRuntime);
TRealX result=0.0;
for (TInt ii=count;ii;ii--)
{
User::LeaveIfError(result.AddEq(TRealX(OplUtil::GetFloat(list++))));
}
User::LeaveIfError(result.DivEq(count));
aStack.Push(TReal64(result));
}
void FuncOpCode::Min(CStack& aStack, COplRuntime& aRuntime , CFrame* )
{
TInt count;
TReal* list=ptrList(count,aStack,aRuntime);
TReal result=OplUtil::GetFloat(list++);
for (TInt ii=(count-1);ii;ii--)
{
// list is return value
TReal val=OplUtil::GetFloat(list++);
if (val<result)
result=val;
}
aStack.Push(result);
}
void FuncOpCode::Std(CStack& aStack, COplRuntime& aRuntime, CFrame* aFramePtr)
{
FuncOpCode::Var(aStack,aRuntime,aFramePtr);
FuncOpCode::Sqr(aStack,aRuntime,aFramePtr);
}
void FuncOpCode::Sum(CStack& aStack, COplRuntime& aRuntime, CFrame* )
/*
SUM(array(), count%) has *IP8==0
stack[0] == array ref
stack[1] == count
SUM(real1,real2,...) has *IP8==count
stack[0] == real1
stack[1] == real2
etc.
*/
{
TInt count;
TReal* list=ptrList(count,aStack,aRuntime);
TRealX result = 0.0;
TInt ii = 0;
for (ii=count; ii; ii--)
{
User::LeaveIfError(result.AddEq(TRealX(OplUtil::GetFloat(list++))));
}
aStack.Push(TReal64(result));
}
void FuncOpCode::Var(CStack& aStack, COplRuntime& aRuntime, CFrame* )
{
TInt count;
TReal* list=ptrList(count,aStack,aRuntime);
TRealX result = 0.0;
TRealX var =0.0;
for (TInt ii=count;ii;ii--)
{
User::LeaveIfError(result.AddEq(TRealX(OplUtil::GetFloat(list++))));
}
TRealX mean=TReal64(result);
User::LeaveIfError(mean.DivEq(count));
list-=count;
for (TInt iii=count; iii; iii--)
{
TRealX val=OplUtil::GetFloat(list++);
TRealX temp(val);
User::LeaveIfError(temp.SubEq(mean));
User::LeaveIfError(temp.MultEq(temp));
User::LeaveIfError(var.AddEq(temp));
}
User::LeaveIfError(var.DivEq(TRealX(count-1)));
aStack.Push(TReal64(var));
}
void PushJustified(CStack& aStack, TBuf<256>& buffer, TInt width,TInt err)
{
TInt absWidth=width;
if (width<0)
absWidth=-width;
if (err<0)
{
buffer.SetLength(absWidth);
buffer.Fill('*');
}
else if (width<0)
{
TInt length=buffer.Length();
TInt pad= absWidth - length;
if (pad<0)
{
buffer.SetLength(absWidth);
buffer.Fill('*');
}
else
{
TBuf<256> spaces(pad);
spaces.Fill(' ');
buffer.Insert(0,spaces);
}
}
aStack.Push(buffer);
}
LOCAL_C TInt PushRealString(CStack& aStack, COplRuntime& aRuntime, TInt aWidth,TInt aDecimals,TInt aEType)
{
TReal arg=aStack.PopReal64();
if (aWidth<-255||aWidth>255)
return KOplErrInvalidArgs;
TBuf<256> buffer;
TInt flags=aRuntime.UserFlags();
TOplRealFormat format(flags,aWidth >= 0 ? aWidth : -aWidth,aDecimals);// object(width) object (width, no.of d.p.'s)
format.SetType(aEType);
// format.iTriLen=0;
TInt err=buffer.Num(arg,format); // fills buffer with arg in format
buffer.UpperCase();
PushJustified(aStack,buffer,aWidth,err);
return KErrNone;
}
void FuncOpCode::FixStr(CStack& aStack, COplRuntime& aRuntime, CFrame* )
{
// double to fixed decimal places string Fix$(x,d.p's,length of string)
TInt16 width=aStack.PopInt16();
TInt16 decimals=aStack.PopInt16();
User::LeaveIfError(PushRealString(aStack,aRuntime,width,decimals,KRealFormatFixed));
}
void FuncOpCode::GenStr(CStack& aStack, COplRuntime& aRuntime, CFrame* )
{
// double to general format string Gen$(x,length of string)
TInt16 width=aStack.PopInt16();
User::LeaveIfError(PushRealString(aStack,aRuntime,width,0,KRealFormatGeneral));
}
void FuncOpCode::HexStr(CStack& aStack, COplRuntime& , CFrame* )
{
// long to hex string Hex$(x&)
TBuf<256> buffer;
buffer.Num(aStack.PopInt32(),EHex);
buffer.UpperCase();
aStack.Push(buffer);
}
void FuncOpCode::NumStr(CStack& aStack, COplRuntime& aRuntime, CFrame* )
{
TInt16 width=aStack.PopInt16();
User::LeaveIfError(PushRealString(aStack,aRuntime,width,0,KRealFormatFixed));
}
void FuncOpCode::SciStr(CStack& aStack, COplRuntime& aRuntime, CFrame* )
{
// floating point to string in scientific format
TInt16 width=aStack.PopInt16();
TInt16 decimals=aStack.PopInt16();
User::LeaveIfError(PushRealString(aStack,aRuntime,width,decimals,KRealFormatExponent));
}
// OpCode class
void OpCode::Randomize(CStack& aStack, COplRuntime& aRuntime, CFrame* /* aFramePtr */)
{
TInt32 s=aStack.PopInt32();
aRuntime.Seed().Set(s,s);
}
/* End of $Workfile: LB_MATHS.CPP $ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -