c#XOR等于(^ =)bug? [英] c# XOR equals ( ^= ) bug?

查看:57
本文介绍了c#XOR等于(^ =)bug?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以告诉我这是不是一个错误,或者它是通过

设计吗?


我使用三重XOR交换技巧获得两个整数。我

显示三种技巧,但只有第一种才有效。

这三种都是用C ++工作的,但我在c#中得到了奇怪的结果。


技巧1 :(适用于C#)

x ^ = y;

y ^ = x;

x ^ = y ;


技术2(在C#中无法正常工作,在C ++中是否正常工作)

x ^ = y ^ = x ^ = y;


技术3在C#中无法正常工作,在C ++中是否正常工作)

x ^ =(y ^ =(x ^ = y));

这里有一些你可以剪切并粘贴到vs.net中的代码。

取消注释Swap()函数中的部分来尝试每个

技术并看到只有第一个有效。

class Class1

{

[STAThread]

static void Main(string [ ] args)

{

int x = 1;

int y = 2;

Console.WriteLine( 交换之前);

Console.WriteLine(" x:{0}",x);

Console.WriteLine(" y:{0 }",y);


交换(re fx,ref y);


Console.WriteLine(" \\\
after swap");

Console.WriteLine(" x:{0} ",x);

Console.WriteLine(" y:{0}",y);

}


public static void Swap(ref int x,ref int y){


//技术1

//这完全有效,就像在c ++中一样

x ^ = y;

y ^ = x;

x ^ = y;


//技术2

//全部放在一行。

//然而,这会产生不正确的结果

// C#,但是有效正确的C ++

//

// x ^ = y ^ = x ^ = y;


//技术3

//这也行不通。 C#应该从右边评估

//(比如C ++),但有些东西

//不起作用。

//

// x ^ =(y ^ =(x ^ = y));

}

}

Could someone please tell me if this is a bug or is it by
design?

I am using the triple XOR swap trick for two integers. I
show three "techniques", but only the first one works.
All three work in C++, but I get weird results in c#.

technique 1: (works in C#)
x ^= y;
y ^= x;
x ^= y;

technique 2 (doesn''t work correctly in C#, does in C++)
x ^= y ^= x ^= y;

technique 3 doesn''t work correctly in C#, does in C++)
x ^= (y ^= (x ^= y));
Here is some code you can cut and paste into vs.net.
Uncomment the parts in the Swap() function to try each
technique and see that only the first one works.
class Class1
{
[STAThread]
static void Main(string[] args)
{
int x = 1;
int y = 2;
Console.WriteLine("before swap");
Console.WriteLine("x: {0}", x);
Console.WriteLine("y: {0}", y);

Swap(ref x, ref y);

Console.WriteLine("\nafter swap");
Console.WriteLine("x: {0}", x);
Console.WriteLine("y: {0}", y);
}

public static void Swap(ref int x, ref int y) {

//Technique 1
// this works perfectly, just as in c++
x ^= y;
y ^= x;
x ^= y;

//Technique 2
// Put all on a single line.
// However, this produces incorrect results in
// C#, but works correctly in C++
//
//x ^= y ^= x ^= y;

//Technique 3
// This also doesn''t work. C# should evaluate
// from the right (like C++), but something
// isn''t working.
//
//x ^= (y ^= (x ^= y));
}
}

推荐答案

还有两件事:


1.我正在使用VS.Net 2003


2.调试器中似乎存在一个错误。

突出显示类似x ^ = y的表达式。用鼠标

,然后将鼠标悬停在操作员面前,将显示一个带答案的

工具提示。但是原值

改变了,从这一点开始值可能不是正确的!


要在代码中重现来自我之前的帖子:


1.加载我之前发布的帖子中的代码。取消注释

第一种技术。评论其他人。


2.在三重XOR交换的三行中的第一行设置断点。

public static Swap(ref int x,ref int y)

{

breakPoint - > x ^ = y;

y ^ = x;

x ^ = y;

}


3.在调试模式下运行代码。程序将停在

断点上。


4.现在,没有前进(没有F10),突出显示
$ b $之一b用鼠标表达式,然后将鼠标悬停在该行的

运算符(^ =)上。工具提示将显示评估的

结果,但现在x和y

中的值将永久更改。


注意:突出显示时,请确保不要在行尾突出显示

分号,否则工具提示不会显示为


Jason P.
two things more:

1. I am using VS.Net 2003

2. There seems to be a bug in the debugger.
Highlighting an expression like "x ^= y" with the mouse
and then hovering over the operator will display a
tooltip with the answer. However the original values
change and from that point on the values may not be
correct!

To reproduce in the code from my previous post:

1. Load the code from my previous post. Uncomment the
first technique. comment the others out.

2. Put a breakpoint on the first of the three lines of
the triple XOR swap.

public static Swap( ref int x, ref int y)
{
breakPoint--> x ^= y;
y ^= x;
x ^= y;
}

3. run the code in debug mode. the program will stop on
the breakpoint.

4. now, without advancing (no F10), highlight the one of
the expressions with the mouse and then hover over the
operator (^=) in that line. The tooltip will show the
results of the evaluation, but now the values in x and y
are changed permanently.

NOTE: when highlighting, make sure not to highlight the
semicolon at the end of the line or the tooltip won''t
show.

Jason P.


Michael,

感谢您回答这么快。
Michael,
Thanks for answering back so soon.
在C#中,看起来发生的事情是x在最后一步是x
与其原始值相关,因为我
得到的结果是0.


我也得到0(零)的结果,但是如你所知

它是错的。

而我们这里所拥有的基本上是旧的区别
介于逐个引用和按值调用之间。在C ++中,变量
是memorylocations。在C#中,它们是值。所以在C#中,
编译器首先获取x和y的当前值,将它们填入
相应的rvaluevariables中,然后执行。
In C# it looks like what is happening is that x is being xored with itsoriginal value in the last step, because the result I get is 0.

I too get the 0 (zero) for the result, but as you know
it''s wrong.
And what we have here is basically the old difference betweencall-by-reference and call-by-value. In C++, variables are memorylocations. In C#, they are values. So in C#, the compiler first grabs thecurrent values of x and y, filling them in for the appropriate rvaluevariables, and then does the execution.




是的,你似乎对某事有所了解,但是所有这三种技术都是功能上等同的。所以他们都应该工作。 C#应该在这个

的情况下从右边开始评估(就像C ++一样)。

另外,看一下我关于
调试器。看看你的想法。

Jason P.



Yes you seem to be on to something, however all three
techniques are functionally equivilant. So they sould all
work. C# is supposed to evaluate from the right in this
situation (just as C++ would).
Also, take a look at my other post about a bug in the
debugger. See what you think.
Jason P.


谢谢Culley先生。


主题有道理,尤其是这篇文章:


-------------------------------

我相信C ++和C#如何考虑复合赋值

运算符是有区别的。在C ++中左操作数被评估为左值并且

存储,之后

右操作数被评估为rvalue然后复合

赋值运算符

应用于左值和右值。


另一方面,C#扩展复合赋值运算符

(A ^ = B => A = A ^ B)

并将左操作数(A)首次评估为左值,而不是

右操作数

(A ^ B)作为右值然后执行赋值。在C#

A ^ = B ^ = A ^ = B等于

A = A ^(B = B ^(A = A ^ B))其中参数从左边开始评估

到右边。

-

Vladimir Nesterovsky

------- --------------------------
Thanks Mr. Culley.

The thread made sense, especially this post:

-------------------------------
I believe there is a difference how C++ and C# consider
compound assignment
operators. In C++ left operand is evaluated as lvalue and
stored, after that
right operand is evaluated as rvalue and then compound
assignment operator
is applied to lvalue and rvalue.

On the other hand C# expands compound assignment operator
(A^=B => A=A^B)
and evaluates left operand (A) first time as lvalue, than
right operand
(A^B) as rvalue and then performs assignment. In C#
A^=B^=A^=B is equal to
A=A^(B=B^(A=A^B)) where arguments are evaluated from left
to right.
--
Vladimir Nesterovsky
---------------------------------


这篇关于c#XOR等于(^ =)bug?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