所以我要做的就是将double转换为有理数。我检查小数点后有多少位数,我想将数字123.456保存为123456/1000,例如。
public Rational(double d){
String s = String.valueOf(d);
int digitsDec = s.length() - 1 - s.indexOf('.');
for(int i = 0; i < digitsDec; i++){
d *= 10;
}
System.out.println((int)d); //checking purposes
}
然而,对于数字123.456,我得到一个舍入错误,结果是123455.我想有可能用BigDecimal解决这个问题,但是我无法让它工作。此外,计算了它的有理数,我想调用另一个带参数的构造函数(int numerator,int denominator),但我现在无法在println所在的行中调用构造函数。我该怎么做?
答案 0 :(得分:4)
对于问题的第一部分,Java将.6存储为.5999999(重复)。见这个输出:
(after first multiply): d=1234.56
(after second multiply): d=12345.599999999999
(after third multiply): d=123455.99999999999
一个解决方法是在循环结束后立即使用d = Math.round(d)。
public class Rational {
private int num, denom;
public Rational(double d) {
String s = String.valueOf(d);
int digitsDec = s.length() - 1 - s.indexOf('.');
int denom = 1;
for(int i = 0; i < digitsDec; i++){
d *= 10;
denom *= 10;
}
int num = (int) Math.round(d);
this.num = num; this.denom = denom;
}
public Rational(int num, int denom) {
this.num = num; this.denom = denom;
}
public String toString() {
return String.valueOf(num) + "/" + String.valueOf(denom);
}
public static void main(String[] args) {
System.out.println(new Rational(123.456));
}
}
它有效 - 尝试一下。
对于你问题的第二部分......
为了从第一个构建函数中调用第二个构造函数,可以使用“this”关键字
this(num, denom)
但它必须是构造函数中的第一行...这在这里没有意义(我们必须先做一些计算)。所以我不打算尝试这样做。
答案 1 :(得分:3)
此代码对您来说可能有点过分,但它会处理您正在经历的舍入错误,并且还会处理重复小数(4.99999999999999变为5,而0.33333333333333333333变为1/3)。< / p>
public static Rational toRational(double number){
return toRational(number, 8);
}
public static Rational toRational(double number, int largestRightOfDecimal){
long sign = 1;
if(number < 0){
number = -number;
sign = -1;
}
final long SECOND_MULTIPLIER_MAX = (long)Math.pow(10, largestRightOfDecimal - 1);
final long FIRST_MULTIPLIER_MAX = SECOND_MULTIPLIER_MAX * 10L;
final double ERROR = Math.pow(10, -largestRightOfDecimal - 1);
long firstMultiplier = 1;
long secondMultiplier = 1;
boolean notIntOrIrrational = false;
long truncatedNumber = (long)number;
Rational rationalNumber = new Rational((long)(sign * number * FIRST_MULTIPLIER_MAX), FIRST_MULTIPLIER_MAX);
double error = number - truncatedNumber;
while( (error >= ERROR) && (firstMultiplier <= FIRST_MULTIPLIER_MAX)){
secondMultiplier = 1;
firstMultiplier *= 10;
while( (secondMultiplier <= SECOND_MULTIPLIER_MAX) && (secondMultiplier < firstMultiplier) ){
double difference = (number * firstMultiplier) - (number * secondMultiplier);
truncatedNumber = (long)difference;
error = difference - truncatedNumber;
if(error < ERROR){
notIntOrIrrational = true;
break;
}
secondMultiplier *= 10;
}
}
if(notIntOrIrrational){
rationalNumber = new Rational(sign * truncatedNumber, firstMultiplier - secondMultiplier);
}
return rationalNumber;
}
这提供了以下结果(测试用例的结果显示为注释):
Rational.toRational(110.0/3.0); // 110/3
Rational.toRational(11.0/1000.0); // 11/1000
Rational.toRational(17357.0/33300.0); // 17357/33300
Rational.toRational(215.0/21.0); // 215/21
Rational.toRational(0.123123123123123123123123); // 41/333
Rational.toRational(145731.0/27100.0); // 145731/27100
Rational.toRational(Math.PI); // 62831853/20000000
Rational.toRational(62.0/63.0); // 62/63
Rational.toRational(24.0/25.0); // 24/25
Rational.toRational(-24.0/25.0); //-24/25
Rational.toRational(-0.25333333333333333333333); // -19/75
Rational.toRational(-4.9999999999999999999999); // -5
Rational.toRational(4.9999999999999999999999); // 5
Rational.toRational(123.456); // 15432/125
答案 2 :(得分:2)
但这并不优雅,我相信这就是你所要求的。
double a = 123.456;
String aString = Double.toString(a);
String[] fraction = aString.split("\\.");
int denominator = (int)Math.pow(10, fraction[1].length());
int numerator = Integer.parseInt(fraction[0] + "" + fraction[1]);
System.out.println(numerator + "/" + denominator);
答案 3 :(得分:1)
这里,d = 123.456,然后num = 123456,j = 1000
public Rational(double d){
double temp =d;
int j=1, num;
do{
j=j*10;
}while((temp*j)%10==0);
j=j/10;
num=(int)(d*j);
System.out.println(num);
System.out.println(j);
}
答案 4 :(得分:0)
尝试
for(int i = 0; i <= digitsDec; i++){
}