기본 유형 '짧은'-Java로 캐스팅
short
Java 의 기본 유형 에 대한 질문이 있습니다 . JDK 1.6을 사용하고 있습니다.
다음이있는 경우 :
short a = 2;
short b = 3;
short c = a + b;
컴파일러는 컴파일을 원하지 않습니다. "int에서 short로 변환 할 수 없습니다"라고 말하고 캐스트를 만들 것을 제안합니다 short
.
short c = (short) (a + b);
정말 작동합니다. 하지만 내 질문은 왜 내가 캐스트해야하나요? a와 b의 값은 범위에 있습니다 short
-짧은 값의 범위는 {-32,768, 32767}입니다. 나는 또한 작업을 수행하고 싶을 때 캐스팅해야합니다-, *, / (다른 사람을 확인하지 않았습니다).
기본 유형에 대해 동일한 작업을 수행하면 int
aa + bb를 int
. 다음은 잘 작동합니다.
int aa = 2;
int bb = 3;
int cc = aa +bb;
나는 short 타입의 두 변수를 추가해야하는 클래스를 디자인하면서 이것을 발견했고 컴파일러는 내가 캐스트를 만들기를 원했다. 유형의 두 변수를 사용하여이 작업을 수행하면 int
캐스트 할 필요가 없습니다.
작은 말 : primitive type에서도 같은 일이 발생합니다 byte
. 따라서 이것은 작동합니다.
byte a = 2;
byte b = 3;
byte c = (byte) (a + b);
그러나 이것은 아닙니다 :
byte a = 2;
byte b = 3;
byte c = a + b;
를 들어 long
, float
, double
,과 int
, 캐스트 할 필요가 없습니다. short
및 byte
값에 대해서만 .
짧은 C #에 설명 된대로 (Java와 같은 다른 언어 컴파일러에도 해당)
short에서 int, long, float, double 또는 decimal로 미리 정의 된 암시 적 변환이 있습니다.
더 큰 스토리지 크기의 비 리터럴 숫자 유형을 short로 암시 적으로 변환 할 수 없습니다 (정수 유형의 스토리지 크기는 Integral Types Table 참조). 예를 들어, 다음 두 개의 짧은 변수 x 및 y를 고려하십시오.
short x = 5, y = 12;
다음 할당 문은 할당 연산자의 오른쪽에있는 산술 표현식이 기본적으로 int로 평가되기 때문에 컴파일 오류를 생성합니다 .
short z = x + y; // Error: no conversion from int to short
이 문제를 해결하려면 캐스트를 사용하십시오.
short z = (short)(x + y); // OK: explicit conversion
그러나 대상 변수의 저장소 크기가 같거나 저장소 크기가 더 큰 다음 문을 사용할 수 있습니다.
int m = x + y;
long n = x + y;
좋은 후속 질문은 다음과 같습니다.
"대입 연산자의 오른쪽에있는 산술 표현식이 기본적으로 int로 평가되는 이유"?
첫 번째 답변은 다음에서 찾을 수 있습니다.
산술 표현식이 평가되어야 정수 자바 언어 사양을 정의는 정수 번호는 어떻게 표현하고 정확하게하는 방법 . 이 프로그래밍 언어는 인터넷의 분산 응용 프로그램에서 사용되도록 설계 되었기 때문에 Java의 중요한 속성입니다. Java 프로그램은이를 실행하는 대상 기계와 독립적으로 동일한 결과를 생성하는 데 필요합니다 .
반대로 C (및 널리 사용되는 명령형 및 객체 지향 프로그래밍 언어의 대부분)는 더 조잡하고 많은 중요한 특성을 열어 둡니다. 이 부정확 한 언어 사양의 의도는 분명합니다. 동일한 C 프로그램은 대상 프로세서에 내장 된 산술 연산을 사용하여 소스 프로그램의 정수 산술을 인스턴스화하여 16 비트, 32 비트 또는 64 비트 아키텍처에서 실행되어야합니다. 이는 사용 가능한 기계 작업을 직접 사용할 수 있기 때문에 훨씬 더 효율적인 코드로 이어집니다. 정수 계산이 "충분히 작은"숫자만을 다루는 한, 불일치는 발생하지 않습니다.
이러한 의미에서 C 정수 산술은 프로그래밍 언어 사양에 의해 정확히 정의되지 않고 대상 머신을 결정함으로써 만 완전히 인스턴스화되는 자리 표시 자입니다.
Java는 정수가 표현되는 방법과 정수 산술이 계산되는 방법을 정확하게 정의합니다.
Java Integers
--------------------------
Signed | Unsigned
--------------------------
long (64-bit) |
int (32-bit) |
short (16-bit) | char (16-bit)
byte (8-bit) |
Char는 유일한 부호없는 정수 유형입니다. 그 값은 유니 코드 문자를 나타냅니다. from
\u0000
~\uffff
, 즉 0 ~ 2 16 -1.정수 연산자에 long 유형의 피연산자가 있으면 다른 피연산자도 long 유형으로 변환됩니다. 그렇지 않으면 연산이 int 유형의 피연산자에 대해 수행되고 필요한 경우 더 짧은 피연산자가 int로 변환됩니다 . 변환 규칙이 정확하게 지정됩니다.
[이론 컴퓨터 과학의 전자 노트 82 No. 2 (2003)
Blesner-Blech-COCV 2003 : Sabine GLESNER , Jan Olaf BLECH,
Fakultät für Informatik,
Universität Karlsruhe
Karlsruhe, Germany]
편집 : 좋아, 이제 우리는 그것이 Java라는 것을 알고 있습니다 ...
Java 언어 사양의 섹션 4.2.2는 다음과 같이 설명합니다.
Java 프로그래밍 언어는 정수 값에 대해 작동하는 여러 연산자를 제공합니다.
[...]
int 또는 long 유형의 값이되는 숫자 연산자 : [...] 더하기 연산자 + 및-(§15.18)
즉, C #과 비슷합니다. 더하기 연산자 (정수 유형에 적용되는 경우)는 항상 int
또는 long
을 생성하므로 short
변수 에 할당하려면 캐스트해야 합니다.
원래 답변 (C #)
In C# (you haven't specified the language, so I'm guessing), the only addition operators on primitive types are:
int operator +(int x, int y);
uint operator +(uint x, uint y);
long operator +(long x, long y);
ulong operator +(ulong x, ulong y);
float operator +(float x, float y);
double operator +(double x, double y);
These are in the C# 3.0 spec, section 7.7.4. In addition, decimal addition is defined:
decimal operator +(decimal x, decimal y);
(Enumeration addition, string concatenation and delegate combination are also defined there.)
As you can see, there's no short operator +(short x, short y)
operator - so both operands are implicitly converted to int, and the int form is used. That means the result is an expression of type "int", hence the need to cast.
In C# and Java, the arithmatic expression on the right hand side of the assignment evaluates to int by default. That's why you need to cast back to a short, because there is no implicit conversion form int to short, for obvious reasons.
Given that the "why int by default" question hasn't been answered ...
First, "default" is not really the right term (although close enough). As noted by VonC, an expression composed of ints and longs will have a long result. And an operation consisting of ints/logs and doubles will have a double result. The compiler promotes the terms of an expression to whatever type provides a greater range and/or precision in the result (floating point types are presumed to have greater range and precision than integral, although you do lose precision converting large longs to double).
One caveat is that this promotion happens only for the terms that need it. So in the following example, the subexpression 5/4 uses only integral values and is performed using integer math, even though the overall expression involves a double. The result isn't what you might expect...
(5/4) * 1000.0
OK, so why are byte and short promoted to int? Without any references to back me up, it's due to practicality: there are a limited number of bytecodes.
"Bytecode," as its name implies, uses a single byte to specify an operation. For example iadd, which adds two ints. Currently, 205 opcodes are defined, and integer math takes 18 for each type (ie, 36 total between integer and long), not counting conversion operators.
If short, and byte each got their own set of opcodes, you'd be at 241, limiting the ability of the JVM to expand. As I said, no references to back me up on this, but I suspect that Gosling et al said "how often do people actually use shorts?" On the other hand, promoting byte to int leads to this not-so-wonderful effect (the expected answer is 96, the actual is -16):
byte x = (byte)0xC0;
System.out.println(x >> 2);
What language are you using?
Many C based languages have a rule that any mathematical expression is performed in size int or larger. Because of this, once you add two shorts the result is of type int. This causes the need for a cast.
Java always uses at least 32 bit values for calculations. This is due to the 32-bit architecture which was common 1995 when java was introduced. The register size in the CPU was 32 bit and the arithmetic logic unit accepted 2 numbers of the length of a cpu register. So the cpus were optimized for such values.
This is the reason why all datatypes which support arithmetic opperations and have less than 32-bits are converted to int (32 bit) as soon as you use them for calculations.
So to sum up it mainly was due to performance issues and is kept nowadays for compatibility.
In java, every numeric expression like:
anyPrimitive zas = 1;
anyPrimitive bar = 3;
?? x = zas + bar
x will always result to be at least an int, or a long if one of the addition elements was a long.
But there's are some quirks tough
byte a = 1; // 1 is an int, but it won't compile if you use a variable
a += 2; // the shortcut works even when 2 is an int
a++; // the post and pre increment operator work
AFAIS, nobody mentions of final
usage for that. If you modify your last example and define variables a and b as final
variables, then the compiler is assured that their sum, value 5 , can be assigned to a variable of type byte
, without any loss of precision. In this case, the compiler is good to assign the sum of a and b to c . Here’s the modified code:
final byte a = 2;
final byte b = 3;
byte c = a + b;
Any data type which is lower than "int" (except Boolean) is implicitly converts to "int".
In your case:
short a = 2;
short b = 3;
short c = a + b;
The result of (a+b) is implicitly converted to an int. And now you are assigning it to "short".So that you are getting the error.
short,byte,char --for all these we will get same error.
I'd like to add something that hasn't been pointed out. Java doesn't take into account the values you have given the variables (2 and 3) in...
short a = 2; short b = 3; short c = a + b;
So as far as Java knows, you could done this...
short a = 32767; short b = 32767; short c = a + b;
Which would be outside the range of short, it autoboxes the result to an int becuase it's "possible" that the result will be more than a short but not more than an int. Int was chosen as a "default" because basically most people wont be hard coding values above 2,147,483,647 or below -2,147,483,648
참고URL : https://stackoverflow.com/questions/477750/primitive-type-short-casting-in-java
'Nice programing' 카테고리의 다른 글
Authorize 속성의 MVC5 클레임 버전 (0) | 2020.10.19 |
---|---|
std :: transform 및 유사하게 'for'루프 증분을 (void)로 캐스팅하는 이유는 무엇입니까? (0) | 2020.10.19 |
SQL Server Management Studio에서 커서가있는 문만 실행하려면 어떻게해야합니까? (0) | 2020.10.19 |
IE에서 HTML5 캔버스 요소를 어떻게 사용할 수 있습니까? (0) | 2020.10.19 |
OnClickListener-x, y 이벤트 위치? (0) | 2020.10.19 |