23 Ocak 2009, Cuma
En iyi Java bir kısmını temsil edecek şekilde?
Java fractions ile çalışıyorum.
Aritmetik fonksiyonları uygulamak istiyorum. Bunun için öncelikle fonksiyonları normale döndürmek için bir yol lazım. Ortak payda kadar 1/6 ve 1/2 ekleyin edemeyeceğimi biliyorum. Ve 1/6 3/6 eklemek zorunda kalacağım. Naif bir yaklaşım beni ve 2/12 6/12 ekleyin ve sonra azaltmak gerekir. Ne kadar az performans ceza ile ortak bir payda elde edebilirsiniz? Ne algoritması en iyi Bu?
Sürüm 8 (hstoerr sayesinde):
Geliştirmeler
- equals() yöntemi şimdi compareTo ile tutarlıdır() yöntemi
final class Fraction extends Number {
private int numerator;
private int denominator;
public Fraction(int numerator, int denominator) {
if(denominator == 0) {
throw new IllegalArgumentException("denominator is zero");
}
if(denominator < 0) {
numerator *= -1;
denominator *= -1;
}
this.numerator = numerator;
this.denominator = denominator;
}
public Fraction(int numerator) {
this.numerator = numerator;
this.denominator = 1;
}
public int getNumerator() {
return this.numerator;
}
public int getDenominator() {
return this.denominator;
}
public byte byteValue() {
return (byte) this.doubleValue();
}
public double doubleValue() {
return ((double) numerator)/((double) denominator);
}
public float floatValue() {
return (float) this.doubleValue();
}
public int intValue() {
return (int) this.doubleValue();
}
public long longValue() {
return (long) this.doubleValue();
}
public short shortValue() {
return (short) this.doubleValue();
}
public boolean equals(Fraction frac) {
return this.compareTo(frac) == 0;
}
public int compareTo(Fraction frac) {
long t = this.getNumerator() * frac.getDenominator();
long f = frac.getNumerator() * this.getDenominator();
int result = 0;
if(t>f) {
result = 1;
}
else if(f>t) {
result = -1;
}
return result;
}
}
Önceki tüm sürümleri kaldırdık. Teşekkür için:
CEVAP
23 Ocak 2009, Cuma
- 27**;
- canonical, 6/4 olur 3/2 (greatest common divisor algoritma Bu için yararlıdır) anlam;
- Bu Rasyonel, rational number; bir temsil ediyorsunuz ne zamandan beri Ara
BigInteger
arbitrarilyy-hassas değerlerini depolamak için kullanabilirsiniz. Eğer değilse o zaman daha kolay bir uygulama olanlong
,;- Payda her zaman pozitif olun. İşaret pay tarafından yapılmalıdır;
- 32*; *uzatmak
- 33**; uygular
equals()
uygulamakhashCode()
;- Bir numara
String
; temsil ettiği için fabrika yöntemi ekleyin - Bazı kolaylık ekleyin fabrika yöntemleri;
- 36**;.
Serializable
.
Aslında, şunu bir dene bakalım. Çalışır ama bazı sorunları olabilir:
public class BigRational extends Number implements Comparable<BigRational>, Serializable {
public final static BigRational ZERO = new BigRational(BigInteger.ZERO, BigInteger.ONE);
private final static long serialVersionUID = 1099377265582986378L;
private final BigInteger numerator, denominator;
private BigRational(BigInteger numerator, BigInteger denominator) {
this.numerator = numerator;
this.denominator = denominator;
}
private static BigRational canonical(BigInteger numerator, BigInteger denominator, boolean checkGcd) {
if (denominator.signum() == 0) {
throw new IllegalArgumentException("denominator is zero");
}
if (numerator.signum() == 0) {
return ZERO;
}
if (denominator.signum() < 0) {
numerator = numerator.negate();
denominator = denominator.negate();
}
if (checkGcd) {
BigInteger gcd = numerator.gcd(denominator);
if (!gcd.equals(BigInteger.ONE)) {
numerator = numerator.divide(gcd);
denominator = denominator.divide(gcd);
}
}
return new BigRational(numerator, denominator);
}
public static BigRational getInstance(BigInteger numerator, BigInteger denominator) {
return canonical(numerator, denominator, true);
}
public static BigRational getInstance(long numerator, long denominator) {
return canonical(new BigInteger("" numerator), new BigInteger("" denominator), true);
}
public static BigRational getInstance(String numerator, String denominator) {
return canonical(new BigInteger(numerator), new BigInteger(denominator), true);
}
public static BigRational valueOf(String s) {
Pattern p = Pattern.compile("(-?\\d )(?:.(\\d )?)?0*(?:e(-?\\d ))?");
Matcher m = p.matcher(s);
if (!m.matches()) {
throw new IllegalArgumentException("Unknown format '" s "'");
}
// this translates 23.123e5 to 25,123 / 1000 * 10^5 = 2,512,300 / 1 (GCD)
String whole = m.group(1);
String decimal = m.group(2);
String exponent = m.group(3);
String n = whole;
// 23.123 => 23123
if (decimal != null) {
n = decimal;
}
BigInteger numerator = new BigInteger(n);
// exponent is an int because BigInteger.pow() takes an int argument
// it gets more difficult if exponent needs to be outside {-2 billion,2 billion}
int exp = exponent == null ? 0 : Integer.valueOf(exponent);
int decimalPlaces = decimal == null ? 0 : decimal.length();
exp -= decimalPlaces;
BigInteger denominator;
if (exp < 0) {
denominator = BigInteger.TEN.pow(-exp);
} else {
numerator = numerator.multiply(BigInteger.TEN.pow(exp));
denominator = BigInteger.ONE;
}
// done
return canonical(numerator, denominator, true);
}
// Comparable
public int compareTo(BigRational o) {
// note: this is a bit of cheat, relying on BigInteger.compareTo() returning
// -1, 0 or 1. For the more general contract of compareTo(), you'd need to do
// more checking
if (numerator.signum() != o.numerator.signum()) {
return numerator.signum() - o.numerator.signum();
} else {
// oddly BigInteger has gcd() but no lcm()
BigInteger i1 = numerator.multiply(o.denominator);
BigInteger i2 = o.numerator.multiply(denominator);
return i1.compareTo(i2); // expensive!
}
}
public BigRational add(BigRational o) {
if (o.numerator.signum() == 0) {
return this;
} else if (numerator.signum() == 0) {
return o;
} else if (denominator.equals(o.denominator)) {
return new BigRational(numerator.add(o.numerator), denominator);
} else {
return canonical(numerator.multiply(o.denominator).add(o.numerator.multiply(denominator)), denominator.multiply(o.denominator), true);
}
}
public BigRational multiply(BigRational o) {
if (numerator.signum() == 0 || o.numerator.signum( )== 0) {
return ZERO;
} else if (numerator.equals(o.denominator)) {
return canonical(o.numerator, denominator, true);
} else if (o.numerator.equals(denominator)) {
return canonical(numerator, o.denominator, true);
} else if (numerator.negate().equals(o.denominator)) {
return canonical(o.numerator.negate(), denominator, true);
} else if (o.numerator.negate().equals(denominator)) {
return canonical(numerator.negate(), o.denominator, true);
} else {
return canonical(numerator.multiply(o.numerator), denominator.multiply(o.denominator), true);
}
}
public BigInteger getNumerator() { return numerator; }
public BigInteger getDenominator() { return denominator; }
public boolean isInteger() { return numerator.signum() == 0 || denominator.equals(BigInteger.ONE); }
public BigRational negate() { return new BigRational(numerator.negate(), denominator); }
public BigRational invert() { return canonical(denominator, numerator, false); }
public BigRational abs() { return numerator.signum() < 0 ? negate() : this; }
public BigRational pow(int exp) { return canonical(numerator.pow(exp), denominator.pow(exp), true); }
public BigRational subtract(BigRational o) { return add(o.negate()); }
public BigRational divide(BigRational o) { return multiply(o.invert()); }
public BigRational min(BigRational o) { return compareTo(o) <= 0 ? this : o; }
public BigRational max(BigRational o) { return compareTo(o) >= 0 ? this : o; }
public BigDecimal toBigDecimal(int scale, RoundingMode roundingMode) {
return isInteger() ? new BigDecimal(numerator) : new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode);
}
// Number
public int intValue() { return isInteger() ? numerator.intValue() : numerator.divide(denominator).intValue(); }
public long longValue() { return isInteger() ? numerator.longValue() : numerator.divide(denominator).longValue(); }
public float floatValue() { return (float)doubleValue(); }
public double doubleValue() { return isInteger() ? numerator.doubleValue() : numerator.doubleValue() / denominator.doubleValue(); }
@Override
public String toString() { return isInteger() ? String.format("%,d", numerator) : String.format("%,d / %,d", numerator, denominator); }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BigRational that = (BigRational) o;
if (denominator != null ? !denominator.equals(that.denominator) : that.denominator != null) return false;
if (numerator != null ? !numerator.equals(that.numerator) : that.numerator != null) return false;
return true;
}
@Override
public int hashCode() {
int result = numerator != null ? numerator.hashCode() : 0;
result = 31 * result (denominator != null ? denominator.hashCode() : 0);
return result;
}
public static void main(String args[]) {
BigRational r1 = BigRational.valueOf("3.14e4");
BigRational r2 = BigRational.getInstance(111, 7);
dump("r1", r1);
dump("r2", r2);
dump("r1 r2", r1.add(r2));
dump("r1 - r2", r1.subtract(r2));
dump("r1 * r2", r1.multiply(r2));
dump("r1 / r2", r1.divide(r2));
dump("r2 ^ 2", r2.pow(2));
}
public static void dump(String name, BigRational r) {
System.out.printf("%s = %s%n", name, r);
System.out.printf("%s.negate() = %s%n", name, r.negate());
System.out.printf("%s.invert() = %s%n", name, r.invert());
System.out.printf("%s.intValue() = %,d%n", name, r.intValue());
System.out.printf("%s.longValue() = %,d%n", name, r.longValue());
System.out.printf("%s.floatValue() = %,f%n", name, r.floatValue());
System.out.printf("%s.doubleValue() = %,f%n", name, r.doubleValue());
System.out.println();
}
}
Çıkış:
r1 = 31,400
r1.negate() = -31,400
r1.invert() = 1 / 31,400
r1.intValue() = 31,400
r1.longValue() = 31,400
r1.floatValue() = 31,400.000000
r1.doubleValue() = 31,400.000000
r2 = 111 / 7
r2.negate() = -111 / 7
r2.invert() = 7 / 111
r2.intValue() = 15
r2.longValue() = 15
r2.floatValue() = 15.857142
r2.doubleValue() = 15.857143
r1 r2 = 219,911 / 7
r1 r2.negate() = -219,911 / 7
r1 r2.invert() = 7 / 219,911
r1 r2.intValue() = 31,415
r1 r2.longValue() = 31,415
r1 r2.floatValue() = 31,415.857422
r1 r2.doubleValue() = 31,415.857143
r1 - r2 = 219,689 / 7
r1 - r2.negate() = -219,689 / 7
r1 - r2.invert() = 7 / 219,689
r1 - r2.intValue() = 31,384
r1 - r2.longValue() = 31,384
r1 - r2.floatValue() = 31,384.142578
r1 - r2.doubleValue() = 31,384.142857
r1 * r2 = 3,485,400 / 7
r1 * r2.negate() = -3,485,400 / 7
r1 * r2.invert() = 7 / 3,485,400
r1 * r2.intValue() = 497,914
r1 * r2.longValue() = 497,914
r1 * r2.floatValue() = 497,914.281250
r1 * r2.doubleValue() = 497,914.285714
r1 / r2 = 219,800 / 111
r1 / r2.negate() = -219,800 / 111
r1 / r2.invert() = 111 / 219,800
r1 / r2.intValue() = 1,980
r1 / r2.longValue() = 1,980
r1 / r2.floatValue() = 1,980.180176
r1 / r2.doubleValue() = 1,980.180180
r2 ^ 2 = 12,321 / 49
r2 ^ 2.negate() = -12,321 / 49
r2 ^ 2.invert() = 49 / 12,321
r2 ^ 2.intValue() = 251
r2 ^ 2.longValue() = 251
r2 ^ 2.floatValue() = 251.448975
r2 ^ 2.doubleValue() = 251.448980
Bunu Paylaş:
En verimli şekilde artış Java Göster b...
En iyi şekilde Java dosyaları Listelem...
Bir şekilde yineleme-sayaç Java'l...
java verimli bir şekilde dosya boyutun...
En iyi şekilde Java 2 XML belgeleri ka...