Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 删除尾随零_C#_.net_Decimal - Fatal编程技术网

C# 删除尾随零

C# 删除尾随零,c#,.net,decimal,C#,.net,Decimal,我有一些由集合返回的字段,如 2.4200 2.0044 2.0000 我想要这样的结果 2.42 2.0044 2 我尝试使用String.Format,但它返回2.0000,并将其设置为N0,同时对其他值进行舍入。像这样尝试 string s = "2.4200"; s = s.TrimStart('0').TrimEnd('0', '.'); 然后将其转换为浮点值取决于您的数字代表什么以及您希望如何管理这些值:它是一种货币,您需要舍入还是截断,您需要舍入仅用于显示吗 如果显示要考虑

我有一些由集合返回的字段,如

2.4200
2.0044
2.0000
我想要这样的结果

2.42
2.0044
2
我尝试使用String.Format,但它返回2.0000,并将其设置为N0,同时对其他值进行舍入。

像这样尝试

string s = "2.4200";

s = s.TrimStart('0').TrimEnd('0', '.');

然后将其转换为浮点值取决于您的数字代表什么以及您希望如何管理这些值:它是一种货币,您需要舍入还是截断,您需要舍入仅用于显示吗

如果显示要考虑格式化,则数字为x.toStult

如果只是四舍五入,请使用需要中点四舍五入重载的Math.Round重载

如果你从数据库中得到你的价值,考虑铸造而不是转换: double value=decimalmyRecord[columnName]

这将起作用:

decimal source = 2.4200m;
string output = ((double)source).ToString();
或者,如果初始值为字符串:


请注意。

如果输入是一个字符串,它不是这么简单吗?您可以使用以下选项之一:

string.Format("{0:G29}", decimal.Parse("2.0044"))

decimal.Parse("2.0044").ToString("G29")

2.0m.ToString("G29")
这应该适用于所有输入

更新检查我必须显式地将精度说明符设置为29,因为文档明确指出:

但是,如果数字为十进制且省略了精度说明符,则始终使用定点表示法并保留尾随零

在评论中更新:


注意0.000001之类的值。G29格式将以尽可能短的方式显示它们,因此它将切换到指数表示法。string.Format{0:G29},decimal.Parse0.00000001,System.Globalization.CultureInfo.getcultureinfo-US将给出1E-08作为结果


我遇到了同样的问题,但我无法控制字符串的输出,这是由库处理的。在详细了解十进制类型的实现后,请参见, 我在这里想出了一个巧妙的技巧作为扩展方法:

public static decimal Normalize(this decimal value)
{
    return value/1.000000000000000000000000000000000m;
}
小数的指数部分减少到所需的程度。在输出十进制数上调用ToString将写入不带任何尾随0的数字。例如

1.200m.Normalize().ToString();

在我看来,使用它更安全


这是一种非常低级的方法,但我相信这将是最有效的方法,只使用快速整数计算,而不使用慢速字符串解析和区域性敏感方法:

public static decimal Normalize(this decimal d)
{
    int[] bits = decimal.GetBits(d);

    int sign = bits[3] & (1 << 31);
    int exp = (bits[3] >> 16) & 0x1f;

    uint a = (uint)bits[2]; // Top bits
    uint b = (uint)bits[1]; // Middle bits
    uint c = (uint)bits[0]; // Bottom bits

    while (exp > 0 && ((a % 5) * 6 + (b % 5) * 6 + c) % 10 == 0)
    {
        uint r;
        a = DivideBy10((uint)0, a, out r);
        b = DivideBy10(r, b, out r);
        c = DivideBy10(r, c, out r);
        exp--;
    }

    bits[0] = (int)c;
    bits[1] = (int)b;
    bits[2] = (int)a;
    bits[3] = (exp << 16) | sign;
    return new decimal(bits);
}

private static uint DivideBy10(uint highBits, uint lowBits, out uint remainder)
{
    ulong total = highBits;
    total <<= 32;
    total = total | (ulong)lowBits;

    remainder = (uint)(total % 10L);
    return (uint)(total / 10L);
}

我从中找到了一个优雅的解决方案

基本上

decimal v=2.4200M;

v.ToString("#.######"); // Will return 2.42. The number of # is how many decimal digits you support.
请尝试以下代码:

string value = "100";
value = value.Contains(".") ? value.TrimStart('0').TrimEnd('0').TrimEnd('.') : value.TrimStart('0');
使用哈希符号仅在必要时显示尾随的0。请参阅下面的测试

