C# 如何检测潜在的溢出 OK,考虑下面的场景: public static bool TryGetNearestRationalNumber(double target, double precision, out RationalNumber nearest) { //implements continued fractions to solve the problem. Only relevant code is shown. var integerPart = (long)target; //necessary for algorithm var fractionalPart = target - integerPart; //necessary for algorithm, .... }
C# 如何检测潜在的溢出 OK,考虑下面的场景: public static bool TryGetNearestRationalNumber(double target, double precision, out RationalNumber nearest) { //implements continued fractions to solve the problem. Only relevant code is shown. var integerPart = (long)target; //necessary for algorithm var fractionalPart = target - integerPart; //necessary for algorithm, .... },c#,C#,RationaNumber内部使用两个Int64有符号整数来表示分子和分母。我希望我的方法抛出一个System.OverflowException,如果试图近似的数字大于或小于可由RationalNumber表示的最大或最小数字,即long.MaxValue和long.MinValue 我的第一次尝试非常简单和天真: public bool TryGetNearestRationalNumber(double target, double precision, out Foo foo) {
RationaNumber
内部使用两个Int64
有符号整数来表示分子和分母。我希望我的方法抛出一个System.OverflowException
,如果试图近似的数字大于或小于可由RationalNumber
表示的最大或最小数字,即long.MaxValue
和long.MinValue
我的第一次尝试非常简单和天真:
public bool TryGetNearestRationalNumber(double target, double precision, out Foo foo)
{
//check overflow here
if (target > long.MaxValue || target < long.MinValue)
throw new OverFlowExcetpion();
//implements continued fractions to solve the problem. Only relevant code is shown.
var integerPart = (long)target; //necessary for algorithm
var fractionalPart = target - integerPart; //necesarry for algorithm,
...
}
问题是这也行不通。它确实适用于最大值溢出TryGetNearestRationalNumber(1f+long.MaxValue,precision,nearest)
,但在最小值溢出TryGetNearestRationalNumber(-1f+long.MinValue,precision,nearest)
时再次失败。除此之外,这个解决方案还远远不够完美,因为给定一个足够大的目标
,溢出可以在不改变符号的情况下发生
我确信必须有一个完全明显和愚蠢的方式来做这件事,我完全错过了。有人能告诉我解决这个问题的方法吗?这个关键字通过抛出OverflowException来帮助代码捕获在运行时发生的溢出
// Checked block.
checked
{
int i3 = 2147483647 + 10; // throws
Console.WriteLine(i3);
}
在另一个线程上与usr讨论之后,我们可以推断,为了捕获double中long值下界的溢出,必须转到1025d-long.MinValue
。因此,您的下限似乎必须考虑十进制类型的尾数大小,才能正确处理回long
的强制转换
作为一种解决方法,它非常讨厌,而且不适合编写非常可读的代码……考虑我的场景:我有一个双
类型的参数,我必须弄清楚它是否会作为长
溢出。如果我传递给方法-1d+long.MinValue
,当我将其转换为long(long)(-1d+long.MinValue)
时,即使在选中的上下文中,我仍然不会得到OverFlowException
。但它确实抛出了1d+long.MaxValue
。这真的很奇怪:我现在正在研究它,因为我认为精度损失是因为您将-1d+long.MinValue
保持为双格式,但精度损失不会被选中的关键字捕获。如果您编写var x=((long))的话,代码就会工作-1d+长最小值)代码>,这太糟糕了。是的,这是因为您正在为计算的所有成员使用long,但是var x=(long)(-1d+long.MinValue)代码>不会抛出,因为双到长转换不考虑数据丢失。是的,但这对我没有帮助。我需要知道double
参数是否溢出。您的代码正在直接传入一个long
。
// Checked block.
checked
{
int i3 = 2147483647 + 10; // throws
Console.WriteLine(i3);
}