c# - BigInteger 解析指数大于 1000 的科学记数法,结果为 9999
问题描述
我一直在为为什么这段代码似乎可以正常工作而苦苦挣扎。对我来说,这看起来像是BigInteger
课堂上的一个错误,但我可能是错的。
using System.Numerics;
using System.Globalization;
BigInteger result;
if (!BigInteger.TryParse("2.36e6007", NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint, null, out result)) result = 0;
Debug.WriteLine(result.ToString("0.00e0000"));
我始终得到2.36e9999
结果,无论我使用什么数量级总是9999
. 我不确定这是一个错误还是我在这里做错了什么。我在解析后尝试了一个断点并检查了该值,它确实9999
有零,所以如果它是一个错误,它就在BigInteger.TryParse
解决方案
这不起作用的原因与其说是一个错误本身,不如说是一个限制ParseNumber
if (exp > 1000)
{
exp = 9999;
while (ch >= '0' && ch <= '9')
{
ch = *++p;
}
}
如您所见,任何超过的指数1000
都将默认为 的指数9999
。
一种方法(取决于您的需要)是自己解析指数并BigInteger
从其组成部分创建指数。这样做的缺点是它不会处理超出其非常狭窄范围的任何变化(您需要添加胡椒和盐来调味)。它也可能会慢很多。
给定
public static (decimal multiplier, int exponent) Decompose(string value)
{
var split = value.Split('e');
return (decimal.Parse(split[0]), int.Parse(split[1]));
}
public static int GetDecimalPlaces(decimal value)
=> BitConverter.GetBytes(decimal.GetBits(value)[3])[2];
public static BigInteger ParseExtended(string value)
{
var (multiplier, exponent) = Decompose(value);
var decimalPlaces = GetDecimalPlaces(multiplier);
var power = (int) Math.Pow(10, decimalPlaces);
return (BigInteger.Pow(10, exponent) * (int) (multiplier * power)) / power;
}
用法
Console.WriteLine(ParseExtended("2.36e6007").ToString("0.00e0000"));
输出
2.36e6007
注意:这并不是所有问题的解决方案,它缺乏适当的容错能力,并且只是可能解决方案的一个示例。
推荐阅读
- python - 如何在 Python 中使用数组输入用户的字符列表
- node.js - 有没有办法在 JSdoc 中指定通配符导出?
- jquery - 如何解决网站自动放大问题?
- tensorflow - tf.layers.Conv1D 与 tf.keras.layers.Conv1D
- html - 未从 Angular 7 中的 Firebase 检索数据
- javascript - 不能将 Chai.js 中的期望与 Nightwatch 一起使用
- javascript - 通过 id 更改表内的值
- node.js - TypeError:使用 findOneAndRemove() 时无法读取未定义的属性“_id”
- c# - (datatype, datatype) x = (value, value) 在 C# 中是什么意思?x 的实际数据类型是什么?
- android - Rxjava - 用批处理迭代列表