我想了解使浮动和双打工作的代码。我之所以尝试,是因为我需要引入一种由军方定义的新浮点类型,该类型不受 Microsoft 原生支持。
这是以前做过还是有可能?如果是这样,是否有我可以检索的文件或我自己可以遵循的步骤?
我想了解使浮动和双打工作的代码。我之所以尝试,是因为我需要引入一种由军方定义的新浮点类型,该类型不受 Microsoft 原生支持。
这是以前做过还是有可能?如果是这样,是否有我可以检索的文件或我自己可以遵循的步骤?
对于初学者,您可以将军用格式编码/解码为 IEEE 754
通过这种方式,您可以使用FPU和标准数学内容,因此在开始时一切正常。代码如下所示:
military fabs(military x)
{
double _x;
_x=military2double(x);
_x=fabs(_x);
return double2military(_x);
}
将函数转换为您的格式
所以开始一一重写数学函数来原生处理军用格式
military fabs(military x)
{
if (x<0) x=-x;
return x;
}
military从这一点来看,the应该是一个类,您需要将基本运算符和函数编码到其中,以便将其作为公共变量数据类型处理。不要忘记优化你可以fabs做的事情,例如可以通过按位AND掩码尾数符号位来完成,除非你的军事格式不使用二进制补码。
这是我的一个浮点数类的样子:
//---------------------------------------------------------------------------
const int _arbnum_max_siz=1<<18; // mantisa limit [32bit words] 1<<18 = MByte
const int _arbnum_min_exp=-0x80000000; // min exponent limit for base = 2
const int _arbnum_max_exp=+0x7FFFFFFD; // max exponent limit for base = 2
const int _arbnum_nan_exp=+0x7FFFFFFE; // not a number exponent constatn
const int _arbnum_inf_exp=+0x7FFFFFFF; // infinity exponent constatn
//---------------------------------------------------------------------------
enum _arbnum_error_enum
{
_arbnum_error_AllOk=0,
_arbnum_error_NotEnoughMemory, // memory allocation
_arbnum_error_CorruptedSignum, // bad combination of sig,exp,siz,dat
_arbnum_error_ZeroSize, // unallocated number usage
_arbnum_error_UnexpectedCharInFormat, // str()
_arbnum_error_TooBigNumber, // str() dec num is bigger than expected
};
//---------------------------------------------------------------------------
// |-----|---------------------------|---------------|------|
// | sig | MSB mantisa LSB | exponent | bits |
// |-----|---------------------------|---------------|------|
// | +1 | 0.(0 ... 0) | 2^0 | 0 | +zero
// | -1 | 0.(0 ... 0) | 2^0 | 0 | -zero
// |-----|---------------------------|---------------|------|
// | +1 | 1.(dat[0] ... dat[siz-1]) | 2^exp | n | +number
// | -1 | 1.(dat[0] ... dat[siz-1]) | 2^exp | n | -number
// |-----|---------------------------|---------------|------|
// | +1 | 1.0 | 2^+0x7FFFFFFE | 1 | +infinity
// | -1 | 1.0 | 2^+0x7FFFFFFE | 1 | -infinity
// |-----|---------------------------|---------------|------|
// ^ ^ ^
// ^ ^ used bits count in mantisa
// ^ exponent of msb of dat[0]
// 1. is included in mantisa dat[0] !!!
//---------------------------------------------------------------------------
class arbnum
{
public:
ALU32 alu;
// dat is LSDW first ... MSDW last
DWORD *dat; int siz,exp,sig,bits;
arbnum() { dat=NULL; siz=0; exp=1; sig=+1; bits=0; }
arbnum(int a) { dat=NULL; siz=0; exp=1; sig=+1; bits=0; *this=a; }
arbnum(DWORD a) { dat=NULL; siz=0; exp=1; sig=+1; bits=0; *this=a; }
arbnum(float a) { dat=NULL; siz=0; exp=1; sig=+1; bits=0; *this=a; }
arbnum(double a) { dat=NULL; siz=0; exp=1; sig=+1; bits=0; *this=a; }
arbnum(AnsiString a) { dat=NULL; siz=0; exp=1; sig=+1; bits=0; *this=a; }
arbnum(arbnum& a) { dat=NULL; siz=0; exp=1; sig=+1; bits=0; *this=a; }
~arbnum() { _free(); }
arbnum* operator = (const arbnum *a) { *this=*a; return this; }
arbnum* operator = (const arbnum &a) { _alloc(a.siz); for(int i=0;(i<siz)&&(i<a.siz);i++) dat[i]=a.dat[i]; exp=a.exp; sig=a.sig; bits=a.bits; return this; }
// error handling
void _error(int err)
{
err=1/0;
}
// memory management
void _free();
void _alloc(int _siz);
void _realloc(int _siz);
void _normalize(int _fbits=-1);
// export functions
AnsiString str(const char *cs=""); // cs: "5.3" ".3" "5" "s5.3" " 5.3" "M.M" b,d,h e
int geti32();
DWORD getu32();
float getf32();
double getf64();
// assign operators
arbnum operator = (int x);
arbnum operator = (DWORD x);
arbnum operator = (float x);
arbnum operator = (double x);
arbnum operator = (AnsiString x); // nahra cislo zo stringu (+/-)dec/bin/hex(d/b/h) podla posledneho znaku
// arithmetic operators
arbnum operator + ();
arbnum operator - ();
arbnum operator ++ (); // ++x return this+1
arbnum operator -- (); // --x return this-1
arbnum operator ++ (int y); // x++ return this, and then this+1
arbnum operator -- (int y); // x-- return this, and then this-1
arbnum operator << (int n);
arbnum operator >> (int n);
arbnum operator <<=(int n) { this[0]=this[0]<<n; return *this; };
arbnum operator >>=(int n) { this[0]=this[0]>>n; return *this; };
arbnum operator & (const arbnum &x);
arbnum operator | (const arbnum &x);
arbnum operator ^ (const arbnum &x);
arbnum operator + (const arbnum &x);
arbnum operator - (const arbnum &x);
arbnum operator * (const arbnum &x);
arbnum operator / (const arbnum &x);
arbnum operator % (const arbnum &x);
arbnum operator &=(const arbnum &x) { this[0]=this[0]&x; return *this; };
arbnum operator |=(const arbnum &x) { this[0]=this[0]|x; return *this; };
arbnum operator ^=(const arbnum &x) { this[0]=this[0]^x; return *this; };
arbnum operator +=(const arbnum &x) { this[0]=this[0]+x; return *this; };
arbnum operator -=(const arbnum &x) { this[0]=this[0]-x; return *this; };
arbnum operator *=(const arbnum &x) { this[0]=this[0]*x; return *this; };
arbnum operator /=(const arbnum &x) { this[0]=this[0]/x; return *this; };
arbnum operator %=(const arbnum &x) { this[0]=this[0]%x; return *this; };
// bool operators
int operator ! ( ) { return iszero(); }
int operator && (const arbnum &x) { return ((isnonzero())&&(x.isnonzero())); }
int operator || (const arbnum &x) { return ((isnonzero())||(x.isnonzero())); }
int operator == (const arbnum &x);
int operator != (const arbnum &x);
int operator < (const arbnum &x);
int operator > (const arbnum &x);
int operator <= (const arbnum &x);
int operator >= (const arbnum &x);
int isnan(); // ( this == nan )
int isinf(); // ( this == inf )
int isone(); // ( this == +1 )
int iszero(); // ( this == 0 )
int isnonzero(); // ( this != 0 )
int isinteger(); // ( this==integer(this)) ...-2,-1,0,+1,+2,...
int isreal(); // ( this!=integer(this)) 12.3456
int isfraction(); // ( 1 > abs(this)) 0.555 -0.789
// bit functions
void bitset(int e); // this|=2^e
void bitres(int e); // this&=2^e [ normalize! ]
void bitnot(int e); // this^=2^e [ normalize! ]
int bitget(int e); // =this & 2^e
int bits2size(int n); // = num of DWORDs needed for n>=0 bits
int nibits(); // = num of used integer bits (from number)
int nfbits(); // = num of used fractional bits (from number)
int mibits(); // = num of used integer bits (from mantisa)
int mfbits(); // = num of used fractional bits (from mantisa)
// low level arithmetics
void nan(); // this =+nan
void inf(); // this =+inf
void one(); // this =+1
void zero(); // this =+0
void integer(); // this = odreze desatinnu cast
void fraction(); // this = odreze celu cast
void round(); // this = zaokruhli podla 0.5
void floor(); // this = zaokruhli nadol
void ceil (); // this = zaokruhli nahor
void overflow(); // this = zaokruhli ak zistil pretecenie (????????????.FFFFFFFFFFFFFF??h [****]
void shl(int n); // mantisa <<= n [ normalize! ]
void shr(int n); // mantisa >>= n [ normalize! ]
void inci(); // this = sig (|this|+1)
void deci(); // this = sig (|this|-1)
void incf(); // this = sig (|this|+lsb)
void decf(); // this = sig (|this|-lsb)
void add(const arbnum &x,const arbnum &y); // this = |x|+|y| kazi sig !!! [ normalize! ]
void sub(const arbnum &x,const arbnum &y); // this = |x|-|y| ; |x|>=|y| kazi sig !!! [ normalize! ]
void mul(const arbnum &x,const arbnum &y); // this = |x|*|y| kazi sig !!! [ normalize! ]
void _mul_karatsuba(DWORD *dst,DWORD *x,DWORD *y,int n);
void mul_karatsuba(const arbnum &x,const arbnum &y);
void mul_NTT(const arbnum &x,const arbnum &y);
void sqr(const arbnum &x); // this = |x|*|x| kazi sig !!! [ normalize! ]
void sqr_NTT(const arbnum &x);
void div(const arbnum &x,const arbnum &y,int acc=-1); // this = |x|/|y| ; y = <0.5,1) kazi sig !!! [ normalize! ]
void div_binary(const arbnum &x,const arbnum &y);
int geq(const arbnum &x,const arbnum &y); // = |x|>=|y| ; 0 <, 1 >, 2==
int int_log2(int x)
{
if (x<=0) return 0;
int y=0,a=1;
for (;a<=x;a<<=1,y++); y--;
return y;
}
// friend arithmetics
friend arbnum integer (const arbnum &x); // = integer(x)
friend arbnum fraction(const arbnum &x); // = fraction(x)
friend arbnum round (const arbnum &x); // = round(x);
friend arbnum floor (const arbnum &x); // = floor(x)
friend arbnum ceil (const arbnum &x); // = ceil(x)
friend arbnum abs (const arbnum &x); // = |x|
friend arbnum sqrt (const arbnum &x); // = |x|^0.5
friend arbnum exp2 (const arbnum &x); // = 2^x
friend arbnum expe (const arbnum &x); // = e^x
friend arbnum exp10 (const arbnum &x); // = 10^x
friend arbnum log2 (const arbnum &x); // = log2(x)
friend arbnum loge (const arbnum &x); // = ln(x)
friend arbnum log10 (const arbnum &x); // = log10(x)
friend arbnum powi (const arbnum &x,const arbnum &y); // = x^int(y)
friend arbnum powi (const arbnum &x,int y); // = x^int(y)
friend arbnum pow (const arbnum &x,const arbnum &y); // = x^y
friend arbnum sin (const arbnum &x); // = sin(x)
friend arbnum cos (const arbnum &x); // = cos(x)
friend arbnum tan (const arbnum &x); // = tan(x)
friend arbnum cotan (const arbnum &x); // = cotan(x)
friend arbnum asin (const arbnum &x); // = asin(x)
friend arbnum acos (const arbnum &x); // = acos(x)
friend arbnum atan (const arbnum &x); // = atan(x)
friend arbnum acotan (const arbnum &x); // = acotan(x)
friend arbnum gcd (arbnum x,arbnum y); // = gcd (int(|x|),int(|y|)) binary greatest common divisor
friend arbnum fact (const DWORD &x); // = x! = (x/2)!^2 * mul[ p(i)^e(i) ]
friend arbnum fact_aprox(const DWORD &x); // ~ x!
};
//---------------------------------------------------------------------------
[笔记]
如果没有关于您的目标平台或军用格式的更多信息,就不可能决定哪种方法在速度、准确性方面更好。我们需要诸如尾数位/格式指数位/格式之类的信息,您是否可以使用FPU(以及哪种格式),您本机可以使用哪些浮点类型等。
在IEEE 754标准描述了浮点表示引擎盖下是如何工作的。