(C#) 我应该在计算中防范 Infinity/-Infinity 吗? IE。抛出溢出异常?
(C#) Should I Guard Against Infinity/-Infinity in my calculations? I.e. Throw an Overflow Exception?
在 C#.
中寻找关于 Infinity/-Infinity 的一些建议
我目前正在为 Rectangle/Circle 等形状构建几何体 类。
用户将分别为 Width/Depth 和直径提供输入。
这些属性将是 double
,我知道如果你将 double.MaxValue
乘以 2,而不是明确地 溢出 ,那么你会得到+无限等
每个形状 类 都将具有其他属性,例如面积、周长等。
因此,即使提供的维度小于 MaxValue,如果用户愿意,计算值也有可能是一个巨大的数字:
例如Math.PI x Math.Pow(diameter, 2) / 4
=> Math.PI x Math.Pow(double.MaxValue, 2) / 4
(即,即使用户提供了 MaxValue 作为输入,此方法也会导致 +infinity。)
我的问题是我是否应该一直提防无穷大?
如果用户值或计算值进入无穷大,我是否应该抛出异常(OverflowException)?
看起来它可能是 code smell 检查这些几何 [=] 中的 every property/method 的无穷大50=]...
有没有更好的方法?
public double Area
{
get
{
double value = Math.PI * Math.Pow(this.diameter, 2) / 4;
if (double.IsInfinity(value)
{
throw new OverflowException("Area has overflowed.");
}
}
}
public double Perimeter
{
get
{
double value = Math.PI * this.diameter;
if (double.IsInfinity(value)
{
throw new OverflowException("Perimeter has overflowed.");
}
}
}
感谢您的时间和想法!
干杯。
Each of the shape classes will have additional properties such as Area, Perimeter etc. Therefore, even if the provided dimensions are less than MaxValue, there is a chance that computed values could be a huge number if the user was so inclined
double max 是 1.7976931348623157E+308
,担心用户输入的几何数据会达到该限制是没有意义的。简单地归还无穷大,它可能永远不会发生。换句话说,以微米为单位,到比邻星的距离约为 4,014 × 10^22
,因此您会发现担心这个是多么浪费时间。
为了至少给用户一个合理的选择,你可以让他定义你的几何环境中的一个单位代表什么;一微米、毫米、米、公里、光年、秒差距等等,所以他总是保持合理的比例。
从概念上讲,您遇到了设计问题。导致无限区域的值会导致您的形状处于无效状态。
例如,假设所讨论的形状是圆形。任何传递的导致 Area > double.MaxValue
的值都是无效状态。换句话说,任何值 diameter
其中 Math.PI * Math.Pow(diamater, 2) > double.MaxValue
无效。
为 diameter
求解 double.MaxValue = Math.PI * Math.Pow(diamater, 2)
(它是 1.5129091144565236E+154
,欢迎您验证我的数学),并在构造函数中检查
private const double MaxDiameter = 1.5129091144565236E+154;
Circle(double diameter)
{
if (diameter > MaxDiameter)
{
throw ArgumentOutOfRangeException();
}
}
--
None 以上可能很重要
在实践中,请考虑以下内容。已知宇宙的直径大约是30千兆秒差距,换算成普朗克长度(我能想到的最小距离单位)大约是5.7e61,也就是远,far低于double.MaxValue
.
我不担心您的属性会出现双重溢出。设计你的形状是明智的,这样你就可以使用你定义的单位类型,所以你总是知道你正在使用什么单位。
public Circle(Meters diamater)
public Rectangle(Meters width, Meters height)
对无限值抛出异常是一种设计选择
IMO,没有 "good answer" 这个,这取决于你想如何使用你的 classes。例如,如果目标是绘图,则防止出现巨大值可能是有意义的。
对于计算和比较,我不会是确定的。为 IEEE 标准浮点值定义的 Inf
和 -Inf
(以及 NaN
)值是一致的。 class 的用户知道您正在使用 double
,因此,期待他们的所有功能是合理的。
哪个形状的面积最大,是边长为 10 个单位的正方形还是大到您认为无限大的圆?答案是一致的,因为 Inf > 100
是 true
.
如果你打算失败,早点失败
如果您决定继续(合理的)异常路径,我建议您尽早失败。
这意味着,不要在 getter 中计算面积/周长,而是尽快计算面积和周长(如果您的 class 是不可变的,则在构造函数中,或者在相关其他属性的设置器中,例如直径/长度等)并检查当时是否有无穷大的值。
此外,还要检查 NaN
s 值。
class Circle
{
public Circle(double diameter)
{
if (double.IsInfinity(diameter) || double.IsNaN(diameter))
{
throw new ArgumentOutOfRangeException(nameof(diameter));
}
Diameter = diameter;
Perimeter = Math.PI * diameter;
if (double.IsInfinity(Perimeter))
{
throw new OverflowException("Perimeter has overflowed.");
}
}
double Diameter { get; }
double Perimeter { get; }
}
在 C#.
中寻找关于 Infinity/-Infinity 的一些建议我目前正在为 Rectangle/Circle 等形状构建几何体 类。 用户将分别为 Width/Depth 和直径提供输入。
这些属性将是 double
,我知道如果你将 double.MaxValue
乘以 2,而不是明确地 溢出 ,那么你会得到+无限等
每个形状 类 都将具有其他属性,例如面积、周长等。 因此,即使提供的维度小于 MaxValue,如果用户愿意,计算值也有可能是一个巨大的数字:
例如Math.PI x Math.Pow(diameter, 2) / 4
=> Math.PI x Math.Pow(double.MaxValue, 2) / 4
(即,即使用户提供了 MaxValue 作为输入,此方法也会导致 +infinity。)
我的问题是我是否应该一直提防无穷大? 如果用户值或计算值进入无穷大,我是否应该抛出异常(OverflowException)?
看起来它可能是 code smell 检查这些几何 [=] 中的 every property/method 的无穷大50=]... 有没有更好的方法?
public double Area
{
get
{
double value = Math.PI * Math.Pow(this.diameter, 2) / 4;
if (double.IsInfinity(value)
{
throw new OverflowException("Area has overflowed.");
}
}
}
public double Perimeter
{
get
{
double value = Math.PI * this.diameter;
if (double.IsInfinity(value)
{
throw new OverflowException("Perimeter has overflowed.");
}
}
}
感谢您的时间和想法! 干杯。
Each of the shape classes will have additional properties such as Area, Perimeter etc. Therefore, even if the provided dimensions are less than MaxValue, there is a chance that computed values could be a huge number if the user was so inclined
double max 是 1.7976931348623157E+308
,担心用户输入的几何数据会达到该限制是没有意义的。简单地归还无穷大,它可能永远不会发生。换句话说,以微米为单位,到比邻星的距离约为 4,014 × 10^22
,因此您会发现担心这个是多么浪费时间。
为了至少给用户一个合理的选择,你可以让他定义你的几何环境中的一个单位代表什么;一微米、毫米、米、公里、光年、秒差距等等,所以他总是保持合理的比例。
从概念上讲,您遇到了设计问题。导致无限区域的值会导致您的形状处于无效状态。
例如,假设所讨论的形状是圆形。任何传递的导致 Area > double.MaxValue
的值都是无效状态。换句话说,任何值 diameter
其中 Math.PI * Math.Pow(diamater, 2) > double.MaxValue
无效。
为 diameter
求解 double.MaxValue = Math.PI * Math.Pow(diamater, 2)
(它是 1.5129091144565236E+154
,欢迎您验证我的数学),并在构造函数中检查
private const double MaxDiameter = 1.5129091144565236E+154;
Circle(double diameter)
{
if (diameter > MaxDiameter)
{
throw ArgumentOutOfRangeException();
}
}
--
None 以上可能很重要
在实践中,请考虑以下内容。已知宇宙的直径大约是30千兆秒差距,换算成普朗克长度(我能想到的最小距离单位)大约是5.7e61,也就是远,far低于double.MaxValue
.
我不担心您的属性会出现双重溢出。设计你的形状是明智的,这样你就可以使用你定义的单位类型,所以你总是知道你正在使用什么单位。
public Circle(Meters diamater)
public Rectangle(Meters width, Meters height)
对无限值抛出异常是一种设计选择
IMO,没有 "good answer" 这个,这取决于你想如何使用你的 classes。例如,如果目标是绘图,则防止出现巨大值可能是有意义的。
对于计算和比较,我不会是确定的。为 IEEE 标准浮点值定义的 Inf
和 -Inf
(以及 NaN
)值是一致的。 class 的用户知道您正在使用 double
,因此,期待他们的所有功能是合理的。
哪个形状的面积最大,是边长为 10 个单位的正方形还是大到您认为无限大的圆?答案是一致的,因为 Inf > 100
是 true
.
如果你打算失败,早点失败
如果您决定继续(合理的)异常路径,我建议您尽早失败。
这意味着,不要在 getter 中计算面积/周长,而是尽快计算面积和周长(如果您的 class 是不可变的,则在构造函数中,或者在相关其他属性的设置器中,例如直径/长度等)并检查当时是否有无穷大的值。
此外,还要检查 NaN
s 值。
class Circle
{
public Circle(double diameter)
{
if (double.IsInfinity(diameter) || double.IsNaN(diameter))
{
throw new ArgumentOutOfRangeException(nameof(diameter));
}
Diameter = diameter;
Perimeter = Math.PI * diameter;
if (double.IsInfinity(Perimeter))
{
throw new OverflowException("Perimeter has overflowed.");
}
}
double Diameter { get; }
double Perimeter { get; }
}