Java / C ++에 전력 연산자가없는 이유는 무엇입니까?


23

**파이썬 에는 그러한 연산자가 있지만 Java와 C ++에 왜 없는지 궁금합니다.

연산자 오버로딩을 사용하여 C ++에서 정의한 클래스를 만들기는 쉽지만 (그리고 Java에서도 가능하다고 생각합니다.) int, double 등과 같은 기본 유형에 대해 이야기 할 때 라이브러리를 사용해야합니다 같은 기능 Math.power(그리고 일반적으로 두 배로 모두 캐스팅해야 함).

그렇다면 왜 원시 유형에 대해 그러한 연산자를 정의하지 않습니까?


8
C ++에서는 자체 연산자를 만들 수 없습니다. 기존 연산자 만 오버로드 할 수 있습니다.

1
@Mahesh이므로 나만의 Number 클래스를 만들고 과부하 ^ 연산자를 힘으로 사용할 수 있습니다. 그 사실은 수학이 아닙니다.

22
@ RanZilber : ^연산자의 우선 순위가 지수 우선 순위와 일치하지 않기 때문에 중요 합니다. 표현을 고려하십시오 a + b ^ c. 수학에서 지수가 먼저 수행 b ^ c된 다음 ( )에 결과 거듭 제곱이에 추가됩니다 a. C ++에서는 덧셈이 먼저 수행 된 a + b다음 ( ) ^연산자가으로 수행됩니다 c. 따라서 ^지수를 의미 하기 위해 연산자를 구현하더라도 우선 순위는 모든 사람을 놀라게 할 것입니다.
silico에서

2
@RamZilber- ^C ++의 XOR입니다. 오버로드 된 연산자는 기본 데이터 유형이 사용하는 것과 다르지 않아야합니다.

4
@ RanZilber : 지수를 의미하기 위해 언급 한 연산자를 사용하는 것이 전혀 직관적이지 않기 때문입니다. ++연산자 또는 !연산자 등에 과부하가 걸리는 C ++ 프로그래머의 역량에 대해 심각하게 의문을 제기합니다 . 알. 지수를 의미합니다. 그러나 당신이 이야기하는 연산자는 오직 하나의 인수만을 받아들이 기 때문에 어쨌든 할 수 없습니다. 지수화에는 두 가지 인수가 필요합니다.
silico에서

답변:


32

일반적으로 C (및 확장 C ++)의 기본 연산자는 간단한 단일 명령으로 간단한 하드웨어로 구현할 수 있도록 설계되었습니다. 지수화와 같은 것은 종종 소프트웨어 지원이 필요합니다. 기본적으로 존재하지 않습니다.

또한 언어의 표준 라이브러리에서 형식으로 제공 std::pow됩니다.

마지막으로, 정수 데이터 유형에 대해이 작업을 수행하는 것은 의미가 없습니다. 지수에 대한 작은 값조차도 int에 필요한 범위, 즉 최대 65,535를 날려 버리기 때문입니다. 물론, 당신은 double과 float에 대해 이것을 할 수는 있지만 int는 아니지만, 거의 사용되지 않는 기능에 대해 언어가 일치하지 않는 이유는 무엇입니까?


4
나는 이것의 대부분에 동의하지만, 모듈러스 연산자를 부동 소수점 유형에 사용할 수 없다는 사실은 원시 데이터 유형과 일치하지 않지만, 아마도 내가 생각하는 하드웨어에서 단일 명령이 아닐 수도 있습니다.

@Sion : 적어도 x86에서 모듈러스는 단일 명령어입니다. ( DIV나눗셈과 계수를 모두 수행) 일관성 점에 대해 알게되었습니다.
Billy ONeal

@ 빌리 ONeal : 단일 명령에서 부동 소수점 계수? 나는 내 자신에 대해 알기 위해 늦게 집회에서 몰두하지 않았습니다. 이 경우 계수 연산자는 부동 소수점 유형에 적용 가능해야합니다.

