获取十进制数的整数部分的最佳方法

Posted

技术标签:

【中文标题】获取十进制数的整数部分的最佳方法【英文标题】: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”更准确——我将在上面重新表述。 【参考方案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 的评价。另外,你的假设特别糟糕。那是炎症吗?我想你可以这么说。你也可以说,告诉某人做一些愚蠢的事情会导致他们在路上遇到问题,即使不是完全不道德的,也是煽动性的。 如果我打算给出一个误导性的答案,那确实是错误的。事实上,我只是想帮忙。如果我犯了轻微的误解或没有完全理解这个问题,那很公平——这不是犯罪。那我们现在为什么吵架?我们都同意截断是正确的答案。

以上是关于获取十进制数的整数部分的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

详解浮点数的二进制表示

数制转换之十进制转十六进制

Python秘籍十进制整数与二进制数的转换

小数怎么转化成二进制数

用C语言编一个将十进制整数转化为16进制数的程序

如何将数值转化为二进制数?