Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.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#_Random - Fatal编程技术网

C# 随机小数导致负数

C# 随机小数导致负数,c#,random,C#,Random,我试图获取一个货币值(使用十进制),并将其分成随机部分,分布在14个不同的标签中,这些标签加起来就是原始值 示例:值50.00 1=1.50 2=3.50 3=7.00 4=0.75 5=1.25 6=2.00 7=5.50 8=6.10 9=0.60 10=0.50 11=5.30 12=3.00 13=3.00 14=10.00 (不是精确的值,而是这样的随机值,总计将达到总数) 问题是,我无法理解以下几点: 第一个随机数较高(如果值为50,则第一个数字通常为40左右),其余数字较低,低

我试图获取一个货币值(使用
十进制
),并将其分成随机部分,分布在14个不同的标签中,这些标签加起来就是原始值

示例:值50.00

  • 1=1.50
  • 2=3.50
  • 3=7.00
  • 4=0.75
  • 5=1.25
  • 6=2.00
  • 7=5.50
  • 8=6.10
  • 9=0.60
  • 10=0.50
  • 11=5.30
  • 12=3.00
  • 13=3.00
  • 14=10.00
(不是精确的值,而是这样的随机值,总计将达到总数)

问题是,我无法理解以下几点:

  • 第一个随机数较高(如果值为50,则第一个数字通常为40左右),其余数字较低,低于5左右
  • 其次,输出的数字不是十进制格式——它们都是整数
  • 最后,一半是正数,一半是负数。它确实达到了我想要的数字,但我不想要负输出
  • 我正在使用的代码:

     private void generatewins(Decimal amount)
        {
            Decimal initialValue = amount;
            Decimal currentRemainder = amount;
            var values = new List<int>();
            Label[] labels = { win1, win5, win10, win9, win6, win2, win3, win7, win8, win11, win13, win12, win4 };
            Random rnd = new Random();
            Decimal remainingPortion = initialValue;
    
            for (int i = 0; i < 13; i++)
            {
    
                Decimal val = currentRemainder - rnd.Next(14 - i);
    
                currentRemainder -= val;
    
    
                labels[i].Text = Convert.ToString(val) + "";
                win14.Text = currentRemainder.ToString();
            }
        }
    
    private void generatewins(十进制金额)
    {
    十进制初始值=金额;
    十进制剩余=金额;
    var值=新列表();
    Label[]labels={win1、win5、win10、win9、win6、win2、win3、win7、win8、win11、win13、win12、win4};
    随机rnd=新随机();
    十进制剩余部分=初始值;
    对于(int i=0;i<13;i++)
    {
    十进制值=当前余数-rnd.Next(14-i);
    当前余数-=val;
    标签[i].Text=Convert.ToString(val)+“”;
    win14.Text=currentRequires.ToString();
    }
    }
    

    为了澄清一些问题,我使用标签的原因是我必须将这些标签放置在表单上的特定位置,以便它们随着表单大小和表单上的另一个对象而变化。我认为使用标签会更容易。另外,数字14不是余数的一部分;它被设置为从初始值中提取剩余值,因为当我将其添加到随机拆分的值中时,它始终会显示为0,而其他13个值的总和不会等于初始值。

    我认为您需要一个类似的循环

    decimal Total = 50.00M;
    for ( i = 0; i <= 14; i++)
    {
        Random random = new Random();
        decimal newDec = Math.Round((random.NextDouble(0 , Total) / 100),3));
        //do something to log newDec
        Total -= newDec;
    }
    
    decimal总计=50.00M;
    
    对于(i=0;i我认为您需要一个类似

    decimal Total = 50.00M;
    for ( i = 0; i <= 14; i++)
    {
        Random random = new Random();
        decimal newDec = Math.Round((random.NextDouble(0 , Total) / 100),3));
        //do something to log newDec
        Total -= newDec;
    }
    
    decimal总计=50.00M;
    
    对于(i=0;iok,从问题2开始)它们是整数的原因是因为您的随机结果将是一个整数。请改用rnd.NextDouble(),它将获得一个介于0和1之间的随机十进制数

    这听起来可能是一个糟糕的范围,但它将有助于解决问题1)结果从大到小。这显然是因为您提供的随机范围随着循环的进行而改变和缩小。我要做的是简单地循环14次(或任何时候),得到14个0到1之间的随机数。那么!将所有数字相加,除以总值(在您的情况下为50.00),然后再次进行运算,并将所有数字乘以该结果。这将使这些数字相加,使所有数字都有均等的机会成为范围内的任何数字

    decimal Total = 50.00;
    decimal randTotal = 0;
    decimal []values = new decimal[14];
    for(int i = 0; i<14; i++)
    {
        values[i] = rnd.NextDouble();
        randTotal += values[i]
    }
    
    decimal co = Total / randTotal;
    
    for (int i = 0; i < 14; i++)
       values[i] *= co;
    
    decimal总计=50.00;
    小数总数=0;
    十进制[]值=新的十进制[14];
    
    对于(inti=0;iok,从问题2开始)它们是整数的原因是因为您的随机结果将是整数。改为使用rnd.NextDouble(),它将获得一个介于0和1之间的随机十进制数

    这听起来可能是一个糟糕的范围,但它将有助于解决问题1)结果从大到小。这显然是因为您提供的随机范围随着循环的进行而改变和缩小。我要做的是简单地循环14次(或任何时候),得到14个0到1之间的随机数。那么!将所有数字相加,除以总值(在您的情况下为50.00),然后再次进行运算,并将所有数字乘以该结果。这将使这些数字相加,使所有数字都有均等的机会成为范围内的任何数字

    decimal Total = 50.00;
    decimal randTotal = 0;
    decimal []values = new decimal[14];
    for(int i = 0; i<14; i++)
    {
        values[i] = rnd.NextDouble();
        randTotal += values[i]
    }
    
    decimal co = Total / randTotal;
    
    for (int i = 0; i < 14; i++)
       values[i] *= co;
    
    decimal总计=50.00;
    小数总数=0;
    十进制[]值=新的十进制[14];
    
    对于(int i=0;i随机类返回整数。如果需要十进制数,可以除以100

    还请注意,Next的参数是随机数的大小。您应该将其限制为所需的数字大小。这就是为什么您会得到负数-如果返回的随机数大于当前余数,(无论何时(14-i)都可能发生)结果大于当前余数,则该值将为负值

    当第一个数字变大时,请考虑第一次迭代的可能结果。随机数介于0和14之间,因此val结果必须始终在比原始数字小14的范围内。您实际需要的是一个偏态分布,其中第一个val可以是从零到原始数字的任意位置值,但平均值在(当前余数/(14-i))。这将给出更多的随机值。要知道确保正确随机数的最佳分布,需要比我更专业的数学专家,但前提是每次迭代都保证在零到当前余数的范围内,那么至少不会超过总数。一个简单的解决方案是限制该值s在平均值的0到两倍之间,就像这样

    十进制当前余数=初始值

    for (int i = 0; i < 13; i++)
    {
        Decimal avg = (currentRemainder/(14-i));
        Decimal val = currentRemainder - (rnd.Next(avg*2*100)/100);
    
        currentRemainder -= val;
    
        labels[i].Text = Convert.ToString(val) + "";
        win14.Text = currentRemainder.ToString();
    }
    labels[13] = Convert.ToString(currentRemainder);
    
    for(int i=0;i<13;i++)
    {
    十进制平均值=(当前余数/(14-i));
    十进制值=当前余数-(下一次随机数(平均值*2*100)/100);
    当前余数-=val;
    标签[i].Text=Convert.ToString(val)+“”;
    win14.Text=currentRequires.ToString();
    }
    标签[13]=Convert.ToString(currentRequires);
    
    那应该是