【问题标题】:Best way to get whole number part of a Decimal number获取十进制数的整数部分的最佳方法
【发布时间】:2010-10-03 13:01:48
【问题描述】:

返回小数的整数部分的最佳方法是什么(在 c# 中)? (这必须适用于可能不适合 int 的非常大的数字)。

GetIntPart(343564564.4342) >> 343564564
GetIntPart(-323489.32) >> -323489
GetIntPart(324) >> 324

这样做的目的是:我在数据库中插入一个十进制 (30,4) 字段,并希望确保我不会尝试插入一个对于该字段来说太长的数字。确定小数部分的整数部分的长度是此操作的一部分。

【问题讨论】:

  • 获取不到 int 部分;你可以得到整数部分并放弃小数部分。 Decimal 的整数部分很容易溢出 int 并抛出或环绕,默默地杀死你的代码。
  • 嗯,这就是为什么这个问题不像看起来那么简单。我需要它像处理小数字一样可靠地处理非常大的数字。但是,“整数”比“int”更准确——我将在上面重新表述。

标签: c# .net decimal int


【解决方案1】:

希望对你有帮助。

/// <summary>
/// Get the integer part of any decimal number passed trough a string 
/// </summary>
/// <param name="decimalNumber">String passed</param>
/// <returns>teh integer part , 0 in case of error</returns>
private int GetIntPart(String decimalNumber)
{
    if(!Decimal.TryParse(decimalNumber, NumberStyles.Any , new CultureInfo("en-US"), out decimal dn))
    {
        MessageBox.Show("String " + decimalNumber + " is not in corret format", "GetIntPart", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return default(int);
    } 

    return Convert.ToInt32(Decimal.Truncate(dn));
}

【讨论】:

    【解决方案2】:
       Public Function getWholeNumber(number As Decimal) As Integer
        Dim round = Math.Round(number, 0)
        If round > number Then
            Return round - 1
        Else
            Return round
        End If
    End Function
    

    【讨论】:

    • 接受的答案(八年前发布)解释了为什么这个答案是错误的。 decimal 的范围远远大于int 的范围。另外,这不是一个 VB 问题。
    • @JoeFarrell - 如果您认为答案是错误的,除了留下评论之外,您还可以考虑对其进行否决。但是,不要标记它(不是我说你有)。这是一个回答问题的尝试。它可能是错误的语言,甚至在 VB 中也可能是错误的,但这是一种尝试。例如,请参见“When an answer answers the wrong question, is it Not An Answer?”。
    【解决方案3】:

    分离值及其小数部分值的非常简单的方法。

    double  d = 3.5;
    int i = (int)d;
    string s = d.ToString();
    s = s.Replace(i + ".", "");
    

    s 是小数部分 = 5 并且
    i 是整数 = 3

    【讨论】:

    • 见上面的最佳答案。这不起作用,因为(int)Decimal.MaxValue 会溢出。
    【解决方案4】:

    顺便说一句,(int)Decimal.MaxValue 会溢出。您无法获得小数的“int”部分,因为小数太大而无法放入 int 框中。刚刚检查过......它甚至太大了很长一段时间(Int64)。

    如果你想要一个 Decimal 值的位到点的 LEFT,你需要这样做:

    Math.Truncate(number)
    

    并将值返回为... DECIMAL 或 DOUBLE。

    edit:截断绝对是正确的函数!

    【讨论】:

    • 所以结果是十进制或双精度,在该点之后永远不会有任何内容,但没有内置对象将结果存储为“int”(没有小数位),看起来有点蹩脚?
    • @CodeBlend:围绕失去精度的愿望设计框架的呼声并不高。
    • @CodeBlend:您仍然会丢失精度,因为您要截断数字的十进制值。不知道你在做什么。
    • 不确定这是否可行。因为 Math.Truncate(-5.99999999999999999) 为我返回 -6.0...!!
    • @Bharat Mori:似乎 -5.99999999999999999 在截断之前四舍五入到 -6.0。尝试使用后缀“m”,它会起作用。 Math.Truncate(-5.99999999999999999m) 给出 -5。
    【解决方案5】:

    我认为System.Math.Truncate 是您正在寻找的。​​p>

    【讨论】:

      【解决方案6】:

      取决于你在做什么。

      例如:

      //bankers' rounding - midpoint goes to nearest even
      GetIntPart(2.5) >> 2
      GetIntPart(5.5) >> 6
      GetIntPart(-6.5) >> -6
      

      //arithmetic rounding - midpoint goes away from zero
      GetIntPart(2.5) >> 3
      GetIntPart(5.5) >> 6
      GetIntPart(-6.5) >> -7
      

      默认始终是前者,这可能会让人感到意外,但makes very good sense

      你的显式演员会做:

      int intPart = (int)343564564.5
      // intPart will be 343564564
      
      int intPart = (int)343564565.5
      // intPart will be 343564566
      

      从你提出问题的方式来看,这听起来不是你想要的——你每次都想把它说出来。

      我愿意:

      Math.Floor(Math.Abs(number));
      

      还要检查 decimal 的大小 - 它们可能很大,因此您可能需要使用 long

      【讨论】:

      • (long)Decimal.MaxValue 溢出。
      • 公平点 - 我想这就是 Math.Truncate(decimal) 返回小数的原因。
      • 在 C# 中,转换为 int 不会四舍五入,因此 (int)0.6f 将为 0,并且 (int)343564565.5 将以 5 结尾,而不是 6。试试这里:repl.it/repls/LuxuriousCheerfulDistributeddatabase跨度>
      • 由于您不能使用 Math.Truncate 的原因,您可能希望使用 Math.Floor 和 Math.Abs​​,但对于负值,您需要更改符号,例如 Math.Floor(Math.Abs(number)) * (number &gt; 0 ? 1 : -1)。试试dotnetfiddle example
      【解决方案7】:

      你只需要像这样投射它:

      int intPart = (int)343564564.4342
      

      如果您仍想在以后的计算中将其用作小数,那么 Math.Truncate(或者如果您想要负数的某种行为,也可能是 Math.Floor)是您想要的函数。

      【讨论】:

      • 这是错错错。如果结果大于 Int32 可以容纳的值,它要么抛出异常,要么(甚至更糟!!!)静默溢出并返回,给你一个完全不正确的结果,你甚至都不知道。
      • 不,这不是。它对非常大的小数/浮点值无效,但在大多数情况下都很好。编码时数字通常被限制为足够低,因此这不是问题。此外,我提供了适用于所有值的 Math.Truncate 解决方案。
      • 我明白你为什么生我的气了。事实是你的答案是错误的。你告诉他要抓住机会不要打破它,因为,嘿,很多数字都很小。这是一个愚蠢的风险。您应该编辑您的答案并删除除 Math.Truncate 之外的所有内容,因为它是唯一正确的部分。
      • 您知道他们对 ASSUME 的评价。另外,你的假设特别糟糕。那是炎症吗?我想你可以这么说。你也可以说,告诉某人做一些愚蠢的事情会导致他们在路上遇到问题,即使不是完全不道德的,也是煽动性的。
      • 如果我打算给出一个误导性的答案,那确实是错误的。事实上,我只是想帮忙。如果我犯了轻微的误解或没有完全理解这个问题,那很公平——这不是犯罪。那我们现在为什么吵架?我们都同意截断是正确的答案。
      猜你喜欢
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 1970-01-01
      • 2021-04-12
      • 2018-08-28
      • 2020-12-26
      • 2021-09-09
      相关资源
      最近更新 更多