C#/VB.NET分辨率匹配指定宽高比的算法正确性及修正问询
正确判断分辨率是否符合指定宽高比(C#/VB.NET)
首先直接说结论:你的原算法并不适用于所有场景,它存在明显的逻辑缺陷,会在多种情况下给出错误结果。
原算法的问题分析
你原代码通过检查分辨率宽度是否能被宽比整除、高度是否能被高比整除来判断比例,但这个逻辑只在指定的宽高比是最简互质形式(比如16:9、4:3)且分辨率是该比例的整数倍时才有效。一旦出现以下情况,就会出错:
- 当传入的宽高比不是最简形式时:比如你传入
Point(4,2)(等价于2:1),而分辨率是Size(2,1),原算法会返回false,但实际上这个分辨率完全符合2:1的比例。 - 极端无效输入未处理:比如分辨率宽/高为0,或者宽高比的X/Y为0时,原算法会抛出异常或返回错误结果。
你提到的“640x480被判定为16:9”的情况,其实原算法应该返回false(因为480%9=3≠0),可能是你测试时的输入有误,但这不妨碍原算法核心逻辑的错误。
正确的实现方式
判断两个比例是否相等的标准方法是交叉相乘——避免使用浮点除法带来的精度误差,直接验证 宽度 × 高比 == 高度 × 宽比。同时我们需要加入无效输入的校验,避免出现除以0或其他异常。
C# 修正代码
/// <summary> /// Determine whether the source resolution belongs to the specified aspect ratio. /// </summary> /// <param name="resolution">The source resolution (width and height must be positive).</param> /// <param name="aspectRatio">The aspect ratio (X and Y must be positive).</param> /// <returns> /// <see langword="true"/> if the source resolution matches the specified aspect ratio; /// otherwise, <see langword="false"/>. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if resolution width/height is non-positive, or aspect ratio X/Y is non-positive. /// </exception> public static bool ResolutionIsOfAspectRatio(Size resolution, Point aspectRatio) { // Validate inputs to avoid invalid calculations if (resolution.Width <= 0 || resolution.Height <= 0) throw new ArgumentOutOfRangeException(nameof(resolution), "Resolution width and height must be positive."); if (aspectRatio.X <= 0 || aspectRatio.Y <= 0) throw new ArgumentOutOfRangeException(nameof(aspectRatio), "Aspect ratio X and Y must be positive."); // Cross-multiply to compare ratios without floating-point errors return (long)resolution.Width * aspectRatio.Y == (long)resolution.Height * aspectRatio.X; }
VB.NET 修正代码
''' <summary> ''' Determine whether the source resolution belongs to the specified aspect ratio. ''' </summary> ''' <param name="resolution">The source resolution (width and height must be positive).</param> ''' <param name="aspectRatio">The aspect ratio (X and Y must be positive).</param> ''' <returns> ''' True if the source resolution matches the specified aspect ratio; ''' otherwise, False. ''' </returns> ''' <exception cref="ArgumentOutOfRangeException"> ''' Thrown if resolution width/height is non-positive, or aspect ratio X/Y is non-positive. ''' </exception> Public Shared Function ResolutionIsOfAspectRatio(resolution As Size, aspectRatio As Point) As Boolean ' Validate inputs to avoid invalid calculations If resolution.Width <= 0 OrElse resolution.Height <= 0 Then Throw New ArgumentOutOfRangeException(NameOf(resolution), "Resolution width and height must be positive.") End If If aspectRatio.X <= 0 OrElse aspectRatio.Y <= 0 Then Throw New ArgumentOutOfRangeException(NameOf(aspectRatio), "Aspect ratio X and Y must be positive.") End If ' Cross-multiply to compare ratios without floating-point errors Return CLng(resolution.Width) * aspectRatio.Y = CLng(resolution.Height) * aspectRatio.X End Function
关键细节说明
- 使用
long(C#)或CLng(VB.NET)进行类型转换:避免整数溢出问题(比如超大分辨率的计算可能超过int的范围,转换为长整数更安全)。 - 输入校验:确保分辨率和宽高比的数值都是正数,避免出现无意义的比例判断或运行时异常。
- 交叉相乘的逻辑:无论传入的宽高比是否是最简形式,都能正确判断比例是否匹配,比如传入
Point(32,18)(等价于16:9),分辨率Size(1920,1080)依然会返回true。
示例用法
Size resolution = new Size(1920, 1080); Point aspectRatio = new Point(16, 9); bool result = ResolutionIsOfAspectRatio(resolution, aspectRatio); Console.WriteLine(result); // Output: True // Test non-simplified aspect ratio Point nonSimplifiedRatio = new Point(32, 18); result = ResolutionIsOfAspectRatio(resolution, nonSimplifiedRatio); Console.WriteLine(result); // Output: True // Test incorrect ratio Point wrongRatio = new Point(4, 3); result = ResolutionIsOfAspectRatio(resolution, wrongRatio); Console.WriteLine(result); // Output: False
内容的提问来源于stack exchange,提问作者ElektroStudios
相关产品推荐
相关产品推荐

