您能否帮我理解以下代码的含义:
x += 0.1;
答案 0 :(得分:92)
编程的“常识”是x += y
是x = x + y
的等效简写符号。只要x
和y
属于同一类型(例如,两者都是int
s),您可以认为这两个语句是等效的。
但是,在Java中,x += y
通常与x = x + y
不相同。
如果x
和y
的类型不同,则由于语言规则,这两个语句的行为会有所不同。例如,让我们有x == 0
(int)和y == 1.1
(double):
int x = 0;
x += 1.1; // just fine; hidden cast, x == 1 after assignment
x = x + 1.1; // won't compile! 'cannot convert from double to int'
+=
执行隐式转换,而对于+
,您需要显式转换第二个操作数,否则会出现编译错误。
引自Joshua Bloch的 Java Puzzlers :
(...)复合赋值表达式自动转换结果 他们对其变量类型执行的计算 左手边。如果结果的类型与类型相同 变量,演员表没有效果。但是,如果是这种类型的话 结果比变量,化合物的结果更宽 赋值运算符执行静默缩小原语 转换[JLS 5.1.3]。
答案 1 :(得分:16)
x += y
是x = x + y
x -= y
是x = x - y
x *= y
是x = x * y
x /= y
是x = x / y
x %= y
是x = x % y
x ^= y
是x = x ^ y
x &= y
是x = x & y
x |= y
是x = x | y
依旧......
答案 2 :(得分:13)
这是assignment operators中的一个。它取值为x
,加0.1,然后将(x + 0.1)的结果存储回x
。
所以:
double x = 1.3;
x += 0.1; // sets 'x' to 1.4
它功能相同,但短于:
double x = 1.3;
x = x + 0.1;
注意:在进行浮点数学运算时don't always work the way you think they will。
答案 3 :(得分:2)
devtop += Math.pow(x[i] - mean, 2);
会将操作Math.pow(x[i] - mean, 2)
的结果添加到devtop
变量。
一个更简单的例子:
int devtop = 2;
devtop += 3; // devtop now equals 5
答案 4 :(得分:1)
devtop += Math.pow(x[i] - mean, 2);
将Math.pow(x[i] - mean, 2)
添加到devtop
。
答案 5 :(得分:1)
在Java中,数字的默认类型(例如2或-2(不带小数部分))为int,与c#不同,它不是对象,我们无法像在c#中那样使用2.tostring和默认的数字类型像2.5(含小数部分)是double; 因此,如果您写:
short s = 2;
s = s + 4;
如果执行以下操作,将会得到int也不能转换为short的编译错误:
float f = 4.6;
f = f + 4.3;
在两行都将double'4.6'设置为float变量时,您将遇到两个编译错误,第一行的错误是合乎逻辑的,因为float和double使用不同的数字存储系统,而使用一个而不是另一个存储数字可能会导致数据丢失; 提到的两个示例可以这样更改:
s += 4
f += 4.3
都具有隐式强制转换代码,并且没有编译错误; 值得考虑的另一点是,在Java中缓存了“字节”数据类型范围内的数字,因此,-128到127的数字在Java中是字节类型,因此此代码没有任何编译错误:
byte b = 127
但是这个确实有一个错误:
byte b = 128
因为128是Java中的int值; 对于长整数,我们建议对整数溢出使用数字后的L,如下所示:
long l = 2134324235234235L
在Java中,我们没有像c ++这样的运算符重载,但+ =仅针对String而不是StringBuilder或StringBuffer进行了重载,我们可以使用它代替String'concat'方法,但是我们知道String是不可变的并且将创建另一个对象,并且将不会像以前一样更改同一对象:
String str = "Hello";
str += "World";
很好;
答案 6 :(得分:0)
每当您想了解java运算符如何工作时,都可以查看字节码。如果您在这里编译:
int x = 0;
x += 0.1;
可通过jdk命令javap -c [*.class]
访问字节码:(有关字节码的更多说明,请参考Java bytecode instruction listings)
0: iconst_0 // load the int value 0 onto the stack
1: istore_1 // store int value into variable 1 (x)
2: iload_1 // load an int value from local variable 1 (x)
3: i2d // convert an int into a double (cast x to double)
4: ldc2_w #2 // double 0.1d -> push a constant value (0.1) from a constant pool onto the stack
7: dadd // add two doubles (pops two doubles from stack, adds them, and pushes the answer onto stack)
8: d2i // convert a double to an int (pops a value from stack, casts it to int and pushes it onto stack)
9: istore_1 // store int value into variable 1 (x)
现在很明显,java编译器将x
提升为两倍,然后将其添加为0.1
。
最后,它将答案投射到integer
上。
我发现有一个有趣的事实,当你写的时候:
byte b = 10;
b += 0.1;
编译器将b
转换为两倍,并与0.1
相加,将double
的结果转换为integer
,最后将其转换为byte
,然后那是因为没有指令直接将double
强制转换为byte
。
如果您有疑问,可以检查字节码:)
答案 7 :(得分:0)
它将x的值增加0.1
int x = 0;
x += 0.1;
//x is now 0.1
x += 0.1;
//x is now 0.2