컴퓨터가 0으로 나누려고 시도합니까?


59

우리는 모두 알고 0/0있다 Undefined내가 계산기에 넣어한다면 오류를 반환, 내가 프로그램을 작성한다면 내가 0으로 분할 할 때 (C에서 이상) 운영 체제가 종료됩니다.

그러나 내가 궁금해했던 것은 컴퓨터 가 0으로 나누려고 시도 하거나 "보호 기능이 내장되어" 0/0있는지 계산하여 계산하기 전에 오류를 반환하는지 여부입니다.


10
0/0은 정의되지 않았습니다. 다른 숫자 / 0은 다른 종류의 오류입니다. 두 가지를 혼동하는 것 같습니다
edc65

7
수학적으로 말하면 0으로 나눈 숫자는 정의되지 않습니다.
ManoDestra

12
@jwg : "값이 있다면 1이 될 것입니다."– 반드시 그런 것은 아닙니다. 거기에 수학의 전체 지점 값이 다른 상황에있을 수 있습니다 무엇에 전념가 :
psmears

11
여기서 용어를 명확하게하기 위해 0/0을 불확정 형식 이라고하며 0이 아닌 x의 경우 x / 0 은 정의되지 않습니다 . 0/0으로 끝나는 계산은 종종 다른 방법으로 계산되어 실제 답변을 제공하는 반면 x / 0은 본질적으로 의미가 없습니다.
시대

9
@jwg 당신은 l' hopital의 규칙에 관심이있을 것입니다. 0/0이 1의 값을 의미하지 않는 경우가 있습니다.
d0nut

답변:


74

CPU가 내장되어 있습니다. 대부분의 명령어 세트 아키텍처는 CPU가 0으로 정수를 나누기 위해 예외 처리기로 트랩하도록 지정합니다 (배당이 0인지 상관하지 않습니다).

나누기 시도와 함께 제로 제수가 제로에 대한 검사가 병렬로 발생할 수 있지만, 위반 조건을 감지하면 효과적으로 나누기와 트랩을 취소하므로 일부 부품이 있는지 실제로 알 수 없습니다 그것의 사단을 시도했다.

(하드웨어는 종종 여러 작업을 병렬로 수행 한 다음 적절한 결과를 선택하여 적절한 작업 선택에 따라 직렬화하는 대신 각 작업을 즉시 시작할 수 있기 때문에 종종 그렇게 작동합니다.)

오버 플로우 감지가 켜질 때 예외 메커니즘에 대한 동일한 트랩도 사용되며, 일반적으로 다른 add / sub / mul 명령어 (또는 해당 명령어의 플래그)를 사용하여 요청합니다.

부동 소수점 나누기도 0으로 나누기위한 감지 기능이 내장되어 있지만 예외 핸들러에 트래핑하는 대신 다른 값 ( IEEE 754는 NaN 지정)을 반환 합니다.


가설 적으로 CPU가 0으로 나누려는 시도를 생략하면 문제는 다음과 같습니다.

  • CPU 정지 (예 : inf. 루프) — CPU가 분자가 제수보다 작을 때 (절대 값으로) 중지하는 알고리즘을 사용하는 경우 발생할 수 있습니다. 이와 같은 중단은 CPU 충돌로 간주됩니다.
  • CPU가 카운터를 사용하여 가능한 최대 나누기 단계 수 (예 : 32 비트 시스템에서 31 또는 32)로 나누기를 종료하는 경우 (예측 가능한) 가비지 응답.

51
@Ankush "시스템 충돌"은 실제로 CPU 수준에서 발생하는 것이 아닙니다. 0으로 나누기를 잡지 않은 CPU의 가장 가능성이 높은 동작은 단순히 나누기 작업을 수행하고 일부 넌센스 결과를 생성하며 계속 진행한다는 것입니다. 오버플로가 발생하는 두 개의 정수를 추가 할 때와 같습니다.
Ixrec 2019

6
부동 소수점의 경우, "NaN"과 "trap"사이의 선택은 일반적으로 FPU에서 플래그를 뒤집어서 설정할 수 있습니다.
Vagin

10
@Ankush lxrec의 말이 불분명 한 경우 : CPU에 관한 한 충돌과 같은 것은 없습니다.
user253751

7
@Ankush CPU 수준의 "시스템 충돌"을 일으키는 상황은 거의 없습니다. 이러한 경우 열 보호 셧다운 (과열 보호), 3 중 오류 및 이와 유사한 상황에 대해 이야기 하고 있습니다. 유효하지 않은 opcodes를 포함하여 일반적인 사용에서 발생하는 거의 모든 충돌 은 어떤 방식으로 트랩 및 복구하거나 단순히 오류를 무시하고 잠재적으로 부정한 상태에서 실행을 계속하여 일부 오류 플래그를 설정했을 때 처리됩니다.
CVn

