【问题标题】:Decimal to exact fraction converter in c#c#中的小数到精确分数转换器
【发布时间】:2017-01-31 04:20:59
【问题描述】:

所以我开始了一个项目,我制作了一个二次方程求解器,并且我设法做到了。我的下一步是转换 X1 和 X2 的值,例如 (X+X1)(X+X 2) 精确到分数,如果它们变成小数的话。

所以一个例子是:

12x2 + 44x + 21

给我,

X1 = -3.10262885097732

X2 = -0.564037815689349

但是我怎么能把它转换成一个精确的分数呢? 感谢您的帮助!

【问题讨论】:

  • 这两个都是无理数。没有确切的分数来表示它们。
  • 也许你可以在这里找到有用的东西:stackoverflow.com/questions/5124743/…
  • 您的示例二次方的解决方案是x = -11/6 - sqrt(29/2)/3x = sqrt(29/2)/3 - 11/6sqrt(29/2) 部分是不合理的,因此没有 JLRishe 所说的精确分数。
  • @Enigmativity 和sqrt(29/2)/3sqrt(58)/6 相同。通常人们把它写成(-11 ± sqrt(58))/6

标签: c# decimal fractions


【解决方案1】:

您可以使用Continued Fractions 解决此问题。

如 cmets 所述,您无法获得完全代表 irrational number 的分数(rational number),但您可以非常接近。

我在一个宠物项目中实现了一次有理数类型。你可以找到它here。查看TryFromDouble 的示例,了解如何使用连续分数获得与任何给定数字最接近的有理数(具有指定精度)。

相关代码的摘录如下(我会 不贴整个类型实现,因为太长了,但代码应该还是挺容易理解的):

public static bool TryFromDouble(double target, double precision, out Rational result)
{
    //Continued fraction algorithm: http://en.wikipedia.org/wiki/Continued_fraction
    //Implemented recursively. Problem is figuring out when precision is met without unwinding each solution. Haven't figured out how to do that.
    //Current implementation computes rational number approximations for increasing algorithm depths until precision criteria is met, maximum depth is reached (fromDoubleMaxIterations)
    //or an OverflowException is thrown. Efficiency is probably improvable but this method will not be used in any performance critical code. No use in optimizing it unless there is
    //a good reason. Current implementation works reasonably well.

    result = zero;
    int steps = 0;

    while (Math.Abs(target - Rational.ToDouble(result)) > precision)
    {
        if (steps > fromDoubleMaxIterations)
        {
            result = zero;
            return false;
        }

        result = getNearestRationalNumber(target, 0, steps++);
    }

    return true;
}

private static Rational getNearestRationalNumber(double number, int currentStep, int maximumSteps)
{
    var integerPart = (BigInteger)number;
    double fractionalPart = number - Math.Truncate(number);

    while (currentStep < maximumSteps && fractionalPart != 0)
    {
        return integerPart + new Rational(1, getNearestRationalNumber(1 / fractionalPart, ++currentStep, maximumSteps));
    }

    return new Rational(integerPart);
}

【讨论】:

    猜你喜欢
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 2015-01-31
    • 2011-07-29
    • 2017-04-23
    • 2013-11-12
    • 2016-12-03
    相关资源
    最近更新 更多