Decimal floating-point class
Decimal floating-point types are likely to be part of a future C and C++ standard.
Here is a simple wrapper class for Mike Cowlishaw's decNumber
C Library, written in C++.
It is currently in an early design stage (just a first try, the design
is far from perfect, it is incomplete and notations are sometimes
inconsistent). But most of its operators work as they should do, and
most of Mikes testcases pass successfully. The function
DecimalFloat_Testcases("d:\\cpp.boo\\decnumber\\decnumberclass\\decTest\\")
in my test program test_rk reads all the testcases from Mikes decTest
files and logs each testcase in a file (bcb files were created with
Borland C++Builder 6, gcc with MinGW g++, and msc with MS Visual Studio
.Net 2003). With “grep "###number" *.log” you get the summary lines:
File abs.decTest_bcb.log: ###number of tests
passed=87 failed=2
File abs.decTest_gcc.log: ###number of tests
passed=87 failed=2
File abs.decTest_msc.log: ###number of tests
passed=87 failed=2
File add.decTest_bcb.log: ###number of tests
passed=773 failed=45
File add.decTest_gcc.log: ###number of tests
passed=773 failed=46
File add.decTest_msc.log: ###number of tests
passed=773 failed=45
...
Example usage (more detailled here):
int
main(int argc, char* argv[])
{
cout<<"Test decimal floats:"<<endl;
// decimal float class is DecFloat, defined in "DecFloat.h"
// DecFloats can be initialized with strings, ints and decimal float
expressions:
DecFloat d1="0.70",
d2="1.05",
d3=d1*d2;
// stream output for DecFloat expressions:
cout<<"d1="<<d1<<endl;
cout<<"d2="<<d2<<endl;
cout<<"d1*d2="<<d3<<endl;
cout<<"d1*d2="<<d1*d2<<endl;
// arithmetic expressions can be formed in the usual way:
int i1=17, i2=123, i3=123;
d1=i1, d2=i2, d3=i3;
DecFloat x=d1+(d1+d2*d3)-d1*d2;
int i=i1+(i1+i2*i3)-i1*i2;
cout<<x<<"=="<<i<<endl; // can't believe it:
they are really equal
// errors are reported by status flags
// DecContextStatusString() returns them as text
d1=0;
d2=d2/d1;
cout<<"After div by 0:
DecContextStatusString()="<<DecContextStatusString()<<endl;
Context.ClearStatus();
d1="abc";
cout<<"After d1=\"abc\":
DecContextStatusString()="<<DecContextStatusString()<<endl;
Context.ClearStatus();
cout<<"After ClearStatus():
"<<DecContextStatusString()<<endl;
// comparison operators
if (d1<d2) cout<<"less"<<endl;
if (d1<=d2) cout<<"less equal"<<endl;
if (d1>d2) cout<<"greater"<<endl;
if (d1>=d2) cout<<"greater equal"<<endl;
if (d1==d2) cout<<"equal"<<endl;
if (d1!=d2) cout<<"not equal"<<endl;
// assignments
d1=d2; // of DecFloats
d1="1.23"; // of string literals
d1=17; // of ints
{ // filestream output and input
ofstream f("c:\\dftest.txt");
f<<d1<<endl;
f<<d2<<endl;
}
// math epressions pow, max, min, sqrt
cout<<"max("<<d1<<","<<d2<<")="<<max(d1,d2)<<endl;
cout<<"min("<<d1<<","<<d2<<")="<<min(d1,d2)<<endl;
d2=2;
cout<<"sqrt("<<d2<<")="<<sqrt(d2)<<endl;
cout<<"pow("<<d1<<","<<d2<<")="<<pow(d1,d2)<<endl;
// pass the directory of the decnumber testcases:
DecimalFloat_Testcases("D:\\cpp.boo\\decNumber\\dectest\\");
// Most of Mike Cowlishaw's testcases are processed correctly
return 0;
}
Download the C++ wrapper class here. To use it, you also have to
download the decNumber
C Library and pay attention to its licence conditions.
EMail:
Richard Kaiser mail_d2 @ rkaiser . de
www.rkaiser.de
June 10, 2004