음의 제로가 중요한 이유는 무엇입니까?


64

왜 우리가 양수와 음수 0에 대한 다른 표현에 관심이 있는지에 대해 혼란 스럽습니다.

나는 복소수를 포함하는 프로그래밍에서 음의 0 표현을 갖는 것이 매우 중요하다는 주장을 읽는 것을 모호하게 기억합니다. 나는 복잡한 숫자를 포함하는 코드를 작성할 기회가 없었기 때문에 이것이 왜 그런지에 대해 약간 당황했습니다.

개념에 관한 Wikipedia의 기사 는 특별히 도움이되지 않습니다. 내가 올바르게 이해한다면 부동 소수점에서 특정 수학 연산을 간단하게 만드는 부호없는 0에 대한 모호한 주장 만합니다. 이 답변 에는 다르게 작동하는 몇 가지 기능 나열되어 있으며 사용 방법에 익숙하다면 예제에서 무언가를 유추 할 수 있습니다. (하지만이 복잡한 제곱근의 특정 예는 플랫 아웃 보이는 잘못, 두 개의 숫자는 수학적으로 동일하기 때문에 오해가 없다면 말입니다.) 그러나 거기에 없을 경우 어떤 종류의 문제가 발생했는지 분명하게 알 수 없었습니다. 내가 찾을 수 있었던 더 많은 수학적 자원은 수학적 관점에서 두 가지를 구별하지 못한다는 것을 나타내며, Wikipedia 기사는 이것이 한계를 설명하는 것 외에는 컴퓨팅 외부에서는 거의 볼 수 없다고 제안하는 것 같습니다.

그렇다면 왜 계산에서 음의 영점이 가치가 있습니까? 나는 단지 뭔가를 놓치고 있다고 확신합니다.


6
음수 0은 IEEE 부동 소수점 수에서 언더 플로를 표시 할 수 있지만 그 이상으로 논란의 여지가 있고 모호한 것으로 보입니다. 내가 추측한다면, 음수 0은 IEEE 부동 소수점으로 표현된다고 말할 수 있습니다. 더욱 흥미로운 라이딩을 위해서는 부동 소수점 신호 NaN에 대한 정보를 찾아보십시오.
Robert Harvey

1
특정 예가 "1 / 0.0"/ "1 / -0.0"인 경우 0은 1 / x에 대한 분기 절단이며 한계는 아래 또는 위에서 접근하는 경우에 따라 다릅니다.
Vatine

@Vatine 아니요, 특정 예는 sqrt(-1+0i) = isqrt(-1-0i) = -i입니다. 일부 프로그래밍 언어에 대한 적절한 구문으로 꾸며져 있지만 믿습니다. 더 명확하게 편집하겠습니다.
jpmc26

3
내가 검색 프로그래머 , 스택 오버플로 , 컴퓨터 과학 , 수학공학 . 내가 찾을 수있는 유일한 질문 은 음의 0 부동 소수점 값에 대한 사용입니까? . 이것이 두 번째로 등장한 것은 아닙니다!

복잡한 숫자가 답에서 전혀 나오지 않는다는 사실에 특히 놀랐습니다. 특히 내가 지적한 제곱근의 예를 들었습니다.
jpmc26

답변:


69

FPU 산술에서 0은 반드시 정확히 0을 의미 할 필요는 없지만 주어진 데이터 유형을 사용하여 표현하기에는 너무 작은 값입니다.

a = -1 / 1000000000000000000.0

a가 너무 작아 float (32 비트)로 올바르게 표현할 수 없으므로 -0으로 "반올림"됩니다.

이제 계산이 계속된다고 가정 해 봅시다.

b = 1 / a

a가 float이므로 -infinity가되어 정답 -1000000000000000000.0과는 거리가 멀다

이제 -0이 없으면 b를 계산하십시오 (따라서 a는 +0으로 반올림됩니다).

b = 1 / +0
b = +infinity

반올림으로 인해 결과가 다시 잘못되지만 이제는 숫자가 아니라 다른 부호로 인해 "더 이상 잘못되었습니다"(계산 결과는 + 무한, 올바른 결과는 -1000000000000000000.0)입니다.

둘 다 잘못되었으므로 실제로 중요하지 않다고 말할 수 있습니다. 중요한 것은 계산의 가장 중요한 결과가 부호가있는 많은 수의 응용 프로그램이 있다는 것입니다. 예를 들어 일부 기계 학습 알고리즘을 사용하여 교차로에서 좌회전 또는 우회전을 결정할 때 양수 값 => 회전을 해석 할 수 있습니다 왼쪽, 음수 => 우회전, 값의 실제 "크기"는 단지 "신뢰 계수"입니다.


언더 플로 부호가 허수 / 복소수 계산에 특히 중요한지 여부에 대한 아이디어가 있습니까?
jpmc26

@ qbd : 그 숫자 응용 프로그램이 무엇인지 알고 있습니까? 나는 트리거하고 사용 +inf하고 -inf정상 작동중인 프로그램에 버그 가 있다고 말합니다 .
Björn Lindqvist 2016 년

