📄 float.java
字号:
}
//
if (v1 > 0 && v2 > Long.MAX_VALUE - v1)
return new Float(ERROR);
else if (v1 < 0 && v2 < Long.MIN_VALUE - v1)
return new Float(ERROR);
//
return new Float(v1 + v2, e1);
}
/**
* Subtract value of argument from value of current Float object and return
* as new Float object
*
* @param value
* Float - argument
* @return Float - current-value
*/
public Float Sub(Float value) {
if (value.Equal(ZERO))
return new Float(m_Val, m_E);
return Add(new Float(-value.m_Val, value.m_E));
}
/**
* Divide value of current Float object on argument and return as new Float
* object
*
* @param value
* Float - argument
* @return Float - current/value
*/
public Float Mul(long value) {
return Mul(new Float(value, 0));
}
/**
* Multiply value of current Float object on argument and return as new
* Float object
*
* @param value
* Float - argument
* @return Float - current*value
*/
public Float Mul(Float value) {
if (value.Equal(ZERO) || this.Equal(ZERO))
return new Float(ZERO);
if (value.Equal(ONE))
return new Float(this);
//
boolean negative1 = (m_Val < 0);
if (negative1)
m_Val = -m_Val;
boolean negative2 = (value.m_Val < 0);
if (negative2)
value.m_Val = -value.m_Val;
// Check overflow and underflow
do {
if (value.m_Val > m_Val) {
if (Long.MAX_VALUE / m_Val < value.m_Val) {
value.m_Val /= 10;
value.m_E++;
} else
break;
} else {
if (Long.MAX_VALUE / value.m_Val < m_Val) {
m_Val /= 10;
m_E++;
} else
break;
}
} while (true);
//
if (negative1)
m_Val = -m_Val;
if (negative2)
value.m_Val = -value.m_Val;
//
long e = m_E + value.m_E;
long v = m_Val * value.m_Val;
return new Float(v, e);
}
/**
* Divide value of current Float object on argument and return as new Float
* object
*
* @param value
* Float - argument
* @return Float - current/value
*/
public Float Div(long value) {
return Div(new Float(value, 0));
}
/**
* Divide value of current Float object on argument and return as new Float
* object
*
* @param value
* Float - argument
* @return Float - current/value
*/
public Float Div(Float value) {
if (value.Equal(ONE))
return new Float(this);
//
long e1 = m_E;
long e2 = value.m_E;
long v2 = value.m_Val;
if (v2 == 0L)
return new Float(ERROR);
long v1 = m_Val;
if (v1 == 0L)
return new Float(ZERO);
//
long val = 0L;
while (true) {
val += (v1 / v2);
v1 %= v2;
if (v1 == 0L || Math.abs(val) > (Long.MAX_VALUE / 10L))
break;
if (Math.abs(v1) > (Long.MAX_VALUE / 10L)) {
v2 /= 10L;
e2++;
} else {
v1 *= 10L;
e1--;
}
val *= 10L;
}
//
Float f = new Float(val, e1 - e2);
f.RemoveZero();
return f;
}
private void RemoveZero() {
if (m_Val == 0)
return;
while (m_Val % 10 == 0) {
m_Val /= 10;
m_E++;
}
}
/**
* Is value of current Float object greater?
*
* @param x
* Float - argument
* @return boolean - true-if current value is greater x, false-if not
*/
private boolean Great(Float x) {
long e1 = m_E;
long e2 = x.m_E;
long v1 = m_Val;
long v2 = x.m_Val;
//
while (e1 != e2) {
if (e1 > e2) {
if (Math.abs(v1) < maxLimit) {
v1 *= 10;
e1--;
} else {
v2 /= 10;
e2++;
}
} else if (e1 < e2) {
if (Math.abs(v2) < maxLimit) {
v2 *= 10;
e2--;
} else {
v1 /= 10;
e1++;
}
}
}
//
return v1 > v2;
}
/**
* Is value of current Float object less?
*
* @param x
* Float - argument
* @return boolean - true-if current value is less x, false-if not
*/
private boolean Less(long x) {
return Less(new Float(x, 0));
}
/**
* Is value of current Float object less?
*
* @param x
* Float - argument
* @return boolean - true-if current value is less x, false-if not
*/
public boolean Less(Float x) {
long e1 = m_E;
long e2 = x.m_E;
long v1 = m_Val;
long v2 = x.m_Val;
//
while (e1 != e2) {
if (e1 > e2) {
if (Math.abs(v1) < maxLimit) {
v1 *= 10;
e1--;
} else {
v2 /= 10;
e2++;
}
} else if (e1 < e2) {
if (Math.abs(v2) < maxLimit) {
v2 *= 10;
e2--;
} else {
v1 /= 10;
e1++;
}
}
}
//
return v1 < v2;
}
/**
* Equal with current Float object?
*
* @param x
* Float - argument
* @return boolean - true-if equal, false-if not
*/
private boolean Equal(Float x) {
long e1 = m_E;
long e2 = x.m_E;
long v1 = m_Val;
long v2 = x.m_Val;
//
if ((v1 == 0 && v2 == 0) || (v1 == v2 && e1 == e2))
return true;
// Values with exponent differences more than 20 times never could be
// equal
/*
* if(Math.abs(e1-e2)>20) return false;
*/
long diff = e1 - e2;
if (diff < -20 || diff > 20)
return false;
//
while (e1 != e2) {
if (e1 > e2) {
if (Math.abs(v1) < maxLimit) {
v1 *= 10;
e1--;
} else {
v2 /= 10;
e2++;
}
} else if (e1 < e2) {
if (Math.abs(v2) < maxLimit) {
v2 *= 10;
e2--;
} else {
v1 /= 10;
e1++;
}
}
}
//
return (v1 == v2);
}
/**
* Reverse sign of value in current Float object and return as new Float
* object
*
* @return Float - new Float object
*/
private Float Neg() {
return new Float(-m_Val, m_E);
}
/**
* Returns the trigonometric sine of an angle. Special cases: If the
* argument is NaN or an infinity, then the result is NaN. If the argument
* is zero, then the result is a zero with the same sign as the argument. A
* result must be within 1 ulp of the correctly rounded result. Results must
* be semi-monotonic
*
* @param x
* Float - an angle, in radians
* @return Float - the sine of the argument
*/
private static Float sin(Float x) {
while (x.Great(PI))
x = x.Sub(PImul2);
while (x.Less(PI.Neg()))
x = x.Add(PImul2);
// x*x*x
Float m1 = x.Mul(x.Mul(x));
Float q1 = m1.Div(6L);
// x*x*x*x*x
Float m2 = x.Mul(x.Mul(m1));
Float q2 = m2.Div(120L);
// x*x*x*x*x*x*x
Float m3 = x.Mul(x.Mul(m2));
Float q3 = m3.Div(5040L);
// x*x*x*x*x*x*x*x*x
Float m4 = x.Mul(x.Mul(m3));
Float q4 = m4.Div(362880L);
// x*x*x*x*x*x*x*x*x*x*x
Float m5 = x.Mul(x.Mul(m4));
Float q5 = m5.Div(39916800L);
//
Float result = x.Sub(q1).Add(q2).Sub(q3).Add(q4).Sub(q5);
// 1e-6
if (result.Less(new Float(-999999, -6)))
return new Float(-1L);
// 1e-6
if (result.Great(new Float(999999, -6)))
return new Float(1L);
// 5e-4
if (result.Great(new Float(-5, -4)) && result.Less(new Float(5, -4)))
return new Float(0L);
//
return result;
}
/**
* Returns the trigonometric cosine of an angle. Special cases: If the
* argument is NaN or an infinity, then the result is NaN. A result must be
* within 1 ulp of the correctly rounded result. Results must be
* semi-monotonic
*
* @param x
* Float - an angle, in radians
* @return Float - the cosine of the argument
*/
private static Float cos(Float x) {
while (x.Great(PI))
x = x.Sub(PImul2);
while (x.Less(PI.Neg()))
x = x.Add(PImul2);
// x*x
Float m1 = x.Mul(x);
Float q1 = m1.Div(2L);
// x*x*x*x
Float m2 = m1.Mul(m1);
Float q2 = m2.Div(24L);
// x*x*x*x*x*x
Float m3 = m1.Mul(m2);
Float q3 = m3.Div(720L);
// x*x*x*x*x*x*x*x
Float m4 = m2.Mul(m2);
Float q4 = m4.Div(40320L);
// x*x*x*x*x*x*x*x*x*x
Float m5 = m4.Mul(m1);
Float q5 = m5.Div(3628800L);
Float result = ONE.Sub(q1).Add(q2).Sub(q3).Add(q4).Sub(q5);
// 1e-6
if (result.Less(new Float(-999999, -6)))
return new Float(-1L);
// 1e-6
if (result.Great(new Float(999999, -6)))
return new Float(1L);
// 5e-4
if (result.Great(new Float(-5, -4)) && result.Less(new Float(5, -4)))
return new Float(0L);
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -