Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 小数到小数的转换_Java_Split_Double_Decimal_Fractions - Fatal编程技术网

Java 小数到小数的转换

Java 小数到小数的转换,java,split,double,decimal,fractions,Java,Split,Double,Decimal,Fractions,我有一个方法,将十进制(双数值)转换成分数,并将分子和分母值转换成大小为2的int[] 测试它对大多数值都很好,但当我点击0.0001时除外。然后返回值为1.0/1.0 方法: private static int[] toFractionPos(double x){ String[] parts = Double.toString(x).split("\\."); double den = Math.pow(10, parts[1].length()); //denominat

我有一个方法,将十进制(双数值)转换成分数,并将分子和分母值转换成大小为2的int[]

测试它对大多数值都很好,但当我点击
0.0001
时除外。然后返回值为
1.0/1.0

方法:

private static int[] toFractionPos(double x){
    String[] parts = Double.toString(x).split("\\.");
    double den = Math.pow(10, parts[1].length()); //denominator
    double num = Double.parseDouble(parts[0]) * den + Double.parseDouble(parts[1]); //numerator
    return reduceFraction((int)num, (int)den);
}
reduceFraction()
方法:

public static int[] reduceFraction(int num, int den){
    int gcf = GCF(num, den); //greatest common factor
    int[] rf = {num/gcf, den/gcf};
    return rf;
}

谢谢

算法似乎很好。但是,使用
double
不适合此类问题,因为精度会随着刻度的增大而降低

您应该使用和。我大致修改了您的示例,使其适用于它们,但我没有考虑细节,即解析
字符串
应该是不必要的,因为可以使用getter从
BigDecimal
检索比例,您可以配置不同的舍入模式,等等:

import java.math.BigDecimal;
import java.math.BigInteger;

public class Sample {

    static int[] toFractionPos(BigDecimal x) {
        String[] parts = x.toString().split("\\.");
        BigDecimal den = BigDecimal.TEN.pow(parts[1].length()); // denominator
        BigDecimal num = (new BigDecimal(parts[0]).multiply(den)).add(new BigDecimal(parts[1])); // numerator
        return reduceFraction(num.intValue(), den.intValue());
    }

    static int[] reduceFraction(int num, int den) {
        int gcd = BigInteger.valueOf(num).gcd(BigInteger.valueOf(den)).intValue(); // greatest
                                                                                   // common
                                                                                   // divisor
        int[] rf = { num / gcd, den / gcd };
        return rf;
    }

    public static void main(String[] args) {
        int[] fraction = toFractionPos(new BigDecimal("0.0001"));
        System.out.println(fraction[0] + "/" + fraction[1]); // 1/10000
    }
}

注意:优化留作练习;)

您不应该使用double,因为您正在失去精度,这可能会导致严重错误。但在
1.0001
的情况下,问题在于:

Double.toString(1.0001) == "1.0E-4"
然后尝试解析
“0E-4”
,得到的是0而不是1。如果最多需要10个小数点,可以执行以下操作:

DecimalFormat df = new DecimalFormat("0", 
    DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(10);
String[] parts = df.format(x).split("\\.");
这个怎么样

private static int[] toFractionPos(double x){
  int den = (int)Math.pow(10,(int)Math.log10(Integer.MAX_VALUE));
  int num = (int)(x*den);
  return reduceFraction(num, den);//this came from your code
}

我想这会管用的

public int[] Fraction(double n) {
   BigDecimal p = BigDecimal.ONE;
   BigDecimal dn = BigDecimal.valueOf(n);       
   while(true){
        dn = dn.multiply(p);
        if( dn.compareTo(new BigDecimal(dn.toBigInteger()))==0 )
            break;
        else
            p = p.multiply(BigDecimal.TEN);
   }
   BigInteger num=dn.toBigInteger(), den=p.toBigInteger(), g=num.gcd(den);
   num = num.divide(g);
   den = den.divide(g);             
   int[] res = new int[2];
   res[0] = num.intValue();
   res[0] = den.intValue();
   return res;
}

可能是精度错误?双精度值不是小数。它是二进制数字的浮点表示法。什么都没有。你的意思是一个带有小数部分的数字吗?这并不能有效地回答这个问题。你为什么相信这是答案?它是如何工作的?简单地告诉某人在没有任何上下文或意义的情况下更改代码并不能帮助他们了解他们做错了什么。我编辑了我的评论,以有用的方式回答了这个问题。