Python에 **
이러한 연산자가 있지만 Java 및 C ++에없는 이유가 궁금합니다. 하나도 마찬가지입니다.
연산자 오버로딩을 사용하여 C ++에서 정의한 클래스 용으로 쉽게 만들 수 있지만 (Java에서도 가능하다고 생각합니다) int, double 및 그래서 “Math.power
와 같은 라이브러리 함수를 사용해야합니다 (일반적으로 둘 다 double로 캐스트해야 함).
그러므로 이러한 연산자를 정의하지 않는 것이 좋습니다. 기본 유형의 경우?
주석
Answer
일반적으로 C의 기본 연산자 (및 확장 C ++) 대략 단일 명령으로 간단한 하드웨어로 구현할 수 있도록 설계되었습니다. 지수화와 같은 것에는 종종 소프트웨어 지원이 필요합니다. 따라서 기본적으로 존재하지 않습니다.
또한 언어의 표준 라이브러리에서 std::pow
형식으로 제공합니다.
마지막으로 정수 데이터 유형에 대해이 작업을 수행하는 것은 의미가 없습니다. 대부분의 지수화 값조차도 int에 필요한 범위 인 최대 65,535를 날려 버리기 때문입니다. 물론 double 및 float에 대해이 작업을 수행 할 수는 있지만 그렇지 않습니다. 하지만 거의 사용되지 않는 기능에 대해 언어가 일관성이없는 이유는 무엇입니까?
댓글
- 이 대부분에 동의하지만 모듈러스는 연산자는 부동 소수점 유형에 사용할 수 없습니다. 원시 데이터 유형에 대해 일관성이 없지만, 내가 상상하는 하드웨어에 대한 단일 명령이 아닐 수도 있습니다.
- @Sion : 적어도 on x86, modulus는 단일 명령어입니다. (
DIV
는 나누기와 모듈러스를 모두 수행합니다.) ‘ 그래도 일관성 지점에 대해 알고 있습니다. - @Billy ONeal : 부동 소수점 모듈 하나의 명령에 루스? 저는 ‘ 나 자신을 알기 위해 늦게 어셈블리를 꼼꼼히 살펴 보지 않았습니다. ‘ 경우, 모듈러스 연산자를 부동 소수점 유형에 적용 할 수 있어야합니다.
- @DonalFellows : FORTRAN은 훨씬 전에 지수 연산자를 가졌습니다. bignum 지원과 유사한 것입니다.
- @DonalFellows : 거듭 제곱 연산자는 ‘ 정수에서 float만큼 유용하지 않지만 작은 거듭 제곱 (특히 제곱)의 경우에는 유용합니다. 확실히 그 용도가 있습니다. 개인적으로 나는 문자로 연산자를 만드는 접근 방식을 좋아합니다 (Pascal이
div
또는 FORTRAN과.EQ.
를 사용하는 것처럼). 언어 공백 규칙에 따라 예약어 일 필요없이 임의의 수의 연산자를 가질 수 있습니다.
Answer
이 질문은 C ++에 대한 답변입니다. Stroustrup,”Design and Evolution of C ++ “는 섹션 11.6.1, pp. 247-250에서 이에 대해 설명합니다.
새로운 연산자. 이미 지나치게 복잡한 우선 순위 테이블에 추가됩니다. 워킹 그룹의 구성원들은 기능을 갖는 것보다 약간의 편리함을 줄 것이라고 생각했으며 때때로 자신의 기능을 대체 할 수 있기를 원했습니다.
운영자에게는 좋은 후보가 없었습니다.^
는 배타적이거나, ^^
는 &
와 |
및 &&
및 ||
. !
는 기존 값의 지수화를 위해 !=
를 쓰는 자연스러운 경향이 있었기 때문에 적합하지 않았으며 이미 사용되었습니다. 가장 좋은 것은 *^
였는데, 아무도 정말 좋아하지 않았던 것 같습니다.
Stroustrup은 다시 **
를 고려했지만 이미 C에서 의미가 있습니다. a**p
는 p
가 가리키는 값의 a
배이며 char ** c;
는 c
를 char
에 대한 포인터에 대한 포인터로 선언합니다. **
를 “포인터에 대한 포인터 선언”, “다음 항목이 가리키는 시간”( “포인터 인 경우)”또는 “지수”(다음에있는 경우)를 의미하는 토큰으로 도입 숫자로 인한) 우선 순위 문제가 발생했습니다. p가 숫자 인 경우 a/b**p
는 a/(b**p)
로 파싱해야하지만 (a/b) * *p
p가 포인터이면 파서에서 해결해야합니다.
즉, 가능했을 수도 있지만 우선 순위 테이블과 둘 다 이미 너무 복잡합니다.
나는 Java에 대한 이야기를 모릅니다. 내가 할 수있는 것은 추측뿐입니다. C가 시작된 곳에서 모든 C 연산자는 부분적으로는 컴파일러를 단순화하고 부분적으로는 간단한 연산자에서 시간 소모적 인 기능을 숨기지 않도록 어셈블리 코드로 쉽게 변환됩니다 (operator+()
및 다른 사람들은 C ++에 대한 초기 불만 사항 중 하나가 성능 저하를 숨길 수있었습니다.
댓글
- 좋은 답변입니다. 이 점에서 Java가 C를 단순화하려고했기 때문에 아무도 새 연산자를 추가하고 싶지 않았습니다. ‘ 아무도 물어 보지 않은 유감입니다.
*^
가 좋았을 것입니다. : D - C는 텍스트 서식 지정을 위해 만들어졌습니다. Fortran은 수학을 수행하기 위해 만들어졌고 20 년 전에 복잡한 전력 및 행렬 수학을 사용했습니다.
- @Martin Beckett : C가 텍스트 서식을 위해 만들어 졌다는 증거를 찾을 수 있습니까? 저에게는 매우 서투른 언어 인 것 같습니다. C의 기원에 대해 읽은 ‘는 주로 Unix 용 시스템 프로그래밍을 위해 설계되었다고 말합니다.
- @DavidThornley-Unix를 작성하도록 설계되었지만 초기 Unix에서 사용하는 모든 것은 텍스트 형식 인 것 같으며 ‘ 당시에는 광범위한 문자열과 i / o 라이브러리.
- +1 :
a**p
의 기존 의미는 킬러입니다. (그 문제를 해결하기위한 방법은… Brr!)
답변
나는 의심 스럽습니다
em> 그것은 당신이 도입하는 모든 연산자가 언어의 복잡성을 증가시키기 때문입니다. 따라서 진입 장벽은 매우 높습니다. 저는 지수화를 매우 드물게 사용하고 있다는 것을 알게되었습니다. 그리고 저는 메소드 호출을 사용하여 행복합니다. 그래서.
댓글
- 모든 기능은 -100 점으로 시작합니다.
- ‘
x**2
및x**3
를 거의 사용하지 않습니다. . 그리고 컴파일러가 알고 있고 간단한 경우에 최적화하는 마법의 힘 구현이 좋을 것입니다. - @CodeInChaos : 그러나
x * x
및x * x * x
‘ 정사각형과 정육면체를 대체 할 수 없습니다. - @David 가능 ‘ x가 표현식이면 단순히
x*x
를 작성하지 마십시오. 최상의 경우에는 코드가 다루기 힘들고 최악의 경우에는 속도가 느려지거나 잘못 될 수 있습니다. 따라서 ‘ 자신의 Square 및 Cube 함수를 정의해야합니다. 그리고이 경우에도 **를 전력 연산자로 사용하는 것보다 코드가 더 나을 것입니다. - @David 괄호를 넣어야하지만 반복 할 필요는 없습니다. ‘ 표현식은 여러 번 소스 코드를 부풀립니다. 가독성을 크게 떨어 뜨립니다. 일반적인 하위 표현식 제거는 컴파일러가 표현식에 부작용이 없음을 보장 할 수있는 경우에만 가능합니다. 그리고 최소한 .net 지터는 ‘이 점에서 너무 똑똑하지 않습니다.
답변
자바 언어 및 핵심 라이브러리 디자이너는 대부분의 수학 연산을 Math 클래스에 맡기기로 결정했습니다. Math.pow () 를 참조하세요.
이유가 무엇인가요? 비트 단위 정밀도보다 성능을 우선시하는 유연성.내장 된 수학 연산자의 동작이 플랫폼마다 다를 수 있다고 말하는 것은 나머지 언어 사양에 위배되는 반면, Math 클래스는 동작이 성능을 위해 잠재적으로 정밀도를 희생 할 가능성이 있다고 명시하므로 구매자는 다음을주의해야합니다.
StrictMath 클래스의 일부 숫자 메서드와 달리 클래스와 동등한 기능의 모든 구현 수학은 비트 단위 동일한 결과를 반환하도록 정의되지 않았습니다. 이러한 완화를 통해 엄격한 재현성이 필요하지 않은 더 나은 성능의 구현이 가능합니다.
답변
Exponentiation은 과학적 프로그래밍을 목표로했기 때문에 처음부터 Fortran의 일부였습니다. 엔지니어와 물리학 자들은 물리에서 멱 법칙 관계가 일반적이기 때문에 시뮬레이션에서 자주 사용합니다.
Python은 과학 컴퓨팅에서도 강력한 입지를 차지하고 있습니다 (예 : NumPy 및 SciPy). 지수화 연산자와 함께 과학적 프로그래밍을 목표로 삼았 음을 암시합니다.
C, Java 및 C #은 시스템 프로그래밍에 뿌리를두고 있습니다. 아마도 그것은 지원되는 연산자 그룹에서 지수를 유지 한 영향 일 것입니다.
이론 일뿐입니다.
답변
C는 ALU로 액세스 할 수있는 일반적인 산술 연산만을위한 연산자를 정의했습니다. 주요 목표는 어셈블리 코드에 대한 사람이 읽을 수있는 인터페이스를 만드는 것이 었습니다.
C ++는 모든 것을 원했기 때문에 연산자 동작을 변경하지 않았습니다. C로 작성된 코드베이스는 준수합니다.
Java는 기존 C ++ 프로그래머를 위협하지 않기 때문에 동일한 작업을 수행했습니다.
댓글
- C가 만들어 졌을 때 곱셈과 나눗셈은 드물게 하드웨어가 부족하지 않았으며 소프트웨어로 구현되어야했습니다. 그러나 C에는 곱셈과 나눗셈 연산자가 있습니다.
- @siride : 제가 아는 한 PDP-7은 처음으로 Unix를 실행하는 컴퓨터로 EAE를 통해 하드웨어 곱셈과 나눗셈을했습니다. 참조 : bitsavers.org/pdf/dec/pdp7/F-75_PDP-7userHbk_Jun65.pdf
Answer
글쎄요. 왜냐하면 권력에 맞는 모든 연산자가 이미 사용 중이기 때문입니다. ^는 XOR이고 **는 포인터에 대한 포인터를 정의합니다. 그래서 대신 그들은 같은 일을하는 함수를 가지고 있습니다. (예 : pow ())
댓글
- @RTS-언어 개발자가 효율성 이상의 의미를 실제로 찾고 있습니까?
- 프로그래밍 언어의 훌륭한 개발자는 두 가지를 모두 살펴 봅니다. Java에 대해 ‘ 말할 수 없습니다. 그러나 C ++에서 pow () 함수는 컴파일 타임에 계산됩니다. 그리고 정규 연산자만큼 효율적입니다.
- @RTS : 상수 폴딩을 수행 할 수있는 컴파일러가 없다면
pow()
함수는 런타임에 계산을 수행합니다.pow()
의 경우 매우 의심 스럽습니다. (일부 컴파일러는 계산을 수행하기 위해 프로세서 내장 함수를 사용할 수있는 옵션을 제공합니다.) - @In silico I didn ‘ 값, 즉 컴파일러가 함수 호출을 최적화하므로 원시 방정식 만 있으면됩니다.
- @josefx : 물론입니다 ‘ 좋은 이유입니다. 단일
*
는 간접 또는 곱셈에 사용되는 ‘ 어휘 토큰입니다. 지수를 의미하는**
는 하나 또는 두 개의 어휘 토큰이 될 것이며, 렉서가 기호를 누르지 않아도됩니다. ‘ 표를 토큰 화합니다.
답변
사실은 산술 연산자는 함수의 단축키 일뿐입니다. (거의) 그들과 함께하는 모든 작업은 함수로 수행 할 수 있습니다. 예 :
c = a + b; // equals c.set(a.add(b)); // or as free functions set(c, add(a,b));
그냥 더 장황하기 때문에 “힘”을 수행하는 함수를 사용하는 데 아무런 문제가 없다고 생각합니다.
답변
더하기 / 빼기 / 부정 및 곱하기 / 나눗셈은 기본적인 수학 연산자입니다. 거듭 제곱을 연산자로 만들려면 어디에서 멈출까요? 제곱근 연산자? N- 루트 연산자? 대수 연산자?
저는 제작자를 대변 할 수는 없지만 이러한 연산자를 언어로 사용하는 것은 다루기 어렵고 직교하지 않을 것이라고 생각합니다. 키보드에 남아있는 영숫자 / 공백이 아닌 문자의 수는 다소 제한되어 있습니다. 사실 C ++에 “모듈러스 연산자가있는 것이 이상합니다.
코멘트
- +1-‘
mod
를 연산자로 사용하는 것이 왜 이상한지 모르겠습니다. div id = “749f89ae7f”>
는 일반적으로 단일 명령어입니다. ‘ 정수에 대한 기본 연산입니다. It ‘는 컴퓨터 과학 분야에서 가장 많이 사용됩니다.(mod
없이 경계 버퍼와 같은 것을 구현하면 악취가납니다.)
^
연산자의 우선 순위가 지수의 우선 순위와 일치하지 않기 때문에 중요합니다.a + b ^ c
표현식을 고려하십시오. 수학에서는 지수 화가 먼저 수행되고 (b ^ c
) 결과 거듭 제곱이a
에 추가됩니다. C ++에서는 추가가 먼저 수행되고 (a + b
)^
연산자가c
. 따라서 지수를 의미하는^
연산자를 구현 한 경우에도 우선 순위는 모든 사람을 놀라게 할 것입니다.^
는 C ++의 XOR입니다. 오버로드 된 연산자는 기본 데이터 유형이 사용하는 것과 다르지 않아야합니다.++
연산자 또는!
연산자 등을 오버로드하는 C ++ 프로그래머의 능력에 대해 진지하게 의문을 제기합니다. al. 지수를 의미합니다. 그러나 ‘ 어쨌든 ‘ 말하는 연산자는 하나의 인수 만 받아들이 기 때문입니다. 지수화에는 두 개의 인수가 필요합니다.