8
0으로 나누기를 트랩하지 않으면 프로그래밍 용어로 "정의되지 않은 동작"이 발생합니다. 이것은 컴퓨터가 무엇이든 할 수 있음을 의미합니다. Bergi가 언급했듯이 버그가있는 루프에 들어가서 매달릴 수 있습니다. 컴퓨터가 수학적으로 "나누지"않는다는 것을 기억하십시오. 두 개의 숫자로 연산을 수행하는데, 이는 나눗셈에 충분히 가깝습니다. 일반적으로 간단히 "나눗셈"이라고 부릅니다. 부동 소수점 반올림 참조).
Cort Ammon

34

언어, 컴파일러, 정수 또는 부동 소수점 숫자 등을 사용하는지 여부에 따라 다릅니다.

부동 소수점 수의 경우 대부분의 구현은 IEEE 754 표준을 사용하며 0으로 나누기가 잘 정의되어 있습니다. 0 / 0은 잘 정의 된 NaN (숫자가 아님)의 결과를 제공하고 x ≠ 0의 x / 0은 x의 부호에 따라 + Infinity 또는 -Infinity를 제공합니다.

C, C ++ 등의 언어에서 0으로 나누면 정의되지 않은 동작이 발생합니다. 언어 정의에 따르면 모든 일이 발생할 수 있습니다. 특히 당신이 일어나고 싶지 않은 것들. 코드를 작성할 때 모든 것이 완벽하게 작동하고 고객이 코드를 사용할 때 데이터가 파괴되는 것처럼. 따라서 언어 관점 에서이 작업을 수행하지 마십시오 . 일부 언어 는 응용 프로그램이 중단되도록 보장 합니다. 이것이 어떻게 구현되는지는 그들에게 달려 있습니다. 이러한 언어의 경우 0으로 나누면 충돌이 발생합니다.

많은 프로세서에는 일종의 내장 "분할"명령이 있으며, 이는 프로세서에 따라 다르게 동작합니다. Intel 32 비트 및 64 비트 프로세서에서 0으로 나누려고하면 "나누기"명령어가 응용 프로그램과 충돌합니다. 다른 프로세서는 다르게 작동 할 수 있습니다.

컴파일러가 일부 코드를 실행할 때 0으로 나누기가 발생하고 컴파일러가 사용자에게 친절하다는 것을 감지하면 경고 메시지를 표시하고 내장 "분할"명령을 생성하여 동작이 같은.


22
"인텔 32 비트 및 64 비트 프로세서에서"분할 "명령어는 0으로 나누려고하면 응용 프로그램이 중단됩니다." 인용이 필요했습니다. CPU는 응용 프로그램에 대해 전혀 모르고, 명령을 실행하고 (MMU를 포함하는 경우) 메모리 액세스 제한을 적용합니다 ( 링 0 이 아니거나 인텔 x86이 아닌 아키텍처와 동등한 경우 제외 ). 명령어는 응용 프로그램 B가 아닌 응용 프로그램 A의 일부이거나 운영 체제 구성 요소 C는 CPU와 관련이 없습니다. 명령어가 명령어 X 일 수 있는지 또는 메모리 주소 Y를 사용할 수 있는지 여부는 관련이 있습니다.
CVn

1
@ MichaelKjörling 의견에 추가하려면 : OS에는이 응용 프로그램 (및 다른 종류의 오류)을 알리는 방법이 있습니다. 윈도우 세계에서 그것은이다 EXCEPTION_INT_DIVIDE_BY_ZERO가치 EXCEPTION_RECORD에 의해 처리 될 것입니다 (희망) 설치 Structed 예외 처리 핸들러를
user45891

1
때로는 앱 충돌을 보장하는 것 이외의 작업을 수행하기도합니다. 예를 들어, 많은 언어 / 플랫폼은 0으로 나누면 예외가 발생합니다. 그런 다음 충돌없이 해당 예외를 포착하고 처리 할 수 ​​있습니다.
reirab

2
"다른 프로세서는 다르게 동작 할 수 있습니다"에서 "may"를 삭제할 수 있습니다. PowerPC 플랫폼에서 나눗셈은 0으로 나눕니다. X86 플랫폼의 당황스러운 행동보다 훨씬 유용합니다.
cmaster

13

누군가가 나누기 전에 명시 적으로 0을 확인하지 않는 CPU를 만들면 어떻게 될지 궁금해하는 것 같습니다. 일어날 일은 전적으로 부서의 구현에 달려 있습니다. 세부 사항으로 들어 가지 않고 한 종류의 구현은 16 비트 CPU에서 65535와 같이 모든 비트가 설정된 결과를 생성합니다. 다른 사람이 전화를 끊을 수 있습니다.


1

그러나 내가 궁금했던 것은 컴퓨터가 0으로 나누려고 시도하거나 "보호 기능이 내장되어"있고 0/0을 "보면"계산하기 전에도 오류를 반환하는지 여부입니다.

