상수로 0?


15

최근에이 프로그래밍 관용구를 접했습니다.

const float Zero = 0.0;

그런 다음 비교에 사용됩니다.

if (x > Zero) {..}

이것이 실제로 다음보다 더 효율적이거나 읽기 쉽고 유지 가능한지 설명 할 수 있습니까?

if (x > 0.0) {..}

참고 : 나는 이 상수를 정의 해야하는 다른 이유를 생각할 수 있습니다 .Im 은이 맥락 에서 그 상수에 대해 궁금 합니다.


31
개발자들은 수학의 법칙이 다른 우주로 코드를 이식 할 계획입니까?
vaughandroid

6
진지하게, 나는 이것에 대한 좋은 이유 하나를 생각할 수 없습니다. 내가 설명 할 수있는 유일한 설명은 지나치게 열성적인 코딩 표준이거나 "매직 넘버가 나쁘다"는 말을 들었지만 왜 (또는 매직 넘버를 구성 할 것인지) 이해하지 못하는 일부 개발자들입니다.
vaughandroid

@Baqueta-대체 우주? 나는 그들이 이미 거기에 살았다 고 생각한다! 마법의 숫자에 관해서는 동의하지만, 0과 1을 제외한 모든 것이 일정하게 유지되어야한다는 경험의 법칙을 사용합니다 .
NWS

1
x유형이 float인 경우 x > 0.0승격을 (으 double)로 설정하면 효율성이 떨어질 수 있습니다. 그게 당신의 상수 (예 : 올바른 유형을 바로 확인하고 들어 명명 된 상수 불구을 사용하는 좋은 이유가 아니다 0f, float(0)또는 decltype(x)(0)).
마이크 시모어

1
@JoSo가 : 공정하게,의 유형이 13.37아니다 float, 그것은이다 double. 그래서 당신이 원한다면 당신의 교사는 정확 했을float입니다. 일부 컨텍스트 (예 : 플로트에 할당) 13.37는 암시 적으로 float원하는 것으로 변환 되고 다른 컨텍스트 (예 : 템플릿 유형 공제)는 그렇지 않지만 static const float항상 의도 한 유형으로 시작됩니다. 따라서 형식이 더 안전합니다. 당신을 염두에 두십시오 13.37f! "type-safety"보다는 매크로를 피해야하는 다른 이유가 있기 때문에, 교사가 당신에게 잘못된 주장을했을 가능성이 높습니다.
Steve Jessop

답변:


29

가능한 이유는 캐싱, 명명 또는 강제 유형입니다.

캐싱 (해당 사항 없음)

비교하는 동안 오브젝트를 작성하는 비용을 피하려고합니다. Java에서 예는 다음과 같습니다.

BigDecimal zero = new BigDecimal ("0.0");

여기에는 상당히 무거운 작성 프로세스가 포함되며 제공된 정적 메소드를 사용하여 더 잘 제공됩니다.

BigDecimal zero = BigDecimal.ZERO;

이를 통해 초기화 중에 JVM이 BigDecimal을 사전 캐시하므로 반복 작성 비용을 발생시키지 않고 비교할 수 있습니다.

설명한 내용의 경우 기본 요소가 동일한 작업을 수행합니다. 이는 캐싱 및 성능 측면에서 대부분 중복됩니다.

명명 (아마도)

원래 개발자는 시스템 전체에서 공통 값에 대해 동일한 이름 지정 규칙을 제공하려고합니다. 이것은 특히 흔치 않은 값을 갖는 장점이 있지만 0과 같은 기본 값은 캐싱 사례의 경우에만 가치가 있습니다.

강제 유형 (대부분)

원래 개발자는 비교가 올바른 유형 및 가능한 특정 스케일 (소수 자릿수) 로 캐스트 되도록 특정 기본 유형을 강제하려고합니다 . 이것은 괜찮지 만, 간단한 이름 "zero"는 아마도이 사용 사례에 대한 세부 사항이 불충분 할 것입니다. ZERO_1DP는 더 적절한 의도 표현입니다.


2
강제 유형의 경우 +1 C ++과 같은 언어로 연산자 오버로드를 허용하고 상수를 정의하고 사용 typedef하면 변수 유형을 정확히 한 곳으로 유지하고 코드를 변경하지 않고도 변경할 수 있습니다.
Blrfl

3
강제 유형은 그들이 시도한 것이 아닐 가능성이 높지만 , 이것이 가능한 이유에 대한 가장 좋은 설명입니다 !
NWS

7
강제 유형의 경우 아마도을 사용하는 것이 좋습니다 0.0f.
Svish

바이트에 비트 연산자를 수행하면 바이트 결과가 생성되는 vb.net에서 경우에 따라 형식 강제가 유용 할 수 있습니다. 말하는 byteVar1 = byteVar2 Or CB128것보다 조금 더 좋은 것 같습니다 byteVar1 = byteVar2 Or CByte(128). 물론 바이트에 적절한 숫자 접미사를 사용하는 것이 더 좋습니다. C #은 연산자에 비트 단위의 피연산자를 승격하여 int결과가에 적합하다고 보장 될 때조차도 byte문제가되기 때문에 문제는 그다지 관련이 없습니다.
supercat

