|
[ 簡単な説明 ]
MPA値設定用の関数は、実数を設定する m_set( )、整数を設定する m_set_l( )、文字列で設定する m_set_a( ) を準備していますが、実数の定数を設定する場合には、m_set( )よりも m_set_a( )の方が正確に設定できます。 m_round( )では、仮数部 int 型配列をn個分に丸めます。 |
| 関数プロトタイプ | 機能説明 | |
| MPA m_set(double a) | MPA値設定 | double → MPA |
| MPA m_set_a(char *s) | 文字列 → MPA | |
| MPA m_set_l(long n) | long int → MPA | |
| MPA m_int(MPA a) | 部分抽出 | 整数部 |
| MPA m_frac(MPA a) | 小数部 | |
| MPA m_round(MPA a, int n) | n 桁に丸め | |
/* m_set.c double --> MPA */
#include "mpa.h"
MPA m_set(double a)
{
MPA m;
int i;
UINT *p;
double t;
m = _M0;
if(a == 0.) return m;
m.zero = 0;
if(a < 0.)
{
m.sign = 0;
a = - a;
}
while(a >= (double)RADIX)
{
m.exp++;
a /= (double)RADIX;
}
while(a < 1.)
{
m.exp--;
a *= (double)RADIX;
}
p = m.num;
i = 0;
do
{
*p = (UINT)a;
a -= (double)*p++;
a *= (double)RADIX;
} while(a != 0. && ++i <= NMPA);
for(i++; i <= NMPA; i++) *p++ = 0;
return m;
}
/* m_set_a "xxx" --> MPA */
MPA m_set_a(char *s)
{
MPA a, t;
char *p;
int c, exp, i, pflag, sign, zflag;
UINT *q;
p = s;
sign = 1;
if(*p == '-')
{
sign = 0;
p++;
}else if(*p == '+') p++;
a = t = _M0;
t.zero = 0;
exp = 0;
pflag = zflag = 0;
for(; *p != '\0'; p++)
{
if(*p == '.')
{
if(pflag)
{
fprintf(stderr, "Error : Illegal parameter in m_set_a()\n");
return _M0;
}
pflag = 1;
}
else if(*p == 'E' || *p == 'e')
{
p++;
exp -= atoi(p);
break;
}
else if(*p == '+' || *p == '-')
{
exp -= atoi(p);
break;
}
else if(*p != ' ' && (*p < '0' || *p > '9'))
{
fprintf(stderr, "Error : Illegal parameter in m_set_a()\n");
return _M0;
}
else
{
c = *p - '0';
if(c != 0 || pflag != 0) zflag = -1;
else
{
if(zflag == 0) zflag = 1;
else if(zflag == 1)
{
fprintf(stderr, "Error : Illegal parameter in m_set_a()\n");
return _M0;
}
}
m_mul1_s(&a, 10);
if(c)
{
t.num[0] = c;
a = m_add(a, t);
/*
a = m_add_a(a, t);
*/
}
if(pflag == 1) exp++;
}
}
if(exp > MAXEXP)
{
fprintf(stderr, "Error : Overflow in m_set_a()\n");
return _MMAX;
}
if(exp < MINEXP)
{
fprintf(stderr, "Error : Underflow in m_set_a()\n");
return _M0;
}
a.sign = sign;
if(exp > 0) while(--exp >= 0) m_div1_s(&a, 10);
else while(++exp <= 0) m_mul1_s(&a, 10);
m_z_chk(&a);
return a;
}
/* m_set_l.c MPA <-- long */
MPA m_set_l(long n)
{
MPA a;
UINT *p, *q, w;
a = _M0;
if(n == 0L) return a;
a.zero = 0;
if(n < 0L)
{
a.sign = 0;
n = - n;
}
p = q = a.num;
while(n != 0)
{
*p++ = n % RADIX;
n /= RADIX;
a.exp++;
}
a.exp--;
p--;
while(q < p)
{
w = *p;
*p-- = *q;
*q++ = w;
}
return a;
}
/* m_int integer MPA --> MPA */
MPA m_int(MPA a)
{
int i;
if(a.zero || a.exp < 0) return _M0;
if(a.exp >= NMPA) return a;
for(i = a.exp + 1; i <= NMPA; i++) a.num[i] = 0;
return a;
}
/* m_frac MPA - integer MPA --> MPA */
MPA m_frac(MPA a)
{
MPA b;
UINT *p, *q;
int i;
if(a.zero || a.exp >= NMPA) return _M0;
if(a.exp < 0) return a;
b.zero = 0;
b.sign = a.sign;
b.exp = -1;
for(i = a.exp + 1, p = a.num + i, q = b.num; i <= NMPA; i++)
*q++ = *p++;
for(i = 0; i <= a.exp; i++) *q++ = 0;
return b;
}
/* m_round round(MPA, n) --> MPA */
MPA m_round(MPA a, int n)
{
MPA t;
char s[15];
sprintf(s, "+1.0e%d\0", n);
t = m_set_a(s);
return m_mul(m_int(m_add(m_div(a, t), m_set_a("0.5"))), t);
}
|