3
@DonalFellows : FORTRAN은 큰 숫자 지원과 비슷한 것이 있기 오래 전에 지수 연산자를 가졌습니다.
supercat

1
@DonalFellows : 전력 연산자는 부동 수만큼 정수에 유용하지 않지만 작은 전력 (특히 제곱)의 경우에는 그 용도를 확실히 가질 수 있습니다. 개인적으로 나는 연산자를 문자로 만드는 접근법을 좋아합니다 (Pascal이 div또는 FORTRAN을 사용하는 것처럼 .EQ.). 언어 공백 규칙에 따라 예약어를 요구하지 않고 임의의 수의 연산자를 가질 수 있습니다.
supercat

41

이 질문은 C ++ : Stroustrup, "C ++의 디자인과 진화"에 대한 대답은 11.6.1, pp. 247-250 단원에서 설명합니다.

새로운 연산자를 추가하는 것에 대한 일반적인 반대 의견이있었습니다. 이미 지나치게 복잡한 우선 순위 테이블에 추가됩니다. 실무 그룹의 구성원들은 그것이 기능을 갖는 것보다 약간의 편의를 줄 것이라고 생각했으며 때로는 자신의 기능을 대체 할 수 있기를 원했습니다.

운영자를위한 좋은 후보자는 없었습니다. ^는 독점적 이며 and 와 and ^^간의 관계로 인해 혼란을 불러 일으켰습니다 . 기존 가치의 지수화를위한 자연스런 경향이있을 것이기 때문에 부적합 했고 이미 취해졌습니다. 가장 좋은 것은 아마도 아무도 좋아하지 않았을 것 입니다.&|&&||!!=*^

스트로브 스트 룹 고려 **다시,하지만 이미 C에서 의미를 가지고 a**p있다 a번 어떤 p포인트를, 및 char ** c;선언 c에 대한 포인터에 대한 포인터 char. 소개 **"무엇 다음 것은 포인트 배", "포인터에 대한 포인터의 선언"토큰의 의미 또는 (뒤에 숫자 경우) "지수"발생하는 우선 순위 문제 (그것은 포인터 인 경우). p가 숫자 인 것처럼 a/b**p파싱해야 a/(b**p)하지만 (a/b) * *pp가 포인터 인 경우 파서에서 해결해야합니다.

다시 말해, 가능했을 수도 있지만 우선 순위 테이블과 파서는 복잡하고 이미 너무 복잡합니다.

나는 Java에 대한 이야기를 모른다; 내가 할 수있는 것은 추측하는 것입니다. 시작된 C의 경우 모든 C 연산자는 어셈블리 코드로 쉽게 변환되어 부분적으로 컴파일러를 단순화하고 일부는 간단한 연산자에서 시간이 많이 걸리는 기능을 operator+()숨기지 않습니다 (다른 사람들이 큰 복잡성과 성능 저하를 숨길 수 있다는 사실 은 하나였습니다) C ++에 대한 초기 불만 중).


2
좋은 대답입니다. Java는이 점에서 C를 단순화하려고 시도했기 때문에 아무도 새로운 연산자를 추가하고 싶지 않았습니다. 아무도 나에게 물어 본 것이 유감입니다 *^. : D
maaartinus

1
C는 텍스트 서식을 설정하기 위해 만들어졌습니다. 포트란은 수학을 위해 만들어졌으며 20 년 전에는 복잡한 수학, 수학 및 행렬 수학을 가졌습니다.
Martin Beckett

@Martin Beckett : C가 텍스트 서식을 위해 만들어진 증거를 찾을 수 있습니까? 저에게는 매우 서투른 언어 인 것 같습니다 .C의 기원에 대해 읽은 것은 주로 Unix의 시스템 프로그래밍을 위해 설계된 것이라고 말합니다.
David Thornley

