【问题标题】:Split decimal to element count equally将小数拆分为元素计数
【发布时间】:2014-04-15 14:33:47
【问题描述】:

我有 List<myType> 绑定到 DataTemplate 属性:

public int pID { get; set; }
public string NamePar { get; set; }
public decimal Count { get; set; }

还有文本框,用户可以在其中输入十进制数或从重量中读取。 我正在寻找将输入的小数拆分为产品计数的解决方案,例如:

TextBox 从权重中得到 16.700 值,productCount = 3,拆分为:

[1] 5.56

[2] 5.56

[3] 5.58

另一个例子 91/3

[1] 30.3

[2] 30.3

[3] 30.4

等等

知道如何解决这个问题吗?

【问题讨论】:

  • 为什么第一个例子四舍五入到小数点后两位,而第二个例子四舍五入到整数?
  • 对不起,我的错,我会修复它。

标签: c# wpf split decimal


【解决方案1】:

您可以通过检查该项目是否是列表中的最后一项,或者它是否是初始 N-1 项目之一来计算结果。

  • 当它是初始N-1 项目之一时,使用Math.Truncate(100*Weight/Count)/100
  • 最后一项时,使用Weight - ((Count-1) * Math.Truncate(100*Weight/Count) / 100)

这背后的逻辑很简单:当它是初始数字之一时,截断除法的结果;通过从总权重中减去截断值的总和来计算最后一个数字。

这种方法在小数点后产生两个数字,所以你的第二个例子看起来像

30.33
30.33
30.34

【讨论】:

  • 我正要测试它,但 Math.Truncate 只需要 2 个参数。
  • @user13657 你的意思是一个论点,对吧?我编辑了答案来解决这个问题。
  • 是的,又是我的错。谢谢。
  • 我以前也使用过这种方法。但是,我建议使用 100m 而不是 100. 来表示它是一个十进制常量。
【解决方案2】:

把剩下的放在最后一项上:

public List<decimal> Allocate(decimal input, int items, int precision)
{
   decimal scale = (decimal)Math.Pow(10,precision);
   decimal split = Math.Truncate((input / items)*scale) / scale;
   List<decimal> output = Enumerable.Repeat(split, items).ToList();

   decimal remainder = input - output.Sum();
   output[output.Count - 1] += remainder;

   return output;
}

虽然四舍五入似乎是一种更准确的方法 - 如果您有多个项目,您可能会产生很多截断错误:

public List<decimal> Allocate(decimal input, int items, int precision)
{
   decimal split = Math.Round((input / items), precision);
   List<decimal> output = Enumerable.Repeat(split, items).ToList();

   decimal remainder = input - output.Sum();
   output[output.Count - 1] += remainder;

   return output;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多