decimal num1 = 13.1534545765;
decimal num2 = 49.100145;
decimal num3 = 30.000235;

num1.ToString("0.##");       //13.15%
num2.ToString("0.##");       //49.1%
num3.ToString("0.##");       //30%

我使用此代码来避免G29科学符号:

public static string DecimalToString(this decimal dec)
{
    string strdec = dec.ToString(CultureInfo.InvariantCulture);
    return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec;
}
编辑:使用系统文化信息.NumberFormat.NumberDecimalSeparator:

public static string DecimalToString(this decimal dec)
{
    string sep = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    string strdec = dec.ToString(CultureInfo.CurrentCulture);
    return strdec.Contains(sep) ? strdec.TrimEnd('0').TrimEnd(sep.ToCharArray()) : strdec;
}
您可以设置为:

decimal decNumber = 23.45600000m;
Console.WriteLine(decNumber.ToString("0.##"));

非常简单的答案是使用TrimEnd。这是结果

double value = 1.00;
string output = value.ToString().TrimEnd('0');
输出为1
如果我的值为1.01,则我的输出将为1.01。以下代码可用于不使用字符串类型:

int decimalResult = 789.500
while (decimalResult>0 && decimalResult % 10 == 0)
{
    decimalResult = decimalResult / 10;
}
return decimalResult;

返回789.5

如果要保留十进制数,请尝试以下示例:

number = Math.Floor(number * 100000000) / 100000000;
这很简单

decimal decNumber = Convert.ToDecimal(value);
        return decNumber.ToString("0.####");
测试


干杯:

尝试做更友好的脱麦芽糖浆解决方案:

输出:

=>1
=>1.000000023
=>1.000000023
=>
这个怎么样:

public static string TrimEnd(this decimal d)
    {
        string str = d.ToString();
        if (str.IndexOf(".") > 0)
        {
            str = System.Text.RegularExpressions.Regex.Replace(str.Trim(), "0+?$", " ");
            str = System.Text.RegularExpressions.Regex.Replace(str.Trim(), "[.]$", " ");
        }
        return str;
    }

最初的记录类型是string??请参见我的答案:string。带有“G”的格式应该得到您想要的。。我用标准数字格式的链接更新了我的答案。非常有用。十进制可以转换为double,double的默认ToString会发出后面的零。读取时,与将G作为字符串格式传递给ToString函数相比,读取大量记录的性能成本可能更低。不应将十进制转换为双精度,这将失去意义,并可能导致两次舍入误差。可以使用子字符串方法,但根据这里发布的问题,我看不到任何这样的要求=不使用“.”的地区如何?对于10.0的偶数倍数,这一点非常糟糕。@BenVoigt所说的完全正确,因为examle 12300.00将被削减到123。另一个似乎不受欢迎的效果是,一些数字,如0.00,被一直修剪到空字符串,尽管这个数字是10.0的整数倍的特例。@Damien,是的,请注意,对于这些钱包,除非你做10亿条记录,否则你不会感觉到任何东西,首先是因为双精度更快,其次是,因为向ToString函数传递字符串格式比不传递参数要耗费更多的性能。同样,除非处理数以百万计的记录,否则您不会有任何感觉。您不必指定G,因为z double.ToString默认情况下会删除尾随的零。请注意0.000001之类的值。这些将以指数表示法表示。double.Parse0.00000001,System.Globalization.CultureInfo.getcultureinfo-US.ToString将给出1E-08,结果是永远不要这样做。通常,使用小数的原因是因为您精确地表示一个数字,而不是近似地表示一个双精度数字。诚然,这个浮点错误可能很小,但可能会导致显示不正确的数字,尤其是将128位数据类型十进制转换为