@DavidThornley-유닉스를 쓸 수 있도록 설계되었지만, 유닉스 초기의 모든 사용은 텍스트 형식이었던 것으로 보이며, 현재로서는 광범위한 문자열과 i / o 라이브러리가 있습니다.
Martin Beckett

6
+1 : 기존의 의미 a**p는 살인자입니다. (이 문제를 해결하려면 해킹 ... BRR!)
DONAL 휄로우

13

나는 당신이 소개하는 모든 연산자가 언어의 복잡성을 증가시키기 때문 이라고 생각 합니다. 따라서 진입 장벽이 매우 높습니다. 나는 매우 드물게 지수를 사용한다는 것을 알게되었습니다. 그렇게하기 위해 메소드 호출을 사용하는 것이 행복합니다.



3
내가 사용하는 거라고 x**2하고 x**3있지 거의 그. 그리고 컴파일러가 알고 있고 간단한 경우에 최적화하는 마법의 포로 구현이 좋을 것입니다.
코드 InChaos

2
@CodeInChaos : 그러나 x * xx * x * x광장과 큐브에 대한 나쁜 대체하지 않습니다.
David Thornley

5
@David x*xx가 표현식이면 간단히 쓸 수 없습니다 . 가장 좋은 경우 코드가 다루기 어려워지고 최악의 경우 느리거나 잘못됩니다. 따라서 고유 한 정사각형 및 큐브 함수를 정의해야합니다. 그런 다음에도 **를 전력 연산자로 사용하는 것보다 코드가 더 나빠질 수 있습니다.
코드 InChaos

1
@David 괄호를 넣어야하지만 표현식을 여러 번 반복하고 소스 코드를 부 풀릴 필요는 없습니다. 가독성을 크게 줄입니다. 그리고 일반적인 하위 표현식 제거는 컴파일러가 표현식에 부작용이없는 것을 보장 할 수있는 경우에만 가능합니다. 그리고 적어도 .net 지터는 그렇게 똑똑하지 않습니다.
코드 InChaos

11

Java 언어 및 핵심 라이브러리 디자이너는 대부분의 수학 연산을 Math 클래스 에 위임하기로 결정했습니다 . Math.pow () 참조 .

왜? 비트 단위 정밀도보다 성능 우선 순위를 지정할 수있는 유연성. 내장 된 수학 연산자의 동작은 플랫폼마다 다를 수 있다고 말하면 나머지 언어 사양과 비교할 수 있지만 Math 클래스는 특히 동작이 성능의 정밀도를 희생 할 수 있으므로 구매자는 다음과 같이주의해야합니다.

클래스 StrictMath 의 숫자 메소드 중 일부와 달리 Math 클래스의 동등한 함수에 대한 모든 구현은 비트마다 동일한 결과를 리턴하도록 정의되지 않습니다. 이러한 완화는 엄격한 재현성이 요구되지 않는 더 나은 성능의 구현을 가능하게합니다.


6

지수는 과학 프로그래밍을 겨냥한 것이기 때문에 처음부터 Fortran의 일부였습니다. 힘 법칙 관계는 물리학에서 일반적이기 때문에 엔지니어와 물리학자는 시뮬레이션에서 자주 사용합니다.

파이썬은 과학 컴퓨팅에서도 강하게 존재합니다 (예 : NumPy 및 SciPy). 지수 연산자와 함께 과학 프로그래밍도 목표로 삼았다 고 제안합니다.

C, Java 및 C #은 시스템 프로그래밍에 뿌리를두고 있습니다. 아마도 그것은 지원되는 연산자 그룹에서 지수를 유지하는 영향 일 것입니다.

그냥 이론.


4

C는 ALU로 액세스 할 수있는 일반적인 산술 연산에 대한 연산자 만 정의했습니다. 주요 목표는 어셈블리 코드에 대한 사람이 읽을 수있는 인터페이스를 만드는 것이 었습니다.

C ++는 C로 작성된 모든 코드베이스가 호환되기를 원했기 때문에 연산자 동작을 변경하지 않았습니다.

