gpt4 book ai didi

C# 十进制(字符串类型)在最后一个字符处四舍五入

转载 作者:行者123 更新时间:2023-12-05 03:30:09 29 4
gpt4 key购买 nike

这似乎是重复的,但我找不到合适的答案(问题足够接近但是..)我有一个代表十进制数的字符串,它总是有很多小数位,至少 20,有时最多 2000 (代表特定的验证计算,即像'是数字 135 到 147 素数 X 等 - 只是为了给你一些上下文)

例如:

123.829743892473218762329384241002373824970132871283923423961723816273823447623528347662123874999

我正在尝试四舍五入到倒数第二位。我建立了一个(有点)有效的小方法。但是(如上例所示)..如果最后一位数字> 4且倒数第二位数字为9,这意味着我还必须提高前一位数字,并删除最后一位0,如果-那么前一位数字也是9,这意味着我还必须提高前一位数字,依此类推。

例如

123.99999 // must become 124
123.823467283762378 // must become 123.82346728376238
123.823467283762398 // must become 123.8234672837624 (notice the last 0 has gone)
123.09999999 // must become 123.1 (notice no trailing zeros needed..)
122.00000009 // must become 122.0000001
124.81379281 // must become simply 124.8137928
129.07872345 // must become 129.0787235
129.07872344 // must become 129.0787234

等等等等。换句话说,它只是通过仅删除最后一位数字来舍入数字(这是一个字符串!!),但继续向左舍入直到不需要为止。仅在最后一个 小数 位需要舍入(如果数字是整数则不需要)并且规则是如果最后一位的数字 >4 则数字被截断并且前一个(左边)数字被保留增加 1,忽略尾随零(如果有),规则继续到整数部分的最后一位(即 123.99999 变为 124,但整数 124 保持原样等)。

有人可以帮我为此构建一个字符串扩展吗?

using System;
public class Example
{
public string round(string LargeDecimal)
{
Console.WriteLine("Number as string is: " + LargeDecimal);

int lastDigit = (int)char.GetNumericValue(LargeDecimal[LargeDecimal.Length -1]); // get last character
Console.WriteLine("lastDigit = " + lastDigit.ToString());

string number = LargeDecimal.Remove(LargeDecimal.Length - 1); // delete last character
Console.WriteLine("Now number is " + number);

if (lastDigit > 4)
{
Console.WriteLine("Last digit {0} was >4", lastDigit.ToString());
int newLastDigit = (int)char.GetNumericValue(number[number.Length -1]);
Console.WriteLine("Next to left last digit is {0} which will be raised by 1 and become {1}", newLastDigit.ToString(), (newLastDigit +1).ToString());
newLastDigit += 1; //increase by one
number = number.Remove(number.Length - 1); // delete ex-penultimate (and now last) character
number = number + newLastDigit.ToString();
return number; // and add a digit increased by 1
}
else
{
return LargeDecimal.Remove(LargeDecimal.Length - 2);
}
}
public Example()
{}
}

public class Program
{
public static void Main(string[] args)
{
string myNumber = "124.2398478278268985738276523548769";

Example myExample = new Example();

string result = myExample.round(myNumber);

Console.WriteLine("Now I have " + result);
}
}

最佳答案

嗯,这很棘手,因为有 2000 位小数,您不能使用 decimal。所以也许有比这更简单的东西,但它可能对你有用(.NET fiddle demo):

public static string RoundLongNumber(this string input)
{
if (!ValidLongNumber(input, out bool isInteger) || isInteger) return input;
int index = input.IndexOf('.');
string part1 = input.Remove(index);
string part2 = input.Substring(index + 1);
StringBuilder sb = new StringBuilder(part2);

while(true)
{
if (LastInt() <= 4)
{
return BuildNumber();
}

sb.Length = sb.Length - 1; // remove last
int lastInt = LastInt() + 1;
while (lastInt == 10)
{
sb.Length = sb.Length - 1;
if (sb.Length == 0)
{
// just integer remaining
int num = int.Parse(part1);
return (++num).ToString();
}
lastInt = LastInt() + 1;
}

sb[sb.Length - 1] = (char)(lastInt + '0');
if (lastInt != 9) return BuildNumber();
}

int LastInt() => sb[sb.Length - 1] - '0';
string BuildNumber() => part1 + "." + sb.ToString();
}

private static bool ValidLongNumber(string number, out bool isInteger)
{
isInteger = true;
if (string.IsNullOrWhiteSpace(number)) return false;
int pointCount = 0;
foreach(char c in number)
{
bool isDigit = char.IsDigit(c);
bool isPoint = c == '.';
if (!isDigit) isInteger = false;
if (isPoint) pointCount++;
if(pointCount > 1 || (!isPoint && !isDigit)) return false;
}
return true;
}

这是您的示例:

public static void Main()
{
var strings = new List<string> {
"123.99999", // must become 124
"129.99999", // must become 130
"123.823467283762378", // must become 123.82346728376238
"123.823467283762398", // must become 123.8234672837624 (notice the last 0 has gone)
"123.09999999", // must become 123.1 (notice no trailing zeros needed..)
"122.00000009", // must become 122.0000001
"124.81379281", // must become simply 124.8137928 >>> Why? Should remain same
"129.07872345", // must become 129.0787235
"129.07872344", // must become 129.0787234 >>> Why? Should remain same
};

IEnumerable<string> results = strings.Select(s => s.RoundLongNumber());
foreach(var res in results)
{
Console.WriteLine(res);
}
}

请注意,这两个结果是不同的,但要么您没有解释该规则,要么您的期望是错误的:

124.81379281 // must become simply 124.8137928
129.07872344 // must become 129.0787234

为什么?据我了解,两者应该保持不变。

关于C# 十进制(字符串类型)在最后一个字符处四舍五入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70901656/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com