To convert BCD to/from double, the following code-piece
could be used. Refer to NumberFormat
for further details.
#include "math.h"
typedef struct{
unsigned char hnibble:4;
unsigned char lnibble:4;
} TBCDbyte;
typedef struct{
unsigned short
exponent:12;
unsigned short
mantissa0:4;
TBCDbyte mantissa[7];
char flags;
short info;
} TBCDvalue;
typedef struct{
int exponent;
int sign;
int unknown;
char mantissa[15];
} TBCDInternal;
////////// TBCD //////////
class TBCD{
public:
TBCDvalue*PValue();
int Get(
TBCDvalue&value );
int Set(
TBCDvalue&value );
int Set(
double&value );
int Get(
double&value );
int SetError(
int error );
int GetError();
void Swap();
protected:
private:
TBCDvalue FValue[2];
};
//
TBCDvalue*TBCD::PValue(){
return FValue;
};
//
int TBCD::Get(
TBCDvalue&value ){
int result = 0;
memcpy( &value, &FValue,
sizeof( TBCDvalue )
);
return result;
};
//
int TBCD::Set(
TBCDvalue&value ){
int result = 0;
memcpy( &FValue, &value,
sizeof( TBCDvalue )
);
return result;
};
//
int TBCD::Set(
double&value ){
int result=0;
double dwork;
double dwork2;
int iexponent;
int i;
memset( FValue, 0,
sizeof( TBCDvalue
) );
iexponent = 100;
dwork = value;
if ( dwork <
0 ){
iexponent += 500;
dwork = -dwork;
};
while ( dwork >=
10 ){
iexponent+=1;
dwork = dwork / 10;
};
while ( dwork <
1 ){
iexponent-=1;
dwork = dwork * 10;
};
FValue[0].exponent
= ( iexponent / 100
);
iexponent = iexponent - ( iexponent /
100 ) *
100;
FValue[0].exponent
<<= 4;
FValue[0].exponent
+= ( iexponent / 10
);
FValue[0].exponent
<<= 4;
iexponent = iexponent - ( iexponent /
10 ) *
10;
FValue[0].exponent
+= iexponent;
dwork = modf( dwork, &dwork2 )
* 10;
FValue[0].mantissa0
= floor( dwork2 );
for ( i =
0; i < 7;i++
){
dwork = modf(
dwork, &dwork2 ) * 10;
FValue[0].mantissa[i].hnibble
= dwork2;
dwork = modf(
dwork, &dwork2 ) * 10;
FValue[0].mantissa[i].lnibble
= dwork2;
}
return result;
};
//
int TBCD::Get(
double&value ){
int result=0;
int i;
double factor = 1;
TBCDInternal work;
BCDtoInternal( &work, FValue );
// syscall 0x500
value = work.mantissa[0];
for (i=1;i<15;i++){
factor /= 10;
if
(work.mantissa[i]){
value += factor * work.mantissa[i];
};
};
while ( work.exponent++
< 0 ){ value /=
10;};
while ( --work.exponent
> 0 ){ value *=
10;};
value *= work.sign;
return result;
};
//
int TBCD::SetError(
int error ){
int result=(FValue[0].exponent
& 0xF00)>>4;
FValue[0].exponent
= ( FValue[0].exponent
& 0xFF ) |
( error << 4
);
return result;
};
//
int TBCD::GetError(){
int result=(FValue[0].exponent
& 0xF00)>>4;
return result;
};
//
void TBCD::Swap(){
TBCDvalue work;
FValue[0]
= FValue[1];
FValue[1]
= work;
};
(12.05.2012 14:52:20)