八进制值会引发编译器错误,但常量不会,并且它们是相同的值
这是其中之一,为什么会发生这样的问题。我需要获取一个 Int32 值,并将其与其类型的最小值进行“或”运算(这是移植 10 年前的 VBA 应用程序的结果)。
这会破坏编译器并发出警告和错误,首先是破坏的代码,然后是有效的代码,然后是错误消息。
破坏编译器(请忽略变量的名称,VBA 类型很长,我使用 Int32):
UInt32Val = UInt32Val | 0x80000000;
这不会破坏编译器:
UInt32Val = UInt32Val | Int32.MinValue;
我得到的错误如下:
- 在符号扩展操作数上使用按位或运算符;首先考虑转换为较小的无符号类型
- 无法将类型“long”隐式转换为“int”。存在显式转换(您是否缺少强制转换?)
据我了解,0x80000000 和 Int32.MinValue 都等于 -2147483648。
我对这个移植的一个大问题是,VBA 应用程序使用 long 和 int,它们分别转换为 .NET 作为 Int32 和 Int16,并且正在进行大量的位移和交换。
因此,我的想法是确保变量的大小和有符号属性相同,以确保我在移植的应用程序中获得与 VBA 应用程序中相同的值。
无论如何,从概念上讲,如果我能够通过将原始八进制值交换为常量来修复编译器问题,我是否隐藏了问题?我即将运行这两个应用程序并开始比较值,但我真的想了解这里发生了什么。
谢谢。
This is one of those, why does it happen kind of questions. I need to take an Int32 value and "OR" it with the minimum value of its type (as a resulting of porting a 10 year old VBA application).
This breaks the compiler with a warning and an error, first the code that breaks, then the code that works and then the error message.
Breaks compiler (please disregard the name of the variable, the VBA type is long and I am using Int32):
UInt32Val = UInt32Val | 0x80000000;
This does not break the compiler:
UInt32Val = UInt32Val | Int32.MinValue;
The errors I get are as follows:
- Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first
- Cannot implicitly convert type 'long' to 'int'. An explicit conversion exists (are you missing a cast?)
It is my understanding that both 0x80000000 and Int32.MinValue equal -2147483648.
My big issue with this port is that the VBA application is using long and int which translate to .NET as Int32 and Int16 respectively, and there is a lot of bit shifting and swapping going on.
So my thinking is to make sure the size and signed property of the variables are the same to make sure I get the same values in the ported application as I do in the VBA application.
At any rate, conceptually, am I hiding a problem if I am able to fix the compiler issue by swapping an original octal value for a constant? I'm about to run both apps and start comparing values, but I really want to understand what is happening here.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
0x80000000 是一个文字,因此它的类型必须由 C# 规则确定。您还没有使用符号,编译器不会为您推断符号,因此它会尝试找到适合该数字的最小数据类型,就好像它是正数一样。在本例中,它是
uint
,当您|
一个int
和一个uint
在一起时,结果是长
。在第二种情况下,
Int32.MinValue
被声明为int
,并且|
两个int
的结果是另一个int
。如果您想使用文字,可以先对其进行强制转换:
请注意
unchecked
语法:0x80000000 通常溢出一个int
(因为它实际上是正数,直到这些位存储在 int 中)。0x80000000 is a literal, and thus its type must be determined by the rules of C#. You haven't used a sign, and the compiler will not infer one for you, so it tries to find the smallest datatype that will fit this number as if it were positive. In this case, that's
uint
, and when you|
anint
and auint
together, the result is along
.In the second case,
Int32.MinValue
is declared as anint
, and|
ing twoint
s results in anotherint
.If you want to use the literal, you can cast it first:
Note the
unchecked
syntax: 0x80000000 would normally overflow anint
(because it's actually a positive number until those bits are stored in anint
).