1 4 package gnu.math; 5 import java.math.BigDecimal ; 6 7 public abstract class RealNum extends Complex 8 9 implements Comparable 10 11 { 12 public final RealNum re() { return this; } 13 public final RealNum im() { return IntNum.zero(); } 14 15 public abstract boolean isNegative (); 16 17 18 public abstract int sign (); 19 20 public RealNum max (RealNum x) 21 { 22 boolean exact = isExact () && x.isExact (); 23 RealNum result = grt (x) ? this : x; 24 if (!exact && result.isExact ()) 25 result = new DFloNum (result.doubleValue ()); 26 return result; 27 } 28 29 public RealNum min (RealNum x) 30 { 31 boolean exact = isExact () && x.isExact (); 32 RealNum result = grt (x) ? x : this; 33 if (!exact && result.isExact ()) 34 result = new DFloNum (result.doubleValue ()); 35 return result; 36 } 37 38 public static RealNum add (RealNum x, RealNum y, int k) 39 { 40 return (RealNum)(x.add(y, k)); 41 } 42 43 public static RealNum times(RealNum x, RealNum y) 44 { 45 return (RealNum)(x.mul(y)); 46 } 47 48 public static RealNum divide (RealNum x, RealNum y) 49 { 50 return (RealNum)(x.div(y)); 51 } 52 53 54 public abstract Numeric add (Object obj, int k); 55 public abstract Numeric mul (Object obj); 56 public abstract Numeric div (Object obj); 57 58 public Numeric abs () 59 { 60 return isNegative () ? neg () : this; 61 } 62 63 public final RealNum rneg() { return (RealNum) neg(); } 64 65 public boolean isZero () 66 { 67 return sign () == 0; 68 } 69 70 73 public RatNum toExact () 74 { 75 return DFloNum.toExact (doubleValue ()); 76 } 77 78 81 public static double toInt (double d, int rounding_mode) 82 { 83 switch (rounding_mode) 84 { 85 case FLOOR: 86 return Math.floor(d); 87 case CEILING: 88 return Math.ceil(d); 89 case TRUNCATE: 90 return d < 0.0 ? Math.ceil (d) : Math.floor (d); 91 case ROUND: 92 return Math.rint(d); 93 default: return d; 95 } 96 } 97 98 101 public RealNum toInt (int rounding_mode) 102 { 103 return new DFloNum(toInt(doubleValue(), rounding_mode)); 104 } 105 106 107 public IntNum toExactInt (int rounding_mode) 108 { 109 return toExactInt(doubleValue(), rounding_mode); 110 } 111 112 113 public static IntNum toExactInt (double value, int rounding_mode) 114 { 115 return toExactInt(toInt(value, rounding_mode)); 116 } 117 118 119 public static IntNum toExactInt (double value) 120 { 121 if (Double.isInfinite (value) || Double.isNaN (value)) 122 throw new ArithmeticException ("cannot convert "+value+" to exact integer"); 123 long bits = Double.doubleToLongBits (value); 124 boolean neg = bits < 0; 125 int exp = (int) (bits >> 52) & 0x7FF; 126 bits &= 0xfffffffffffffL; 127 if (exp == 0) 128 bits <<= 1; 129 else 130 bits |= 0x10000000000000L; 131 if (exp <= 1075) 132 { 133 int rshift = 1075 - exp; 134 if (rshift > 53) 135 return IntNum.zero(); 136 bits >>= rshift; 137 return IntNum.make (neg ? -bits : bits); 138 } 139 return IntNum.shift (IntNum.make (neg ? -bits : bits), exp - 1075); 140 } 141 142 public Complex exp () 143 { 144 return new DFloNum(Math.exp(doubleValue())); 145 } 146 147 public Complex log () 148 { 149 double x = doubleValue(); 150 if (x < 0) 151 return DComplex.log(x, 0.0); 152 return new DFloNum(Math.log(x)); 153 } 154 155 public final Complex sin() { return new DFloNum(Math.sin(doubleValue())); } 156 157 public final Complex sqrt () 158 { 159 double d = doubleValue(); 160 if (d >= 0) 161 return new DFloNum(Math.sqrt(d)); 162 else 163 return DComplex.sqrt(d, 0); 164 } 165 166 167 public static IntNum toScaledInt (double f, int k) 168 { 169 return toScaledInt(DFloNum.toExact(f), k); 170 } 171 172 173 public static IntNum toScaledInt (RatNum r, int k) 174 { 175 if (k != 0) 176 { 177 IntNum power = IntNum.power(IntNum.ten(), k < 0 ? -k : k); 178 IntNum num = r.numerator(); 179 IntNum den = r.denominator(); 180 if (k >= 0) 181 num = IntNum.times(num, power); 182 else 183 den = IntNum.times(den, power); 184 r = RatNum.make(num, den); 185 } 186 return r.toExactInt(ROUND); 187 } 188 189 190 public IntNum toScaledInt (int k) 191 { 192 return toScaledInt(toExact(), k); 193 } 194 195 209 210 214 public int compareTo(Object o) 215 { 216 return compare(o); 217 } 218 219 public java.math.BigDecimal asBigDecimal () 220 { 221 return new BigDecimal (doubleValue()); 222 } 223 224 public static String toStringScientific (float d) 225 { 226 return toStringScientific(Float.toString(d)); 227 } 228 229 public static String toStringScientific (double d) 230 { 231 return toStringScientific(Double.toString(d)); 232 } 233 234 238 public static String toStringScientific (String dstr) 239 { 240 int indexE = dstr.indexOf('E'); 241 if (indexE >= 0) 242 return dstr; 243 int len = dstr.length(); 244 char ch = dstr.charAt(len-1); 246 if (ch == 'y' || ch == 'N') 247 return dstr; 248 StringBuffer sbuf = new StringBuffer (len+10); 249 int exp = toStringScientific(dstr, sbuf); 250 sbuf.append('E'); 251 sbuf.append(exp); 252 return sbuf.toString(); 253 } 254 255 public static int toStringScientific (String dstr, StringBuffer sbuf) 256 { 257 boolean neg = dstr.charAt(0) == '-'; 258 if (neg) 259 sbuf.append('-'); 260 int pos = neg ? 1 : 0; 261 int exp; 262 int len = dstr.length(); 263 if (dstr.charAt(pos) == '0') 264 { int start = pos; 266 for (;;) 267 { 268 if (pos == len) 269 { 270 sbuf.append("0"); 271 exp = 0; 272 break; 273 } 274 char ch = dstr.charAt(pos++); 275 if (ch >= '0' && ch <= '9' && (ch != '0' || pos == len)) 276 { 277 sbuf.append(ch); 278 sbuf.append('.'); 279 exp = ch == '0' ? 0 : start - pos + 2; 280 if (pos == len) 281 sbuf.append('0'); 282 else 283 { 284 while (pos < len) 285 sbuf.append(dstr.charAt(pos++)); 286 } 287 break; 288 } 289 } 290 } 291 else 292 { 293 int ndigits = len - (neg ? 2 : 1); 295 int dot = dstr.indexOf('.'); 296 exp = ndigits - len + dot; 301 sbuf.append(dstr.charAt(pos++)); sbuf.append('.'); 303 while (pos < len) 304 { 305 char ch = dstr.charAt(pos++); 306 if (ch != '.') 307 sbuf.append(ch); 308 } 309 } 310 pos = sbuf.length(); 312 int slen = -1; 313 for (;;) 314 { 315 char ch = sbuf.charAt(--pos); 316 if (ch == '0') 317 slen = pos; 318 else 319 { 320 if (ch == '.') 321 slen = pos + 2; 322 break; 323 } 324 } 325 if (slen >= 0) 326 sbuf.setLength(slen); 327 return exp; 328 } 329 330 public static String toStringDecimal (String dstr) 331 { 332 int indexE = dstr.indexOf('E'); 333 if (indexE < 0) 334 return dstr; 335 int len = dstr.length(); 336 char ch = dstr.charAt(len-1); 338 if (ch == 'y' || ch == 'N') 339 return dstr; 340 StringBuffer sbuf = new StringBuffer (len+10); 341 boolean neg = dstr.charAt(0) == '-'; 342 if (dstr.charAt(indexE+1) != '-') 343 { 344 throw new Error ("not implemented: toStringDecimal given non-negative exponent: "+dstr); 345 } 346 else 347 { 348 int pos = indexE+2; int exp = 0; 350 while (pos < len) 351 exp = 10 * exp + (dstr.charAt(pos++) - '0'); 352 if (neg) 353 sbuf.append('-'); 354 sbuf.append("0."); 355 while (--exp > 0) sbuf.append('0'); 356 for (pos = 0; (ch = dstr.charAt(pos++)) != 'E'; ) 357 { 358 if (ch != '-' & ch != '.' 359 && (ch != '0' || pos < indexE)) 360 sbuf.append(ch); 361 } 362 return sbuf.toString(); 363 } 364 } 365 } 366 | Popular Tags |