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);
}