@ BjörnLindqvist 만약 당신이 구체적이고 다운로드 가능한 응용 프로그램을 원한다면-나는 모른다. 필자는 버그가 있다고 생각하지 않습니다 .float / double 대신 BigDecimal과 같은 것을 무제한 정밀도로 사용할 수 있습니다. 그러나 프로그램이 float / double을 사용하는 것과 정확히 동일한 결과를 제공하지만 성능이 훨씬 나쁜 경우에는 그만한 가치가 있습니까?
qbd 2016 년

"계산의 가장 중요한 결과가 부호 인 숫자 형 응용 프로그램"을 썼지 만 -0과 값이 +inf및 에 의존하는 잘 작성된 응용 프로그램이 있다고 믿을 수는 없습니다 -inf. 프로그램이 부동 소수점 언더 플로를 발생시키는 경우 이는 버그이며 이후에 발생하는 일은 그리 흥미롭지 않습니다. 우리는 여전히 -0이 유용한 실용적인 예제를 놓치고 있습니다.
Björn Lindqvist 2016 년

1
@ BjörnLindqvist x265의 많은 부분은 성능에 대해 아는 사람들이 모호한 세부 사항 (CPU 아키텍처에 따라 다름)에 의존하여 어셈블리로 이루어집니다. 잘못 됐나? 성능 이름에서 간단하고 잘 이해 된 기능 하나에 대해 널리 구현 된 30 년 된 표준 (여기서는 여기 있음)에 의존하는 것이 갑자기 그리 나쁘지 않은 것처럼 보입니다.
qbd

8

먼저, -0을 어떻게 만드나요? 두 가지 방법이 있습니다. (1) 수학 결과가 음수 인 부동 소수점 연산을 수행하지만 0에 가까워 0이 아닌 숫자가 아닌 0으로 반올림됩니다. 그 계산은 -0을 줄 것입니다. (b) 0과 관련된 특정 연산 : 양수 0에 음수를 곱하거나 양수 0을 음수로 나누거나 양수 0을 부정합니다.

음수 0을 가하면 곱셈과 나눗셈이 약간 단순화됩니다. x * y 또는 x / y의 부호는 항상 x의 부호, 배타적이거나 y의 부호입니다. 음수 0이 없으면 -0을 +0으로 바꾸려면 추가 검사가 필요합니다.

유용한 아주 드문 상황이 있습니다. 언더 플로가 있어도 곱셈 또는 나눗셈의 결과가 수학적으로 0보다 크거나 작은 지 여부를 확인할 수 있습니다 (결과가 수학적으로 0이 아님을 아는 한). 차이가 나는 곳에 코드를 작성한 것을 기억할 수 없습니다.

컴파일러 최적화는 -0을 싫어합니다. 예를 들어 x가 -0.0이면 결과는 x가 아니므로 x + 0.0을 x로 바꿀 수 없습니다. x <0 또는 x가 -0.0 인 경우 결과는 -0.0이어야하므로 x * 0.0을 0.0으로 바꿀 수 없습니다.


7
IEEE-754에 "정확한", 양의 무한대, 음의 무한대, 부호없는 4 개의 0이 포함 되었으면합니다 (후자는 구별 할 수없는 값의 차이). 그렇게하면 많은 부동 소수점 공리가 작동했을 것입니다. x) [x가 양의 0이면, 둘 다 pos-inf가 될 것임; 음의 값이 0이면, 음의 값이 둘 다입니다. 정확하거나 서명되지 않은 경우, NaN].
supercat

내가 전달하여 부의 제로를 얻을 수있었습니다 -55fmod(). 내 유스 케이스에는 상당히 성가신 일입니다.
Aaron Franke

6

IEEE 754를 준수하는 C # Double

    double a = 3.0;
    double b = 0.0;
    double c = -0.0;

    Console.WriteLine(a / b);
    Console.WriteLine(a / c);

인쇄물:

Infinity
-Infinity

실제로 조금 설명하기 위해 ...

Double d = -0.0; 

이것은 d = The Limit of x as x approaches 0-또는에 더 가까운 것을 의미합니다 The Limit of x as x approaches 0 from the negatives.


Philipp의 의견을 전하기 위해 ...

기본적으로 음수 0은 언더 플로를 의미합니다.

마이너스 제로에 대한 실질적인 사용은 거의 없습니다 ...