64位数据类型双用于格式化,不是一个好主意!var d=2.0m;d、 托斯特林@戴夫·希利尔——我明白了,我已经更正了我的答案。干杯[添加了明确的“精度说明符”]注意0.000001之类的值。G29格式将以尽可能短的方式显示它们,因此它将切换到指数表示法。string.Format{0:G29},decimal.Parse0.00000001,System.Globalization.CultureInfo.GetCultureInfo-US将给出1E-08作为结果注意G0的工作方式与G29类似,因为,如上所述,当精度说明符为零时,使用类型的默认精度为29表示小数。@Konrad-有没有办法避免对小数点后5位或6位的数字使用科学记数法?这个答案是正确的,因为与这个问题的所有其他答案不同,甚至整个主题实际上都在工作,并且做OP所要求的事情。0的数量是一个吗此处的确切数量或仅涵盖大多数预期值?MSDN声明比例因子隐式为数字10,提升为0到28之间的指数,我理解为十进制数最多超过小数点28位。任何数量的零>=28都可以。这是最好的答案!答案中的数字有34位数字,1后面跟着33位0-s,但这与一个有29位数字,1位1,28位0-s的数字产生了完全相同的十进制实例。就像@ThomasMaterna在评论中说的那样。没有系统。十进制可以有超过29位数字,前导数字大于79228。。。总共只能有28个数字。如果需要更多的尾随零,请乘以1.000…m,而不是除以。此外,Math.Round可以去掉一些零,例如Math.Round27.40000m,2给出27.40m,所以只剩下一个零。这是一个很好的技巧,但在Mono上不起作用,也不能保证在.NET+1的功能版本上使用唯一依赖于稳定、有文档记录的行为的答案。你应该在那里放28个字符,请参见。为什么有两个答案,我的朋友?那不使用“.”的区域设置呢?与本文中的其他方法相比,这根本不是一个选项。转换为字符串并返回始终是操纵数字的坏选项,至少因为localeI曾尝试过这一路线,但对其进行了进一步优化,因此它比您的速度快得多,例如,如果a和b都为零,则在每次迭代中不分割hi和mid INT。然而后来我发现,这是一个很好的答案。它非常简单,您可以准确地看到正在发生的事情,而不是使用神奇的字符串格式化程序。很好,但它不适用于使用逗号作为小数分隔符的区域性。您需要使用Culture.NumberFormat.NumberDecimalSeparatorBest方法。其他一切都是不必要的复杂。请记住始终检查您的数字是否包含小数点。要成为扩展名,请在参数:public static string decismaltostring此小数点之前删除此参数。非常感谢您的评论。我已经用新版本的提示更新了答案。不是答案。您不是在删除尾随零,而是在删除精度。您建议的方法num1.ToString0。应该返回13.15345765无更改,因为没有任何尾随的零。这正是我显示三个建议输入的答案的原因,这样用户就可以看到我的解决方案是如何工作的。即使您列出了建议输入,它也不会回答问题。如果可以,我将对此进行10次投票。正是我需要的!这个问题的完美答案。我认为这是最好的答案。关于它会降低精度的评论是正确的,但这不是问题所在。最重要的是,这是我需要的。我的用户通常会输入整数,可能类似于2.5,但我需要支持小数点后的3位数字。所以我想给他们输入的,而不是一堆他们没有输入的零。e、 g.,Console.Write$num3={num3:0.};=>num3=30请注意,如果v是0m,则代码的结果是一个空字符串,而不是0.Yes。答案应该是0。很好,但链接已断开-现在转到站点主页-因此您可能会将其删除。如果您的值的小数位数超过格式字符串,您将丢失数据。decimal test=0.00000005m;Console.WriteLinetest.ToString0。;要做到这一点,你应该放二十八个而不是两个。是的,我误解了他的问题=/如果值=100呢?@Raj De Inno即使值是1.00,它给出的输出也是1。不是1
private static decimal Trim(this decimal value)
{
    var s = value.ToString(CultureInfo.InvariantCulture);
    return s.Contains(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator)
        ? Decimal.Parse(s.TrimEnd('0'), CultureInfo.InvariantCulture)
        : value;
}

private static decimal? Trim(this decimal? value)
{
    return value.HasValue ? (decimal?) value.Value.Trim() : null;
}

private static void Main(string[] args)
{
    Console.WriteLine("=>{0}", 1.0000m.Trim());
    Console.WriteLine("=>{0}", 1.000000023000m.Trim());
    Console.WriteLine("=>{0}", ((decimal?) 1.000000023000m).Trim());
    Console.WriteLine("=>{0}", ((decimal?) null).Trim());
}
=>1
=>1.000000023
=>1.000000023
=>
public static string TrimEnd(this decimal d)
    {
        string str = d.ToString();
        if (str.IndexOf(".") > 0)
        {
            str = System.Text.RegularExpressions.Regex.Replace(str.Trim(), "0+?$", " ");
            str = System.Text.RegularExpressions.Regex.Replace(str.Trim(), "[.]$", " ");
        }
        return str;
    }