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
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);
那应该是