Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.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
C# 将百分比转换为最接近的分数_C#_Percentage_Fractions - Fatal编程技术网

C# 将百分比转换为最接近的分数

C# 将百分比转换为最接近的分数,c#,percentage,fractions,C#,Percentage,Fractions,我们有一个非常数据密集的系统。它存储原始数据,然后根据正确回答数/总试验数计算百分比 最近,我们有一些客户希望将旧数据导入我们的系统 我需要一种方法将百分比转换为最接近的分数 例子 33%的人需要给我2/6。即使1/3是0.33333 67%的人需要给我4/6。即使4/6是0.66667 我意识到我可以将其计算为67/100,但这意味着我必须向系统中添加100个数据点,而6个数据点就足够了 有人有什么想法吗 编辑 分母可以是任何东西。他们给了我一个原始的、四舍五入的百分比,我正试图用原始数据尽可

我们有一个非常数据密集的系统。它存储原始数据,然后根据正确回答数/总试验数计算百分比

最近,我们有一些客户希望将旧数据导入我们的系统

我需要一种方法将百分比转换为最接近的分数

例子

  • 33%的人需要给我2/6。即使1/3是0.33333
  • 67%的人需要给我4/6。即使4/6是0.66667
  • 我意识到我可以将其计算为67/100,但这意味着我必须向系统中添加100个数据点,而6个数据点就足够了

    有人有什么想法吗

    编辑
    分母可以是任何东西。他们给了我一个原始的、四舍五入的百分比,我正试图用原始数据尽可能接近它

    它必须返回2/6而不是1/3吗?如果总是在6小时内,那么

    Math.Round((33 * 6)/100) = 2
    

    在这里回答我自己的问题。这样行吗

        public static Fraction Convert(decimal value) {
        for (decimal numerator = 1; numerator <= 10; numerator++) {
            for (decimal denomenator = 1; denomenator < 10; denomenator++) {
                var result = numerator / denomenator;
                if (Math.Abs(value - result) < .01m)
                    return new Fraction() { Numerator = numerator, Denomenator = denomenator };
            }
        }
    
        throw new Exception();
    }
    
    公共静态分数转换(十进制值){
    
    对于(十进制分子=1;分子而言,您的要求是矛盾的:一方面,您希望“将百分比转换为最接近的分数”(*),但另一方面,您希望分数较小(est)数字。你需要找到一些折衷办法,何时/如何降低精度,以利于较小的数字。你目前的问题是无法解决的


    (*)任何给定(整数)百分比n的最近分数f为n/100。根据定义。

    我已尝试使用连续分数来满足您的要求。通过将深度限制为3,我得到了合理的近似值

    我没能在合理的时间内想出一个迭代(或递归)方法。不过我已经清理了一点。(我知道3个字母的变量名并不好,但我想不出它们的好名字:-/)

    代码在指定公差范围内为您提供最佳有理近似值。生成的分数将减少,并且是具有相同或更低分母的所有分数中的最佳近似值

    public partial class Form1 : Form
    {
        Random rand = new Random();
    
        public Form1()
        {
            InitializeComponent();
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                double value = rand.NextDouble();
                var fraction = getFraction(value);
                var numerator = fraction.Key;
                var denominator = fraction.Value;
    
                System.Console.WriteLine(string.Format("Value {0:0.0000} approximated by {1}/{2} = {3:0.0000}", value, numerator, denominator, (double)numerator / denominator));
            }
            /*
                Output:
                Value 0,4691 approximated by 8/17 = 0,4706
                Value 0,0740 approximated by 1/14 = 0,0714
                Value 0,7690 approximated by 3/4 = 0,7500
                Value 0,7450 approximated by 3/4 = 0,7500
                Value 0,3748 approximated by 3/8 = 0,3750
                Value 0,7324 approximated by 3/4 = 0,7500
                Value 0,5975 approximated by 3/5 = 0,6000
                Value 0,7544 approximated by 3/4 = 0,7500
                Value 0,7212 approximated by 5/7 = 0,7143
                Value 0,0469 approximated by 1/21 = 0,0476
                Value 0,2755 approximated by 2/7 = 0,2857
                Value 0,8763 approximated by 7/8 = 0,8750
                Value 0,8255 approximated by 5/6 = 0,8333
                Value 0,6170 approximated by 3/5 = 0,6000
                Value 0,3692 approximated by 3/8 = 0,3750
                Value 0,8057 approximated by 4/5 = 0,8000
                Value 0,3928 approximated by 2/5 = 0,4000
                Value 0,0235 approximated by 1/43 = 0,0233
                Value 0,8528 approximated by 6/7 = 0,8571
                Value 0,4536 approximated by 5/11 = 0,4545
             */
        }
    
        private KeyValuePair<int, int> getFraction(double value, double tolerance = 0.02)
        {
            double f0 = 1 / value;
            double f1 = 1 / (f0 - Math.Truncate(f0));
    
            int a_t = (int)Math.Truncate(f0);
            int a_r = (int)Math.Round(f0);
            int b_t = (int)Math.Truncate(f1);
            int b_r = (int) Math.Round(f1);
            int c = (int)Math.Round(1 / (f1 - Math.Truncate(f1)));
    
            if (Math.Abs(1.0 / a_r - value) <= tolerance)
                return new KeyValuePair<int, int>(1, a_r);
            else if (Math.Abs(b_r / (a_t * b_r + 1.0) - value) <= tolerance)
                return new KeyValuePair<int, int>(b_r, a_t * b_r + 1);
            else
                return new KeyValuePair<int, int>(c * b_t + 1, c * a_t * b_t + a_t + c);
        }
    }
    
    公共部分类表单1:表单
    {
    Random rand=新的Random();
    公共表格1()
    {
    初始化组件();
    }
    私有无效按钮1\u单击(对象发送者,事件参数e)
    {
    对于(int i=0;i<10;i++)
    {
    double value=rand.NextDouble();
    var分数=getFraction(值);
    var分子=分数。键;
    var分母=分数值;
    System.Console.WriteLine(string.Format(“值{0:0.0000}近似于{1}/{2}={3:0.0000}”),值、分子、分母、(双)分子/分母);
    }
    /*
    输出:
    值04691近似为8/17=04706
    值00740近似为1/14=00714
    值07690近似为3/4=07500
    值07450近似为3/4=07500
    值03748近似为3/8=03750
    值07324近似为3/4=07500
    值05975近似为3/5=06000
    值07544近似为3/4=07500
    值07212近似为5/7=07143
    值00469近似为1/21=00476
    值02755近似为2/7=02857
    值08763近似为7/8=08750
    值08255近似为5/6=08333
    值06170近似为3/5=06000
    值03692近似为3/8=03750
    值08057近似为4/5=08000
    值03928近似为2/5=04000
    值00235近似为1/43=00233
    值08528近似为6/7=08571
    值04536近似为5/11=04545
    */
    }
    private KeyValuePair getFraction(双值,双容差=0.02)
    {
    双f0=1/值;
    双f1=1/(f0-数学截断(f0));
    int a_t=(int)Math.Truncate(f0);
    int a_r=(int)数学四舍五入(f0);
    int b_t=(int)Math.Truncate(f1);
    int b_r=(int)数学圆(f1);
    int c=(int)Math.Round(1/(f1-Math.Truncate(f1));
    
    如果(Math.Abs(1.0/a_r-值)是你的百分比整数?另外,为什么你不希望33%给你1/3,而不是2/6?@ChrisKooken-请根据大多数回答者/读者(包括我在内)的误解更新你的问题你需要一个更清晰的说明,说明什么时候分母越小越好,什么时候结果越准确越好。
    67/100
    比2/3更接近67%。你有一个不可能完成的任务。百分比的四舍五入删除了信息。你不能在没有其他形式信息的情况下简单地将这些信息放回去帮助您(例如,预期分母的概率权重).分母可以是任何东西。他们给了我一个原始的、四舍五入的百分比,我试图用原始数据尽可能接近它。但是1/3=2/6。如果你再举几个例子,也许可以。你确定你会找到一个介于1和10之间的有效分母吗?另外请注意,如果分母是固定的,你可以找到最接近y的分子我们的值;您也不需要强制执行该值。让分母为外部循环,然后计算最近的分子。此外,由于可能性很小,只需让循环运行并保持最佳结果,而不是有一个固定的阈值。