때문에 x/0아무 의미, 기간을하지 않으며, 컴퓨터는 항상 0으로 나누기를 확인해야합니다. 여기에 문제가 있습니다. 프로그래머 (a+b)/c는 계산이 타당한 지 확인하지 않아도 계산 을 원합니다 . CPU + 숫자 유형 + 운영 체제 + 언어에 의해 0으로 나누는 것에 대한 생생한 반응은 다소 과감한 것 (예 : 프로그램 충돌)을 수행하거나 지나치게 양성적인 것 (예 : IEEE 부동 소수점과 같은 의미 ( NaN숫자가 아님)

일반적인 환경에서 프로그래머는 (a+b)/c의미 가 있는지 알아야합니다 . 이와 관련하여 0으로 나누기를 확인할 이유가 없습니다. 0으로 나누기가 발생하고 기계 언어 + 구현 언어 + 데이터 유형 + 운영 체제에 대한 응답이 프로그램 충돌을 일으키는 것이라면 괜찮습니다. 응답이 결국 프로그램의 모든 숫자를 오염시킬 수있는 값을 작성하는 것이라면 괜찮습니다.

"신뢰할 수있는 것"또는 "과도한 양성"이 높은 신뢰성의 컴퓨팅 세계에서 올바른 일이 아닙니다. 이러한 기본 응답으로 인해 환자가 사망하거나 여객기가 추락하거나 폭탄이 잘못된 곳에서 폭발 할 수 있습니다. 신뢰성이 높은 환경 (a+b)/c에서 코드를 작성하는 동안 또는 현대에 글을 쓰는 프로그래머는 죽어가는 구조를 확인하는 도구에 의해 자동으로 죽을 것이다. 이 환경에서 해당 프로그래머는 대신 줄을 따라 무언가를 작성 했어야 div(add(a,b),c)하고 오류 상태를 확인해야합니다. 후드 아래에서 div(및 add) 기능 / 매크로는 0으로 나눠지는 것을 방지합니다 (또는 경우에는 오버플로 add). 그 보호가 수반하는 것은 구현에 따라 다릅니다.


NaN의 당신이 학교에서 배운 산술 순종하지 않는해서 수행은하지 않습니다 의미하지 아무 의미. 그것은 다른 산술을
따릅니다

-2

우리는 지금 알고 x/0하고 0/0잘 정의 된 답변이 없습니다. 0/0어쨌든 계산을 시도하면 어떻게됩니까?

최신 시스템에서는 계산이 CPU 내의 MPU로 전달되고을 반환하는 잘못된 작업으로 플래그가 지정됩니다 NaN.

온칩 부서가없는 80 년대 가정용 컴퓨터와 같은 훨씬 오래된 시스템에서 계산은 실행중인 소프트웨어에 따라 수행되었습니다. 몇 가지 가능한 선택 사항이 있습니다.

  • 값이 0에 도달 할 때까지 제수의 작고 작은 사본을 빼고 크기가 지정된 사본을 빼는 것을 추적합니다.
    • 첫 번째 빼기 전에 0을 확인하면 빠르게 종료되고 결과는 0
    • 그것이 적어도 한 번 빼야한다고 가정하면 결과는 1
  • 두 숫자의 로그를 계산하고 빼고 e 를 결과의 거듭 제곱으로 올립니다 . 위의 빼기 방법과 비교할 때 매우 비효율적 인 방법이지만 수학적으로 유효합니다.
    • 계산하려고하면 오버플로가 발생할 수 log(0)있으며 소프트웨어에서 오류 처리 루틴을 사용하거나 충돌합니다
    • 소프트웨어는 모든 로그를 고정 된 단계 수로 계산할 수 있다고 가정하지만 크지 만 잘못된 값을 반환합니다. 두 로그가 동일하기 때문에 차이는 0e 0 = 1이되며 결과는 다음과 같습니다.1

다시 말해, 구현에 따라 구현이 달라질 수 있으며, 모든 값에 대해 정확하고 예측 가능한 결과를 생성하지만 그에 대한 이상한 값은 0/0여전히 내부적으로 일관성이있는 소프트웨어를 작성할 수 있습니다 .


3
이 질문은 정수에서 0으로 나누는 것에 관한 것이며 정수와 같은 것은 없습니다 NaN.
David Hammen

3
CPU가 로그를 계산하지 않고 나누기 결과를 계산하기 위해 빼지 않습니다. 로그 명령 타이밍은 나누기보다 몇 배 더 큽니다. log (0)의 값은 무엇입니까?
wallyk

1
@DavidHammen OP는 한 번도 정수를 언급하지 않았으며 질문에 대해 언급 한 사람도 없었습니다. 정수는 답변에서만 언급됩니다.
CJ Dennis

@ wallyk 나는 이미 대답에서 로그가 very inefficient나누기위한 것이라고 말했습니다 . 산술 비용은 (더하기 = 빼기) <= 곱셈 <= 나누기입니다. 더하기 (보통 1 개)와 동일한 수의 클럭 주기로 나눌 수있는 MPU가없는 경우 나누기는 더하기와 빼기보다 비싸고 일반적으로 곱셈보다 비쌉니다.
CJ Dennis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.