Java는 기존 C ++ 프로그래머를 위협하고 싶지 않기 때문에 동일하게 수행되었습니다.


C가 만들어 졌을 때, 곱셈과 나눗셈은 하드웨어에서 자주 부족하지 않았으며 소프트웨어로 구현되어야했습니다. 그러나 C에는 곱셈과 나눗셈 연산자가 있습니다.
siride

@siride : PDP-7은 유닉스를 최초로 실행 한 컴퓨터로 EAE를 통해 하드웨어 곱셈과 나눗셈을 수행했습니다. 다음을 참조하십시오 : bitsavers.org/pdf/dec/pdp7/F-75_PDP-7userHbk_Jun65.pdf
Ates

1

전력에 적합한 모든 작업자가 이미 사용 중이기 때문입니다. ^는 XOR이며 **는 포인터에 대한 포인터를 정의합니다. 대신에 그들은 같은 일을하는 기능을 가지고 있습니다. (pow ()처럼)


@RTS-langauge 개발자가 efficieny 이상의 의미를 찾고 있습니까?

프로그래밍 언어의 훌륭한 개발자는 두 가지를 모두 살펴 봅니다. 나는 자바에 대해 아무 말도 할 수 없다. 그러나 C ++에서 pow () 함수는 컴파일 타임에 계산됩니다. 그리고 일반 연산자만큼 효율적입니다.

@ RTS : pow()상수 폴딩을 수행 할 수있는 컴파일러가 없다면 이 함수는 런타임에 계산을 수행합니다 pow(). (그러나 일부 컴파일러는 프로세서 내장 함수를 사용하여 계산을 수행 할 수있는 옵션을 제공합니다.)
silico

@ silico에서는 최종 값을 계산한다는 것을 의미하지는 않았지만 컴파일러가 함수 호출을 최적화하여 원시 방정식을 갖기를 의미했습니다.

2
@ josefx : 물론 좋은 이유입니다. 단일 *은 간접 또는 곱셈에 사용되는 어휘 토큰입니다. **의미 지수는 하나 또는 두 개의 어휘 토큰 것, 그리고 당신이 정말로 당신의 렉서가 토큰 화에 심볼 테이블을 칠하고 싶지 않아요.
David Thornley

0

사실, 산술 연산자는 함수의 바로 가기 일뿐입니다. (거의) 당신이 그들과 함께하는 모든 일은 기능으로 할 수 있습니다. 예:

c = a + b;
// equals
c.set(a.add(b));
// or as free functions
set(c, add(a,b));

더 장황하기 때문에 'power of'를 수행하는 함수를 사용하는 데 아무런 문제가 없습니다.


-1

더하기 / 빼기 / 부정 및 곱셈 / 나눗셈은 기본적인 수학 연산자입니다. 전원을 운전자로 만들려면 어디에서 멈추겠습니까? 제곱근 연산자? N- 루트 연산자? 대수 연산자?

나는 그들의 제작자를 위해 말할 수는 없지만 언어에 그러한 연산자를 사용하는 것이 다루기 힘들고 직교하지 않을 것이라고 생각할 수 있습니다. 키보드에 남아있는 영숫자 / 공백이 아닌 문자의 수는 다소 제한되어 있습니다. C ++에 모듈러스 연산자가 있다는 것은 이상합니다.


+1-왜 mod연산자로서 이상 한지 모르겠습니다 . 일반적으로 단일 명령입니다. 정수에 대한 원시 작업입니다. 컴퓨터 과학에서 가장 많이 사용됩니다. (바운드 버퍼와 같은 것을 구현하지 않으면 mod악취가 날 것입니다)
Billy ONeal

@Billy ONeal : 정수 타입과 부동 소수점 타입과의 사용이 불일치하여 이상합니다. 그래도 절대적으로 유용하며 제거를 꿈꾸지 않습니다. 기발한 것이 전부입니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.