【问题标题】:What is the difference between 'decimal' and 'float' in C#? [duplicate]C# 中的“十进制”和“浮点”有什么区别? [复制]
【发布时间】:2016-01-25 23:37:24
【问题描述】:

在 C# 中使用 decimalfloat 有什么区别?我知道float 用于更精确的十进制数字,decimal 用于像货币或价格这样的小数点,但是当它用于小数点时,为什么使用decimal而不是float

【问题讨论】:

  • “我知道 float 用于更精确的十进制数字,而 decimal 用于像货币这样的少数小数” 你反过来说,decimal 更精确。跨度>
  • 简单的答案。低精度使用浮点数。使用双精度高。使用小数来获得精确的精度。当然,您不能存储超过 15 位小数的范围,但那绝对不是浮点数。
  • @M.kazemAkhgary “准确”!哇!那么decimal 怎么代表 1/3 呢?后者乘以 3 会发生什么?
  • 对不起。十进制存储大约 28 位数字范围。如果将 1 除以 3,则得到 0.33。它将仅存储 28 个重复的三分球。当你将它乘以 3 时,你将得到 0.99。 28 个重复的 9。如您所见,这是精确的数学评估。但是如果你使用 double 类型,因为它的浮点型和高精度(不精确)你会得到 1。因为它总是会舍入到小数点较少的东西。这就是为什么我们说浮动。它可以根据小数四舍五入或向下舍入。因此它不适合存储例如世界纪录或赛车中的时间。因为毫秒很重要,我们不应该四舍五入!
  • 但是当你想以数学形式计算某些东西时,你必须使用 double 来给你更好的数字(在某些情况下,由于四舍五入会给你精确的结果。就像你给出的例子一样。1/3 是不完全存储。0.33*3 不是精确计算的,但是当我们舍入 0.999 时,我们得到 1,这是预期的精确结果)。双倍也比十进制快得多,但你感觉不到它,因为处理器速度很快!你必须阅读这个关于十进制与双倍性能的答案stackoverflow.com/a/329618/4767498

标签: c# floating-point decimal


【解决方案1】:

float 是浮点二进制类型,这意味着,在底层,它是二进制尾数后跟二进制指数,形式为mantissa x 10 ^ exponent10 是二进制中的数字 2。例如,数字 3.0 表示为 1.1 x 10^1,数字 8 1/2 表示为 1.0001 x 10^11。它本质上以二进制分数的形式表示数字。以 2 为底的浮点数的问题在于难以精确表示不是 2 的因数的十进制数。

用浮点二进制格式表示 1/2、1/4、1/8、1/16 等值很容易。 1/2 只是0.1,1/4 是0.01,1/8 是0.001,等等。但是如果你想表示像0.6 这样的十进制值,你必须建立一个以2 为底的分数的总和接近代表它。因此,您最终会得到 1.001100110011001100110011 x 10^-1 的浮点表示,其中 0011 只是不断重复,因为在 base-2 中没有十进制 0.6 的有理表示。

这就是 decimal 类型的用武之地。decimal 类型不使用小数二进制表示,而是使用符号位、96 位整数有效位和整数比例因子来表示值,取表格(sign x significand) / (10 ^ scaling factor)。符号可以是 0 或 1,有效数字可以是 0 到 2^96 - 1 之间的任何值,比例因子可以是 0 到 28 之间的任何值。这意味着数字在幕后以小数形式表示而不是二进制分数,因此我们人类习惯使用的数字可以在引擎盖下以有理形式精确而准确地表示。与我们之前看到的 0.6 的丑陋和不精确的二进制表示不同,decimal 类型将 0.6 表示为干净的(1 x 6) / (10 ^ 1)。漂亮,不是吗?

不幸的是,这是有代价的。 decimal 类型上的操作比 floatdouble 上的操作要慢得多。几乎所有人类已知的计算机中的处理器都是二进制处理器(我说“几乎每个”,因为我无法反驳地球上某个地方存在非二进制计算机)。这意味着它本机支持二进制加法、减法等。像float x = 256.0 / 2; 这样的操作编译为一个简单的指令,其中浮点数的指数递减。但是,decimal x = 256.0m / 2; 编译为更复杂的指令集,因为数字不是以二进制小数形式存储的,而且必须考虑数字的特殊 base-10 表示。

一般来说,如果您需要的速度超过十进制精度,floatdouble 就足以满足您的应用需求。但是,如果您首先需要小数精度,例如会计,那么decimal 是要使用的类型。

更多详情请见this MSDN documentation

【讨论】:

    【解决方案2】:

    decimal 关键字表示 128 位数据类型。与浮点类型相比,十进制类型的精度更高,范围更小,适用于金融和货币计算。小数类型的大致范围和精度如下表所示。

    (-7.9 x 1028 到 7.9 x 1028) / (10^0 - ^28), 28-29 位有效数字

    From MSDN

    另一方面是浮动:

    float 关键字表示存储 32 位浮点值的简单类型。下表显示了浮点类型的精度和近似范围。

    -3.4 × 10^38 到 +3.4 × 10^38,7 位有效数字

    Link

    【讨论】:

    • 那么,decimal是十进制数最精确的关键字吗?
    • 是的,它支持更大的可能数字(因此更精确)。不过,我不知道哪个支持更高的数学值。 编辑 Decimal.Max给你79,228,162,514,264,337,593,543,950,335,而Single.MaxValue(为什么是浮点类型Single?)根据MSDN说3.402823e38
    • 但是float 更快,所以我应该避免使用decimal,除非我需要很多精度,对吧?
    • 考虑到现代计算机的强大功能,人们可以说它“并不重要”,但我认为强化坏习惯没有意义。因此,如果您能记住哪种类型更小(就内存而言)并且您知道它足以满足您的需求,那么是的,我猜float 会更好。我有教授关心使用必要的最小类型,而我有雇主只要它编译就不会在意。
    • @FacundoSchiavoni 如果您使用十进制值(不是二进制),请使用decimal,除非您需要很高的速度。尝试运行以下代码:float x = 0.29f; bool surprise = (x * 10) == (0.29f * 10);
    【解决方案3】:

    十进制将有 128 位,浮点数只有 32 位表示数字

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-11
      • 2016-02-14
      • 2016-10-04
      • 1970-01-01
      • 2014-09-03
      相关资源
      最近更新 更多