八进制值会引发编译器错误,但常量不会,并且它们是相同的值

发布于 2024-11-29 20:35:02 字数 765 浏览 0 评论 0原文

这是其中之一,为什么会发生这样的问题。我需要获取一个 Int32 值,并将其与其类型的最小值进行“或”运算(这是移植 10 年前的 VBA 应用程序的结果)。

这会破坏编译器并发出警告和错误,首先是破坏的代码,然后是有效的代码,然后是错误消息。

破坏编译器(请忽略变量的名称,VBA 类型很长,我使用 Int32):

UInt32Val = UInt32Val | 0x80000000;

这不会破坏编译器:

UInt32Val = UInt32Val | Int32.MinValue;

我得到的错误如下:

  1. 在符号扩展操作数上使用按位或运算符;首先考虑转换为较小的无符号类型
  2. 无法将类型“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:

  1. Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first
  2. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉南桥 2024-12-06 20:35:02

0x80000000 是一个文字,因此它的类型必须由 C# 规则确定。您还没有使用符号,编译器不会为您推断符号,因此它会尝试找到适合该数字的最小数据类型,就好像它是正数一样。在本例中,它是 uint,当您 | 一个 int 和一个 uint 在一起时,结果是

在第二种情况下,Int32.MinValue 被声明为 int,并且 | 两个 int 的结果是另一个int

如果您想使用文字,可以先对其进行强制转换:

Int32Value = Int32Value | unchecked((int)0x80000000);

请注意 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 | an int and a uint together, the result is a long.

In the second case, Int32.MinValue is declared as an int, and |ing two ints results in another int.

If you want to use the literal, you can cast it first:

Int32Value = Int32Value | unchecked((int)0x80000000);

Note the unchecked syntax: 0x80000000 would normally overflow an int (because it's actually a positive number until those bits are stored in an int).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文