'0'에 대해 상수 이름을 0으로 확신 할 수 없지만 때로는 코드 가독성에 도움이됩니다. 예를 들어, 제로에이 상수를 갖는 - "ROOT_TYPE_ID 0 ="성명을 작성하는 데 도움이 될 것입니다 경우 같은 {...} (ID = ROOT_TYPE_ID!)
테크 마약 중독자

6

"툴링 잔소리"때문입니다

내가 여기에 표시되지 않는 가능한 이유는 많은 양질의 도구가 마술 숫자 사용을 표시하기 때문 입니다. 특히 코드의 여러 위치에 중복되는 경우 나중에 변경을 위해 명확하게 표시하지 않고 알고리즘에 매직 넘버를 던져 넣는 것은 나쁜 습관 입니다.

따라서 이러한 도구는 이러한 문제를 신고하는 데 적합하지만 이러한 값이 무해하고 정적이거나 대부분 초기화 값일 수있는 상황에 대해 오 탐지 를 생성하는 경우가 많습니다 .

그리고 그러한 일이 발생하면 때로는 다음과 같은 선택에 직면하게됩니다.

  • 도구가 허용하는 경우 (보통 도구를 사용하지 않는 사람들에게는 성가신 특수한 형식의 주석으로) 오 탐지로 표시
  • 또는 중요한지 여부에 관계없이 이러한 값을 상수로 추출합니다.

성능 정보

그것은 내가 생각하는 언어에 달려 있지만 Java에서는 상당히 일반적이며 값이 실제 상수 인 경우 컴파일 타임에 인라인되므로 성능에 영향을 미치지 않습니다 static final. 상수 또는 전 처리기 매크로로 선언 된 경우 C 또는 C ++에 영향을 미치지 않습니다.


5

명시 적 Zero으로 유형 으로 정의 되었기 때문에 의미가있을 수 있습니다 float.

C 및 C ++ 적어도 값 0.0유형 인 double등가물 동안 float이다 0.0f. 따라서 x당신이 비교하는 것은 항상 float말하는 것입니다.

x > 0.0

실제로 추진하면서 x하는 double유형과 일치하는의 0.0어떤 (평등 테스트 특히에) 문제가 발생할 수 있습니다. 전환없는 비교는 물론

x > 0.0f

어느 것과 같은

float Zero = 0.0; // double 0.0 converted to float  
x > Zero

그럼에도 불구하고 사용자가 어색한 코드를 작성하는 대신 컴파일러에서 변환 경고를 활성화하는 것이 훨씬 더 유용하다고 생각합니다.


1

우선, 여기서 0은로 정의 float되지 않습니다 int. 물론 이것은 비교에서 아무 영향을 미치지 않지만 다른 경우에는이 상수를 사용하면 차이가 발생할 수 있습니다.

나는 왜 Zero상수가 여기에 선언 되었는지 다른 이유를 알지 못합니다 . 코딩 스타일 일뿐이며 특정 프로그램의 다른 곳에서 사용되는 스타일을 따르는 것이 좋습니다.


1

(컴파일러가 매우 원시적 인 경우가 아니라면) 실행하는 동안 거의 정확하게 효율적이며 컴파일 중에는 효율성이 약간 떨어집니다.

그보다 더 읽기 쉬운 지 x > 0... 정직하고 진정으로 COBOL이 함께 일하기에 좋은 아이디어와 즐거움이라고 생각하는 사람들이 있다는 것을 기억하십시오. 그런 다음 C에 대해 똑같이 생각하는 사람들이 있습니다. C ++에 대해 같은 의견을 가진 일부 프로그래머도 존재합니다!) 다시 말해, 이 시점에서 일반적인 합의를 얻지 못할 것이며 아마도 싸울 가치가 없습니다.


0

[is] 이것은 실제로 다음보다 더 효율적이거나 읽기 가능하거나 유지 관리 가능합니다.

if (x > 0.0) {..}

당신은 서면으로 된 경우 일반적인 매우 가능성이 후, (즉, 비 타입 별) 코드. zero()함수는 대수 형식 또는 그룹 WRT 부가 어떤 유형에 적용 할 수있다. 정수, 부동 소수점 값, 변수 자체가 일부 선형 공간 내의 함수 인 경우 함수일 수도 있습니다 (예 : x는 z-> a_x 형식의 선형 함수입니다). z + b_x) 다음 기본 유형의 zero()a와 b를 함수에 제공합니다 zero().

따라서 C ++ (A zero()는 매우 일반적인 AFAIK는 아니지만) 또는 Julia 및 다른 언어로 이러한 코드를 기대할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.