【问题标题】:C# midpointrounding down to zeroC# 中点向下舍入为零
【发布时间】:2012-10-02 04:50:54
【问题描述】:

我知道 MidpointRounding.AwayFromZero 和 MidpointRounding.ToEven,但我想我想要介于两者之间的东西。它用于促销模块,因此如果值为 0.5,则折扣价格必须向下舍入。

例如,我想:

£1.244 四舍五入为 £1.24 1.245 英镑四舍五入为 1.24 英镑 1.246 英镑四舍五入至 1.25 英镑

据我了解,.AwayFromZero 会将中间值四舍五入为 1.25 英镑,.ToEven 将正确四舍五入为 1.24 英镑,但 1.335 英镑将四舍五入为 1.34 英镑,而不是我想要的 1.33 英镑。

有谁知道如何做到这一点?

谢谢,乔恩

【问题讨论】:

  • 这个 SO 问题可能会有所帮助...看起来默认行为是向偶数四舍五入:stackoverflow.com/q/977796/945456
  • 您总是可以使用数学模数来检查第 100 位是否为 5 或更低并向下舍入,6 或更高则向上舍入。

标签: c#


【解决方案1】:

有很多未指定的行为。让我们保持安全并明确地进行四舍五入,忽略负面因素,因为这是关于金钱的:

    public static decimal Promotion(decimal value) {
        decimal unround = decimal.Floor(value * 100m);
        decimal fraction = value * 100m - unround;
        if (fraction <= 0.5m) return unround / 100m;
        else return (unround + 1m) / 100m;
    }

【讨论】:

  • 非常有用!我很惊讶枚举中没有“MidPointRoundDown”,而且这段代码甚至是必要的,但微软似乎忽略了这一点。这是一个精确的版本:private static decimal RoundDown(decimal value, int precision) { decimal factor = (decimal)Math.Pow(10, precision); decimal unround = decimal.Floor(value * factor); decimal fraction = value * factor - unround; return fraction &lt;= 0.5m ? unround / factor : (unround + 1m) / factor; }
【解决方案2】:
Math.ceiling(x - 0.5)

应该做的伎俩。

【讨论】:

  • 我想过,但这些是商品价格,所以我认为这不是问题。 OP 必须定义他想如何处理价格,例如 -1.5 ......如果他认为这种情况会出现。如果是这样,它可以被包装在一个条件中: x > 0 ? Math.ceiling(x-0.5) : ;
【解决方案3】:

通常要做这样的事情,你从你的价值中减去 0.001,然后正常四舍五入。

1.244 - .001 = 1.243 = 1.24 1.245 - .001 = 1.244 = 1.24 1.246 - .001 = 1.245 = 1.25 1.300 - .001 = 1.299 = 1.3

在这种情况下,你真的想把它放在它自己的函数/扩展方法中,无论如何,并用函数记录为什么你在舍入之前减去 .001。

【讨论】:

  • 如果你的值是 1.245001 怎么办?在这种情况下,它将按应有的方式向下取整,而不是向上取整。
  • @Servy,我们说的是促销货币,它推断消费货币(不是疯狂的银行东西,只有几分之一美分),我们可能不需要担心 .000001英镑。
  • 您可能会因为浮点错误(取决于数据类型)或除法/乘法而得到这样的数字。
  • @Servy,你永远不应该用浮点数存储货币,那只是自找麻烦。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 2017-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多