#include <stdio.h>
#include <string.h>
#define INFGR 0x7F800000
#define INFSM 0x00000000
typedef long MyFloat;
union FandL{
float f;
unsigned long l;
};
/*Transform a string with binary integer to a decimal integer*/
int atoi(char *s)
{
int res = 0, i;
for(i=0; i<32; i++)
{
res = res << 1;
res = res | s[i];
}
return res;
}
/*Transform a decimal number to a string with binary integer*/
char *itoa(int num, char *s)
{
unsigned int temp = 0x80000000;
int i;
for(i=0; i<32; i++)
{
if(num & temp)
s[i] = 1;
else
s[i] = 0;
temp = temp >> 1;
}
return s;
}
int iadd(int addend, int summand)
{
char a[32], b[32], res[32];
int i, result;
char c = 0;
unsigned int temp = 0x80000000;
itoa(addend, a);
itoa(summand, b);
for(i=31; i>=0; i--)
{
res[i] = a[i] ^ b[i] ^ c;
if(a[i]&b[i] || a[i]&c || b[i]&c)
c = 1;
else
c = 0;
}
result = atoi(res);
if((result & temp) && !(addend & temp) && !(summand & temp) || !(result & temp) && (addend & temp) && (summand & temp))
printf("Data overflow!!\n");
return result;
}
int isub(int minuend, int subtrahend)
{
int temp;
temp = iadd(~subtrahend, 1);
return iadd(minuend, temp);
}
/*Compare two integers, return 1 when a>b, return 0 when a==b, return -1 when a<b*/
int compare(int a, int b)
{
int c;
c = isub(a, b);
if(c & 0x80000000)
return -1;
else if(c == 0)
return 0;
else
return 1;
}
__int64 imul(int m, int n)
{
int mult = n;
__int64 res = 0, temp;
int k = m, nk, dk, ndk, i;
mult <<= 1;
nk = iadd(~k, 1);
dk = k << 1;
ndk = nk << 1;
for(i=0; i<16; i++)
{
temp = res & 0xFFFFFFFF00000000;
res = res & 0x00000000FFFFFFFF;
temp >>= 32;
switch(mult & 0x00000007)
{
case 0:
case 7: break;
case 1:
case 2: temp = iadd((int)temp, k);
break;
case 5:
case 6: temp = iadd((int)temp, nk);
break;
case 3: temp = iadd((int)temp, dk);
break;
case 4: temp = iadd((int)temp, ndk);
break;
}
res = res | (temp << 32);
res >>= 2;
mult >>= 2;
}
return res;
}
int idiv(int dividend, int divisor)
{
__int64 temp, remainder = 0;
int quotient = 0;
int ndivisor;
int i = 0;
char sign = 0;
if(!dividend)
return 0;
if((dividend & 0x80000000) ^ (divisor & 0x80000000))
sign = 1;
if(dividend & 0x80000000)
dividend = iadd(~dividend, 1);
if(divisor & 0x80000000)
divisor = iadd(~divisor, 1);
ndivisor = iadd(~divisor, 1);
remainder |= dividend;
remainder <<= 1;
temp = remainder & 0xFFFFFFFF00000000;
remainder &= 0x00000000FFFFFFFF;
temp >>= 32;
temp = iadd((int)temp, ndivisor);
while(i++ < 32)
{
quotient <<= 1;
if((temp & 0x0000000080000000) == 0)
quotient |= 0x00000001;
remainder |= (temp << 32);
remainder <<= 1;
temp = remainder & 0xFFFFFFFF00000000;
remainder &= 0x00000000FFFFFFFF;
temp >>= 32;
if((temp & 0x0000000080000000) == 0)
temp = iadd((int)temp, ndivisor);
else
temp = iadd((int)temp, divisor);
}
if(sign)
quotient = iadd(~quotient, 1);
return quotient;
}
int imod(int dividend, int divisor)
{
__int64 temp, remainder = 0;
int ndivisor;
int i = 0;
if(dividend & 0x80000000)
dividend = iadd(~dividend, 1);
if(divisor & 0x80000000)
divisor = iadd(~divisor, 1);
ndivisor = iadd(~divisor, 1);
remainder |= dividend;
remainder <<= 1;
temp = remainder & 0xFFFFFFFF00000000;
remainder &= 0x00000000FFFFFFFF;
temp >>= 32;
temp = iadd((int)temp, ndivisor);
while(i++ < 31)
{
remainder |= (temp << 32);
remainder <<= 1;
temp = remainder & 0xFFFFFFFF00000000;
remainder &= 0x00000000FFFFFFFF;
temp >>= 32;
if((temp & 0x0000000080000000) == 0)
temp = iadd((int)temp, ndivisor);
else
temp = iadd((int)temp, divisor);
}
if(temp & 0x0000000080000000)
temp = iadd((int)temp, divisor);
remainder |= temp << 32;
remainder >>= 32;
return (int)remainder;
}
void Int_To_Bina(char* Binary, char* Integer)
{
int remainder, temp, i, II = 0, k, len = strlen(Integer);
while(1){
remainder = 0;
i = 0;
while(Integer[i] != '\0'){
temp = iadd((int)imul(remainder, 10), isub(Integer[i], '0'));
Integer[i++] = iadd(idiv(temp, 2), '0');
remainder = imod(temp, 2);
}
Binary[II++] = iadd(remainder, '0');
for(k=0; k<len; k++)
if(Integer[k] != '0')
break;
if(k == len)
break;
}
Binary[II] = '\0';
i = isub(strlen(Binary), 1);
for(II=0; II<=(i>>1); II++){
temp = Binary[II];
Binary[II] = Binary[isub(i,II)];
Binary[isub(i,II)] = temp;
}
}
void Float_To_Bina(char* FBinary, char* Float)
{
int i, k=0, carry, temp;
int len = strlen(Float);
while(k<150){
carry = 0;
for(i=len-1; i>=0; i--){
temp = iadd((int)imul(isub(Float[i], '0'), 2), carry);
Float[i] = imod(temp, 10) + '0';
carry = idiv(temp, 10);
}
FBinary[k++] = iadd(carry, '0');
}
FBinary[k] = '\0';
}
MyFloat atof(char *s)
{
char Integer[39], Float[39], Binary[279], FBinary[151];
char sign = 0, Find_Dot = 0;
int i=0, II=0, FF=0, lenI, power=0, len;
MyFloat result = 0;
if(s[i] == '-'){
sign = 1;
i++;
}
while(s[i] != '\0'){
if(s[i] == '.'){
Find_Dot = 1;
i++;
continue;
}
if(!Find_Dot)
Integer[II++] = s[i++];
else
Float[FF++] = s[i++];
}
Integer[II] = '\0';
Float[FF] = '\0';
if(!II)
strcpy(Integer, "0");
if(!FF)
strcpy(Float, "0");
Int_To_Bina(Binary, Integer);
Float_To_Bina(FBinary, Float);
lenI = strlen(Binary);
strcat(Binary, FBinary);
len = strlen(Binary);
for(i=0; i<len; i++)
if(Binary[i] == '1')
break;
if(i==len)
return 0;
power = isub(isub(lenI, i), 1);
for(II=0; II<23; II++){
result <<= 1;
if(Binary[++i] == '1')
result |= 1;
}
if(Binary[++i] == '1') /*????*/
result = iadd(result, 1);
if(sign)
result |= 0x80000000;
result |= iadd(power, 127) << 23;
return result;
}
char *Power_Gre_Zero(char *res, long power){
int i, k, carry, temp;
for(i=0; i<power; i++){
carry = 0;
for(k=39; k>0; k--){
temp = iadd((int)imul(isub(res[k], '0'), 2), carry);
res[k] = iadd(imod(temp, 10), '0');
carry = idiv(temp, 10);
}
}
res[40] = '\0';
strcat(res, ".000000");
return res;
}
char *Power_Les_Zero(char *res, long power){
int k, i, temp, remainder, carry;
power = iadd(~power, 1);
res[40] = '\0';
strcat(res, ".0000000");
for(k=0; k<power; k++){
remainder = 0;
for(i=1; i<48; i++){
if(res[i] == '.')
continue;
temp = iadd((int)imul(remainder, 10), isub(res[i], '0'));
res[i] = iadd(idiv(temp, 2), '0');
remainder = imod(temp, 2);
}
}
if(res[47] - '0' >= 5){
carry = 1;
for(i=46; i>25; i--){
res[i] = iadd(res[i], carry);
carry = 0;
if(res[i] - '0' > 9){
res[i] = '0';
carry = 1;
}
}
}
res[47] = '\0';
return res;
}
char *ftoa(MyFloat f, char *s)
{
char res[49];
unsigned long tail=0;
long temp=0;
int i, k=0;
long power=(f&0x7F800000)>>23;
if(power==255){
strcpy(s,"1.#INF00");
return s;
}
if(power<=105){
strcpy(s,"0.000000");
return s;
}
for(i=0; i<48; i++)
res[i] = '0';
tail = f & 0x007FFFFF;
tail |= 0x00800000;
for(i=0; i<24; i++){
temp = (int)imul(temp, 2);
if(tail & 0x00800000)
temp = iadd(temp, 1);
tail <<= 1;
}
for(i=39; i>31; i--){
res[i] = iadd(imod(temp, 10), '0');
temp = idiv(temp, 10);
}
res[48] = '\0';
power -= 150;
if(power < 0)
strcpy(s, Power_Les_Zero(res, power));
else
strcpy(s, Power_Gre_Zero(res, power));
if(f & 0x80000000){
s[0] = '-';
k = 1;
}
for(i=1; i<39; i++)
if(s[i] != '0')
break;
while(i<49)
s[k++] = s[i++];
s[47] = '\0';
return s;
}
MyFloat fadd(MyFloat addend, MyFloat summand)
{
MyFloat _Addend, _Summand, Greater, Small