【问题标题】:Convert Double --> Decimal not exactly [duplicate]转换双精度-> 小数不完全 [重复]
【发布时间】:2012-12-02 04:58:17
【问题描述】:

可能重复:
What is the difference between Decimal, Float and Double in C#?

帮帮我。

我正在用 C# 开发一个应用程序。我正在尝试:

DateTime dtm1 = new DateTime(2012, 11, 15, 11, 3, 0);
DateTime dtm2 = new DateTime(2012, 11, 15, 11, 3, 20);
TimeSpan timespan3 = dtm2 - dtm1;
decimal _Hour = Convert.ToDecimal(timespan3.TotalHours);

什么时候输出如下:

 _Hour = 0.00555555555555556M

而 which 不完全是,使用时是一种 double it 用于输出:

 double _Hour = timespan3.TotalHours;

 output: 0.0055555555555555549

一个例子:

public decimal tinhDienTichHinhThang(decimal D1, decimal D2, decimal H)
        {
            //tính tổng 2 đáy
            decimal tong2Day = D1 + D2;
            //cộng vào nhân chiều cao :))
            tong2Day = tong2Day * H;

            //return diện tích
            return tong2Day / 2;
        }


DateTime dtm1 = new DateTime(2012, 11, 15, 11, 3, 0);
DateTime dtm2 = new DateTime(2012, 11, 15, 11, 3, 20);
TimeSpan timespan3 = dtm2 - dtm1;

///progress
///cal1: _Hour
///cal2: decimal D1 = 0.25
///cal3: decimal D2 = 5
///cal4: decimal D3 = 0.9

decimal test1 = (decimal test1 = Math.Round((D1 + tinhDienTichHinhThang(D2, 0, Convert.ToDecimal(timespan3.TotalHours))) * D3, 3, MidpointRounding.AwayFromZero);

输出:test1 = 0.237

如果手动计算:

test1 =  Math.Round((0.25 + ((5+0)*timespan3.TotalHours/2))*0.9, 3, MidpointRounding.AwayFromZero);

输出:test1 = 0.238(确切地说:0.2375)

注意:那么精确计算 win XP:0.2375 但是计算win 7则不准确。

请解释一下为什么会出现这个问题以及解决这个问题的方法?

【问题讨论】:

  • 你到底想从什么开始?根据我对日期和时间的经验,如果您使用 double decimal,您可能会以错误的方式处理事情。

标签: c#


【解决方案1】:

双精度值是浮点值。它们仍然被限制为 64 位精度,但它们有一个值和一个将值提升到的指数(本质上是科学记数法)。这就是为什么它们的范围比 int 或 long 多,但是由于这个扩展的范围,它们不能表示该范围内的所有可能值。

小数的位数比双精度多,因此在转换值时,您只会看到双精度低于小数的副作用。

【讨论】:

  • 感谢扎克·约翰逊。但是window XP正好,win 7不一样。在我的示例中,分别使用 Round 0.238 和 0.237 时会给出 2 个不同的结果
  • @user1903252 只是在黑暗中尝试了一下,但您可能会看到硬件和软件中实现的浮点运算之间的区别。
  • 控制你说是骚?你解决的方法是像我说的那样不是吗?
  • @user1903252 抱歉,我不太明白你的意思?一个小调查告诉我你可能是从越南翻译过来的? (这里的非英语单词“sao”和问题中的“cho”。)不幸的是,有些东西在翻译中丢失了。
  • 双精度位的精度是 53 位,而不是 64 位。小数以十进制基数表示,而不是二进制,因此它们在小数位上“更准确”,不仅仅是因为有额外的位。您关于硬件与软件的陈述仅仅是猜测。 -1
【解决方案2】:

我不确定你的问题是什么。但是,如果您对十进制和双精度值的不同值有疑问,那是设计使然。默认浮点数是不精确的。

更新:(在答案中回答您的问题)

由于这个问题,你的答案中的第一个和第二个陈述不同:

原因

5M * Convert.ToDecimal(timespan3.TotalHours)/ 2M

计算是十进制的, 但在第二个:

5 * timespan3.TotalHours / 2

计算是双倍的(因为 timespan3.TotalHours 是双倍的)。这意味着结果可能与第一个语句不同。但是在计算的时候,你将它转换为十进制,它会隐式地将值转换为十进制,这可以改变值。

在第三个语句中,你也有整数值计算,但是 double 是浮点类型,所以它的值可以不同于第二个语句,其中定点类型为小数。

【讨论】:

  • 但是window XP正好,win 7不一样。在我的示例中,分别使用 Round 0.238 和 0.237 时会给出 2 个不同的结果
【解决方案3】:
decimal test1 = (0.25M + 5M * Convert.ToDecimal(timespan3.TotalHours) / 2M) * 0.9M;

decimal test2 = (decimal)((0.25 + 5 * timespan3.TotalHours / 2) * 0.9);

double test3 = (0.25 + 5 * timespan3.TotalHours / 2) * 0.9;

何时执行此操作,它们的以下输出不一样。 你能指导解决这个问题吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-24
    • 1970-01-01
    • 2017-10-11
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 2015-09-13
    相关资源
    最近更新 更多