#include <stdio.h>
#include "bigdecimal.h"
int main(int argc, char* argv[])
{
VP_HANDLE a = VpAlloc("+1234567890.1234567890 123456789000000E0",100);
VpPrintF (stdout,a); /* ===> 1234567890.1234567890 123456789 */
VpFree(&a);
return 0;
}
Bigdecimal functions | meaning |
---|---|
c = VpAlloc(szVal,m) | Allocates Bigdecimal variable and sets it's value to szVal. szVal is a character string representing any numerical value. m is the maximum number of digits c can hold. |
c = VpMemAlloc(m) | Allocates Bigdecimal variable(the value is 0). m is the maximum number of digits c can hold. |
c = VpClone(a) | Creates a copy of a. |
c = VpLoad(c,szVal) |
Load the value represented by szVal(which is 'const char *') to existing vp-variable c. And returns c,if normally processed,otherwise ERROR code. c must have enough length to keep value given by szVal without any rounding operation, otherwise this function fails. |
VpFree(&c) | Frees memories allocated to c. |
Bigdecimal functions | meaning |
---|---|
m = VpMaxLength(c) | m is the maximum number of digits c can store. m is slightly bigger than the value specified by VpAlloc() or VpMemAlloc() due to internal logic. |
n = VpCurLength(c) | n is the number of digits currently stored in c. |
int main(int argc, char* argv[])
{
VP_HANDLE a = VpAlloc("+1234567890.1234567890 123456789000000E0",100);
VP_HANDLE b = VpAlloc("20",10);
VP_HANDLE c = VpMemAlloc(150);
VpPrintE(stdout,VpMul(c,a,b)); /* c=a*b ===> 0.2469135780 2469135780 246913578E11 */
VpFree(&a);
VpFree(&b);
VpFree(&c);
return 0;
}
Bigdecimal offers functions for arithmetic operations(most function returns resulting 'c' for convenience of the programming).Bigdecimal functions | meaning | notes | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
c = VpAsgn(c,a,op) | c = a (op=1) or c = -a (op=-1) | the final digit of c is rounded if VpMaxLength(c)<VpCurLength(b) | ||||||||||||||||
c = VpAdd(c,a,b) | c = a+b | the final digit of c is rounded if VpMaxLength(c)<VpCurLength(a+b) | ||||||||||||||||
c = VpSub(c,a,b) | c = a-b | the final digit of c is rounded if VpMaxLength(c)<VpCurLength(a-b) | ||||||||||||||||
c = VpMul(c,a,b) | c = a*b | VpMaxLength(c)>VpCurLength(a)+VpCurLength(b)* | ||||||||||||||||
c = VpDiv(c,r,a,b) | c = a/b (r is a remainder) | VpMaxLength(r)>Max(VpCurLength(a),VpMaxLength(c)+VpCurLength(b))* | ||||||||||||||||
f = VpCmp(a,b) | 1(if a>b),0(if a==b),-1(if a<b),VP_ERROR_NON_NUMERIC(if uncomparable). | return value is an integer. | ||||||||||||||||
c = VpFrac(c,a) | copies all digits after the decimal point of a to c(|c|<1 or c=0) | |||||||||||||||||
c = VpFix(c,a) c = VpInt(c,a) | copies all digits before the decimal point of a to c(|c|>=1 or c=0) | |||||||||||||||||
c = VpAbs(c) | c = |c| | |||||||||||||||||
n = VpExponent(c) | returns n,where c=0.xxxxxxx10**n | n is an integer. | ||||||||||||||||
n = VpEffectiveDigits(c) | returns n,where n is the number of effective digits. | n is an integer for which leading and trailing 0's are not counted. | ||||||||||||||||
c = VpRevertSign(c) c = VpNegate(c) | c = -c | |||||||||||||||||
f = VpGetSign(c) | returns one of the values defined in bigdecimal.h as listed bellow :
| return value is an integer. | ||||||||||||||||
c = VpSetSign(c,f) | sets c=|c|(if f>0),c=-|c|(if f<0) | f is an integer. |
Bigdecimal functions | meaning | notes |
---|---|---|
c = VpSqrt(c,a) | c = a1/2 | computed by Newton's method. |
c = VpPI(c) | c = 3.141592.... | computed by Matine's formula. |
c = VpSin(c,a) | c = sin(a) | see Note* |
c = VpCos(c,a) | c = cos(a) | see Note* |
c = VpAtan(c,a) | c = tan-1(a) | |a|<=1, see Note* |
c = VpExp(c,a) | c = ea | see Note* |
c = VpLog(c,a) | c = logea | 0<a<= 2, see Note* |
c = VpPower(c,a,n) | c = an | n must be an ingteger. |
#define F(H,V) printf(H);VpPrintF(stdout,V);printf("\n");
#define E(H,V) printf(H);VpPrintE(stdout,V);printf("\n");
VP_HANDLE sqrt2 = VpMemAlloc(100);
VP_HANDLE pi = VpMemAlloc(100);
VP_HANDLE pi2 = VpMemAlloc(100);
VP_HANDLE one = VpMemAlloc(100);
VP_HANDLE two = VpAlloc("2",1);
VP_HANDLE r;
VP_UINT m;
F("Sqrt(2) =",VpSqrt(sqrt2,two)); /* sqrt2 = sqrt(2) */
VpFree(&two);two = VpAlloc("0",VpCurLength(sqrt2)*2+1);
F("Sqrt(2)**2=",VpMul(two,sqrt2,sqrt2)); /* two = sqrt(2)**2 ==> 2.0 */
F("pi =",VpPI(pi)); /* pi = 3.141592... */
m = VpCurLength(pi)+VpCurLength(two)+1;
if(m<VpMaxLength(pi2)) m = VpMaxLength(pi2)+1;
r = VpAlloc("0",m);
F("pi2 =",VpDiv(pi2,r,pi,two)); /* pi2 = pi/2 */
E("sin(pi2) =",VpSin(one,pi2)); /* one = sin(pi/2) ==> 1.0 */
VpFree(&r);
.........
Results:
Sqrt(2) = 1.4142135623 7309504880 1688724209 6980785696 7187537694 8073176679 7379907324 7846210703 8850387534 3276415727 Sqrt(2)**2= 1.9999999999 9999999999 9999999999 9999999999 9999999999 9999999999 9999999999 9999999999 9999999999 9999999999 0096588757 8795506493 0439931247 0016809150 7199370597 5256343471 3223747479 7111963099 3958184437 6132938529 pi = 3.1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170676 pi2 = 1.5707963267 9489661923 1321691639 7514420985 8469968755 2910487472 2961539082 0314310449 9314017412 671058 sin(pi2) = 0.9999999999 9999999999 9999999999 9999999999 9999999999 9999999999 9999999999 9999999999 9999999999 9999999991 0017E0As series expansion is adopted for math functions,maximum iteration count can be set by the user.
Bigdecimal functions | meaning |
---|---|
m = VpGetMaxIterationCount() | returns maximum iteration count(default=10000) |
m = VpSetMaxIterationCount(m) | sets maximum iteration count to m. |
n = VpGetIterationCount() | returns iteration count spent by the most recent computation. |
Bigdecimal functions | meaning |
---|---|
n = VpPrintE(fp,c) | print c to fp in E-format. |
n = VpPrintF(fp,c) | print c to fp in F-format. |
E-format ==> 0.xxxxxxxxxx....Eeeewhere x,y and e are digits('0'-'9'). Bigdecimal value can be converted to string(character array).
F-format ==> xxxxxxxx.yyyyyyyyyyy
Bigdecimal functions | meaning |
---|---|
char *szE = VpToStringE(c,szE) | szE <== E-format of c. |
char *szF = VpToStringF(c,szF) | szF <== F-format of c. |
Bigdecimal functions | meaning |
---|---|
m = VpStringLengthE(c) | m is a maximum character array size to represent c in E-format. |
m = VpStringLengthF(c) | m is a maximum character array size to represent c in F-format. |
VP_UINT VpGetDigitSeparationCount(); /* default = 10 */ VP_UINT VpSetDigitSeparationCount(VP_UINT m);DigitSeparator
char VpGetDigitSeparator(); /* default = ' ' */ char VpSetDigitSeparator(char c);DigitLeader
char VpGetDigitLeader(); /* default = ' ' */ char VpSetDigitLeader(char c);The results of these options can be easily confirmed by using VPC.
VPC(Variable Precision Calculator) of Bigdecimal(V1) Copyright (c) 2018 by Shigeo Kobayashi. Allrights reserved. Enter command ? PI a a= 0.3141592653 5897932384 6264338327 9502884197 1693993751 0582097494 4592307816 4062862089 9862803482 5342117063 2E1 ? dc? 10 ? dc= 5 5 ? a a= 0.31415 92653 58979 32384 62643 38327 95028 84197 16939 93751 05820 97494 45923 07816 40628 62089 98628 03482 53421 17063 2E1 ? ds? ' ' ? ds= , ',' ? a a= 0.31415,92653,58979,32384,62643,38327,95028,84197,16939,93751,05820,97494,45923,07816,40628,62089,98628,03482,53421,17063,2E1 ? dl? ' ' ? dl= + '+' ? a a=+0.31415,92653,58979,32384,62643,38327,95028,84197,16939,93751,05820,97494,45923,07816,40628,62089,98628,03482,53421,17063,2E1 ?
Bigdecimal functions | meaning |
---|---|
f = VpGetRoundMode() | f is a rounding mode listed bellow. |
f = VpSetRoundMode(f) | f is a rounding mode listed bellow. |
Round mode | Meaning | Value |
---|---|---|
VP_ROUND_UP | round away from zero. | 1 |
VP_ROUND_DOWN | round towards zero(truncate). | 2 |
VP_ROUND_HALF_UP | round up if the digit >= 5 otherwise truncated(default). | 3 |
VP_ROUND_HALF_DOWN | round up if the digit >= 6 otherwise truncated. | 4 |
VP_ROUND_CEILING | round towards positive infinity(ceil). | 5 |
VP_ROUND_FLOOR | round towards negative infinity(floor). | 6 |
VP_ROUND_HALF_EVEN | round towards the even neighbor(Banker's rounding). | 7 |
Bigdecimal functions | meaning |
---|---|
c = VpScaleRound(c,i) |
i is the position of round operation mesured from decimal point. If i>=0,then the (i+1)th digit counted from the decimal point to right direction is processed(resulting number of digits after decimal point is less than or equal to i). If i<0,then the i-th digit counted from the decimal point to left direction is processed(at least i 0s are placed from the decimal point to left). |
c = VpLengthRound(c,i) | Round operation is done at the i-th position counted from the left side of the number. |
VP_HANDLE c = VpAlloc("5555555555.5555555555",1);
VP_HANDLE a = VpMemAlloc(VpMaxLength(c));
VpAsgn(a,c,1); F("ScaleRound ( 0)= ",VpScaleRound (c, 0));
VpAsgn(c,a,1); F("ScaleRound ( 2)= ",VpScaleRound (c, 2));
VpAsgn(c,a,1); F("ScaleRound (-2)= ",VpScaleRound (c,-2));
VpAsgn(c,a,1); F("LengthRound(12)= ",VpLengthRound(c,12));
VpAsgn(c,a,1); F("LengthRound( 8)= ",VpLengthRound(c, 8));
Results:
ScaleRound ( 0)= 5555555556 ScaleRound ( 2)= 5555555555.56 ScaleRound (-2)= 5555555600 LengthRound(12)= 5555555555.56 LengthRound( 8)= 5555555600In above examples,the rounding operation is done by default rounding mode(VP_ROUND_HALF_UP).
VP_EXPORT(VP_HANDLE) VpAsgn2(VP_HANDLE c, VP_HANDLE a, int isw,int mode) VP_EXPORT(VP_HANDLE) VpScaleRound2(VP_HANDLE a, int ixRound,int mode) VP_EXPORT(VP_HANDLE) VpLengthRound2(VP_HANDLE a, int ixRound,int mode)
VP_HANDLE h = VpAlloc("12345+123",2); /* ==> ERROR: + is placed at illegal position. */
if(VpInvalid(h)) {
printf("ERROR returned by VpAlloc()\n");
exit(0);
}
......
Checking on the return value is always valid.macros | meaning |
---|---|
VpIsInvalid(c) | 1 if c is invalid,0 if c is valid VP_HANDLE. |
VpIsValid(h) | 0 if h is invalid,1 if h is valid VP_HANDLE. |
VpIsNumeric(h) | 1 if h is valid and is not NaN nor Infinity,0 of h is invalid,h is NaN or Infinity. |
void MyException(VP_HANDLE h,const char *msg)
{
printf("MyException(%s)\n",msg);
}
void main(int argc, char* argv[])
{
VpSetExceptionHandler(MyException);
E("Err =",VpAlloc("-0..123",1)); /* ERROR => this causes MyException() is called within VpAlloc() */
}
Results:
MyException(Bad numeric string for VpAlloc()) VpPrintF():Invalid handle(1)
Bigdecimal functions | meaning |
---|---|
f = VpIsOne(c) c = VpSetOne(c) | 1 if c==1 c=1 |
f = VpIsPosZero(c) c = VpSetPosZero(c) | 1 if c==+0 c=+0 |
f = VpIsNegZero(c) c = VpSetNegZero(c) | 1 if c==-0 c=-0 |
f = VpIsZero(c) c = VpSetZero(c,f) | 1 if c==0 c=0 (+0 if f>0, -0 if f<0)) |
f = VpIsNaN(c) c = VpSetNaN(c) | 1 if c== NaN c=NaN |
f = VpIsPosInf(c) c = VpSetPosInf(c) | 1 if c==+Infinity c=+Infinity |
f = VpIsNegInf(c) c = VpSetNegInf(c) | 1 if c==-Infinity c=-Infinity |
f = VpIsInf(c) c = VpSetInf(c,f) | 1 if c==Infinity c=Infinity (+Infinity if f>0,-Infinity if f<0) |
/*
* VP representation
* r = 0.xxxxxxxxx *BASE**exponent
*/
typedef struct {
VP_UINT Size; /* all byte size of this structure(used in realloc() case). */
VP_UINT MaxPrec; /* Maximum precision size */
/* This is the actual size of frac[] */
/*(frac[0] to frac[MaxPrec-1] are available). */
VP_UINT Prec; /* Current precision size. */
/* This indicates how much the. */
/* the array frac[] is actually used. */
VP_UINT Tag; /* Space for the user(Bigdecimal never touch this) */
/* Use VpSetTag() or VpGetTab() to access. */
int exponent;/* Exponent part. */
int sign; /* Attributes of the value. */
/* See VP_SIGN_xxxxxxx defined.
* ==0 : NaN
* 1 : Positive zero
* -1 : Negative zero
* 2 : Positive number
* -2 : Negative number
* 3 : Positive infinite number
* -3 : Negative infinite number
*/
VP_DIGIT frac[1]; /* Array of fraction part. */
} Real;
#define VP_SIGN_NaN 0 /* NaN */
#define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */
#define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */
#define VP_SIGN_POSITIVE_FINITE 2 /* Positive finite number */
#define VP_SIGN_NEGATIVE_FINITE -2 /* Negative finite number */
#define VP_SIGN_POSITIVE_INFINITE 3 /* Positive infinite number */
#define VP_SIGN_NEGATIVE_INFINITE -3 /* Negative infinite number */
VP_DIGIT can be 32-bit or 64-bit unsigned integer(see bigdecimal.h).