예를 들어이 코드 (C #)는 다음과 같습니다.

double a = -0.0;
double b = 0.0;

Console.WriteLine(a.Equals(b));
Console.WriteLine(a==b);
Console.WriteLine(Math.Sign(a));

이 결과를 얻습니다.

True
True
0

비공식적으로 설명하자면, IEEE 754 부동 소수점이 가질 수있는 모든 특수 값 (양의 무한대, 음의 무한대, NAN, -0.0)은 실제 의미에서 의미가 없습니다. 물리적 가치 나 "실제"계산에 의미가있는 가치를 나타낼 수 없습니다. 그들이 의미하는 것은 기본적으로 이것입니다 :

  • 양의 무한대는 부동 소수점이 나타낼 수있는 양의 끝에서 오버플로를 의미합니다.
  • 음의 무한대는 부동 소수점이 나타낼 수있는 양의 끝에서 오버플로를 의미합니다.
  • 음수 0은 언더 플로를 의미하며 피연산자는 반대 부호를 가짐
  • 양의 0 언더 플로를 의미 할 수 있으며 피연산자는 동일한 부호를가집니다.
  • NAN은 귀하의 계산이 과도하게 정의되지 않았 거나 이와 같은 sqrt(-7)제한 이 없음을 의미합니다0/0PositiveInfinity/PositiveInfinity

7
예, 그러나 이것이 왜 중요합니까? 차이가 중요한 실제 사례를 제공 할 수 있습니까?
Philipp

5

이것이 복소수 계산과 어떤 관련이 있는지에 대한 질문은 실제로 +0과 -0이 모두 부동 소수점에 존재하는 이유의 핵심입니다. 복소수 분석을 전혀 연구하지 않으면 복소수에서 복소수까지의 연속 함수는 출력이 '리만 표면 (Riemann surface)'으로 알려진 '정치 소설'을 채택하지 않는 한 일반적으로 '단일 가치'로 취급 될 수 없음을 신속하게 발견 할 수 있습니다. 예를 들어, 복잡한 로그는 각 입력에 무한히 많은 출력을 할당합니다. 연속 출력을 형성하기 위해 '연결'할 때, 모든 실제 부품은 원점 주위에 '무한 코르크 마개'표면을 형성하게됩니다. '긍정 가상 측면에서 아래쪽으로'실제 축을 가로 지르는 연속 곡선과 '극을 감싸고'실제 축을 가로 지르는 다른 곡선 '

이제 복잡한 부동 소수점을 사용하여 계산하는 수치 프로그램에 적용하십시오. 주어진 계산 후 수행되는 작업은 프로그램이 현재 '설정된'시트에 따라 매우 다를 수 있으며 마지막 계산 결과의 부호는 아마도 '시트'를 알려줍니다. 이제 결과가 0이라고 가정하십시오. 여기서 '제로'는 실제로 '정확하게 표현하기에는 너무 작습니다'를 의미합니다. 그러나 결과가 0 일 때 계산에서 부호를 유지 (즉, 어떤 '시트'를 기억) 할 수 있다면 코드는 부호를 확인하고이 상황에서도 올바른 조치를 수행 할 수 있습니다.


1

그 이유는 평소보다 간단합니다

물론 정말 멋져 보이는 많은 해킹 이 있으며 유용합니다 (반올림 -0.0또는 반올림과 같이 +0.0시작 부분에 마이너스 / 더하기 기호가있는 부호있는 int의 표현이 있다고 가정합니다 (U2 바이너리 코드로 해결됨) 일반적으로 정수로 표시되지만 덜 복잡한 double 표현으로 가정)

0 111 = 7
^ sign

음수가 있으면 어떻게합니까?

1 111 = -7

좋아요, 간단합니다. 따라서 0을 나타내겠습니다.

0 000 = 0

그것도 괜찮습니다. 그러나 어떻 1 000습니까? 금지 된 숫자 여야합니까? 안돼

따라서 두 가지 유형의 0이 있다고 가정합니다.

0 000 = +0
1 000 = -0

글쎄, 그것은 계산을 단순화하고 추가 기능을 반올림합니다. 그래서 +0와는 -0단지 바이너리 표현의 문제에서오고있다.


6
내가 이것을 올바르게 읽고 있다면, 당신은 본질적으로 표준을 정의하거나 구현하는 사람들이 그것을 금지하는 문제에 가고 싶지 않다고 말하는 것입니다. 나는이 추론이 2의 보수가 완전히 다른 숫자에 대해 "음의 0"표현을 사용하고 음의 0을 나타내지 않는다는 사실을지지하지 않는다고 생각한다. 내가 링크 한 Wikipedia 기사를 참조하십시오.
jpmc26

1
@ jpmc26 실제로 그 사실에 대해 약간의 진실 이 있다고 생각합니다. 금지하지 않으면 구현에 특별한 경우가 필요하지 않습니다. 있는 그대로 모든 숫자는 부호 비트를 가지며 부호 비트를 토글하여 무효화 할 수 있습니다. NaN조차도 서명되며 구현에서는 NaN을 생성 할 때 적절한 기호를 선택할 수 있습니다 (그러나 필수는 아닙니다). 음의 0이 존재하지 않으면 0을 초래 한 모든 계산은 부호 비트 등을 수정하기 위해 추가 작업을 수행해야합니다.
hobbs

4
@ jpmc26 (즉, 두 숫자의 다른 모든 곱셈에서 결과의 부호는 곱하기 부호의 xor이고 크기는 두 크기의 곱입니다. 실제로는 -1 * 0 =- 0. 그러나 부호 비트가 뒤집힌 0이 특별한 0이 아닌 값이라면 0을 생산할 수있는 모든 제품은 실수로 그 특별한 값을 생산하지 않는지 확인하고 확인해야합니다.)
hobbs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.