Float' average'百分之一秒

时间:2018-05-23 04:11:56

标签: c#

我在线解决此问题:https://www.codewars.com/kata/getting-along-with-integer-partitions/train/csharp/5af1b2b768e64499ed000102

它的基本思想是我应该找到一个数字的所有部分并显示范围,平均值和中位数。该程序处理大多数数字,但面对一些数字,平均值不准确。

这些是我遇到问题的一些数字:

  • 43 - 预期:平均值:202904.6 5 但是:202904.6 0

  • 36 - 预期:平均值:26832.8 1 但是:平均值:26832.8 0

  • 41 - 预期:平均值:113720.8 2 但是:平均值:113720.8 0

这是因为我使用浮动来存储我的号码吗?如果是这样,我应该使用什么数据类型?

这是我的代码(您可以将其直接粘贴到我链接的网站上,它会给您带来与我相同的错误)

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;

public class IntPart
{
    public static List<List<string>> listOfLists = new List<List<string>>();
    public static List<string> lastPartion = new List<string>(); //get the last partion

    public static string Part(long n)
    {
        Console.WriteLine(n);
         lastPartion.Clear();
         listOfLists.Clear();

        List<List<long>> result = new List<List<long>>();
        partition((int)n);

        //gets rid of blip where there's an extra space at the start of the string and 
        foreach (var cycle in lastPartion)
            listOfLists.Add(cycle.Split(' ').ToList());

        //converts the cycles to a list and converts string list to double
        for (int i = 0; i < listOfLists.Count; i++)
        {
            listOfLists[i].RemoveAt(0);
            result.Add(listOfLists[i].Select(x => long.Parse(x)).ToList());
        }                

        return removeAndSort(result);
    }

    //partioning algorithom with recursion 
    public static void partition(int n)
    {
        partition(n, n, "");
    }
    public static void partition(int n, int max, string prefix)
    {
        if (n == 0)
        {
            lastPartion.Add(prefix);
            return;
        }

        for (int i = Math.Min(max, n); i >= 1; i--)
            partition(n - i, i, prefix + " " + i);
    }

    public static string removeAndSort(List<List<long>> listOfLists)
    {
        List<long> result = new List<long>();
        string resultString = "";

        //find the products
        foreach (var list in listOfLists)
        {
            long product = 1;

            for (int i = 0; i < list.Count; i++)
                product *= list[i];

            result.Add(product);
        }

        //removes the duplicates
        result = result.Distinct().ToList(); //returns a copy of the list without any duplicates in the previous list
        result.Sort();

        int range = (int)(result.Max() - result.Min());
        float avg = (float)result.Sum() / (float)result.Count;
        float median = 0f;

        if (result.Count % 2 == 0)
            median = (float)Math.Round((double)((result[(result.Count / 2) - 1] + result[(result.Count / 2)])) / 2, 3);
        else
            median = result[result.Count / 2]; //odd

        return "Range: " + range + " Average: " + avg.ToString("0.00") + " Median: " + median.ToString("0.00");
    }

}

1 个答案:

答案 0 :(得分:1)

此错误是由计算float值的方式引起的。它们是以2为基数而不是10来计算的。当切换不同的碱基时,有些数字不能以十进制形式表示。

众所周知,1/3不能在基数10中写为小数,但在基数12中,1/30.4(且1/2为{{ 1}})。

Base 2在代表十分之一时遇到麻烦。 0.6最终会0.1重复,或类似的事情。

C#中的{p> 0b00110011计算基数为十,而不是基数为二。这使得它更准确,更省钱,但它在某种程度上更慢