OverflowException仅在VB.net中,而不在C#中
为了自学目的,我试图找到一种方法来创建一个高度自己的地图。 我google了一下,发现了一个创建伪随机数的函数。
public static float Noise(int x) { x = (x << 13) ^ x; return (1f - ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7FFFFFFF) / 1073741824.0f); }
由于我选择的语言是VB.net,我将此函数翻译为:
Private Function Noise(ByVal x As Integer) As Double x = (x << 13) Xor x Return (1.0R - ((x * (x * x * 15731.0R + 789221.0R) + 1376312589.0R) And &H7FFFFFFF) / 1073741824.0R) End Function
如果我使用C#版本,我会得到x值从1到100的结果。如果我使用VB.net版本,我得到x <6的值,但是x = 6的OverFlowException
。 当我拆开这个function的部分时,我发现了溢出的部分
(x * x * 15731.0R)
所以,我的第一个问题是:为什么我在VB.net中获得了OverflowException
而在C#中没有? 如果中间结果对于包含变量来说太大,那么无论我使用何种语言,它都应该太大。
我的第二个问题是:我还能做些什么才能让它在VB.net中运行?
谢谢您的回答。
为什么我在VB.net中获得了OverflowException而在C#中没有?
因为VB项目默认检查溢出,而C#没有。 如果要将项目设置为检查溢出或将代码放在已checked{ }
块中,您将在C#中看到相同的exception:
public static float Noise(int x) { x = (x << 13) ^ x; checked{ return (1f - ((x * (x * x * 15731) + 1376312589) & 0x7FFFFFFF) / 1073741824.0f); } }
我该怎么做才能使它在VB.net中运行?
我怀疑它对C#“有用”。 由于它无声地溢出,你可能会得到不正确的结果。
但是,您可以通过将x
转换为double来防止溢出:
Private Function Noise(ByVal x As Integer) As Double x = (x << 13) Xor x Dim y As Double = x Return (1.0R - ((y * (y * y * 15731.0R) + 1376312589.0R) And &H7FFFFFFF) / 1073741824.0R) End Function
您还可以打开VB项目的“删除整数溢出检查”属性,但这是项目范围设置。 VB目前没有办法像C#那样关闭特定代码行的溢出检查。
无论你做什么,我都会彻底测试它,因为你正在计算一个浮点值,对它进行位掩码( And &H7FFFFFFF
)然后除以另一个浮点值。 混合整数和浮点数学可能非常棘手。
另请注意,您的两个代码段并不等效。 当VB返回Double
时,C#函数返回一个float
。 你在VB中使用浮点文字但在C#中使用整数文字。 它似乎不是一个很大的区别,但它可以意外地改变数学。
就像D Stanley指出的那样,VB.net中OverFlowException
的原因是VB.net会自动对整数运算进行溢出检查,而C#则不行。
如果其他人有兴趣让它在VB.net中工作,您可以执行以下操作:
将此结构添加到项目中
Public Structure LongToIntegerNoOverflow Public LongValue As Long Public IntValue As Integer End Structure
并将Noisefunction更改为
Private Function Noise(ByVal x As Integer) As Single Dim x1 As Long Dim x2 As LongToIntegerNoOverflow Dim x3 As LongToIntegerNoOverflow Dim x4 As Long x1 = (x << 13) Xor x x2.LongValue = x1 * x1 * 15731 + 789221 x3.LongValue = x1 * x2.IntValue + 1376312589 x4 = x3.IntValue And &H7FFFFFFF Return (1.0R - x4 / 1073741824.0R) End Function
在这些更改之后,我在VB.net和C#中得到了相同的结果。
- Post FromBody始终无效
- Oracle.ManagedDataAccess和ORA-01017:用户名/密码无效; 登录被拒绝
- 如何在C#中的WebBrowser控件中加载本地HTML页面
- asp.net 5.0 project.json中RavenDB.Client引用的问题
- .NET中的IMAPI2 MsftFileSystemImage在创建ISO时不释放文件
- TimeZoneInfo.ConvertTimeToUtc问题
- 结构图和generics类型
- 如何将条件编译符号(DefineConstants)传递给msbuild
- 这两个HttpContext.Current.Session和Session – asp.net 4.0有什么区别