예외를 지원하지 않는 언어에서 0으로 나누기를 처리하는 방법은 무엇입니까?


62

일부 비즈니스 요구 사항을 해결하기 위해 새로운 프로그래밍 언어를 개발하는 중입니다.이 언어는 초보자 사용자를 대상으로합니다. 따라서 언어에서 예외 처리를 지원하지 않으므로 추가해도 예외를 사용할 것으로 기대하지 않습니다.

나누기 연산자를 구현 해야하는 시점에 도달했으며 0으로 나누기 오류를 가장 잘 처리하는 방법이 궁금합니다.

이 사례를 처리 할 수있는 방법은 세 가지 뿐인 것 같습니다.

  1. 오류를 무시하고 0결과로 생성 하십시오. 가능하면 경고를 기록합니다.
  2. NaN숫자의 가능한 값으로 추가 하되 NaN, 언어의 다른 영역에서 값 을 처리하는 방법에 대한 질문 을합니다.
  3. 프로그램 실행을 종료하고 심각한 오류가 발생한 경우 사용자에게보고하십시오.

옵션 # 1이 유일한 합리적인 해결책 인 것 같습니다. 이 언어는 야간 크론으로 논리를 실행하는 데 사용되므로 옵션 # 3은 실용적이지 않습니다.

0으로 나누기 오류를 처리하는 대안은 무엇이며 옵션 # 1을 사용할 때의 위험은 무엇입니까?


12
예외 지원을 추가하고 사용자가이를 파악하지 못하면 옵션 # 3이 있습니다.
ratchet freak

82
궁금합니다. 완전히 새로운 프로그래밍 언어를 만들어야하는 어리석은 요구 사항은 무엇입니까? 내 경험상, 모든 언어는 (디자인 또는 실행, 종종 두 가지 모두에서) 짜증을 냈고, 그렇게 많은 것을 얻기 위해서는 부당하게 많은 노력 필요했습니다. 첫 번째에는 예외가 있지만 두 번째에는 예외가 없으며, 사례의 0.01 % 미만이면 측정 오류 일 수 있습니다. ;-)

16
@delnan 대부분의 새로운 언어는 비즈니스 규칙을 구현 방식과 분리 할 수 ​​있도록 만들어졌습니다. 사용자 reject "Foo"는 구현 방법을 알 필요 는 없지만 키워드가 포함 된 문서는 거부합니다 Foo. 사용자가 익숙한 용어를 사용하여 언어를 읽기 쉽게 만들려고합니다. 사용자에게 고유 한 프로그래밍 언어를 제공하면 기술 직원의 도움없이 비즈니스 규칙을 추가 할 수 있습니다.
Reactgular

19
@Mathew Foscarini. 절대로 오류를 무시하고 자동으로 0을 반환하지 마십시오. 나누기를 할 때 0은 완벽하게 유효한 값일 수 있습니다 (어떤 이유로 Power Basic에는 그러한 것이 있으며 실제로 고통 스럽습니다). 부동 소수점 숫자를 나누면 Nan 또는 Inf가 좋습니다 ( 이유를 이해하기 위해 IEEE 754 를 살펴보십시오 ). 정수를 나누면 프로그램을 중지 할 수 있습니다. 0으로 나누면 안됩니다 (실제 예외 시스템을 구현하지 않는 한).

16
저는 독점적이고 Turing-complete 프로그래밍 언어를 정당화 할 수있을만큼 비즈니스 영역이 복잡하지만 놀랍도록 부정확 한 결과를 견딜 수있을 정도로 느슨합니다.
Mark E. Haase

답변:


98

오류를 무시하는 것은 위험한 안티 패턴이기 때문에 # 1에 강력히 권합니다. 분석하기 어려운 버그로 이어질 수 있습니다. 나누기 결과를 0으로 0으로 설정하면 아무런 의미가 없으며, 무의미한 값으로 프로그램을 계속 실행하면 문제가 발생합니다. 특히 프로그램이 무인으로 실행될 때. 프로그램 인터프리터가 프로그램에 오류가 있음을 발견하면 (0으로 나누기는 거의 항상 설계 오류 임),이를 중단하고 모든 것을 그대로 유지하는 것이 일반적으로 데이터베이스를 쓰레기로 채우는 것보다 선호됩니다.

또한이 패턴을 철저히 따르는 데 성공하지 못할 수도 있습니다. 조만간 메모리 부족 또는 스택 오버플로와 같이 무시할 수없는 오류 상황이 발생하고 프로그램을 종료하는 방법을 구현해야합니다.

옵션 # 2 (NaN 사용)는 약간의 작업이지만 생각만큼 많지는 않습니다. 다른 계산에서 NaN을 처리하는 방법은 IEEE 754 표준에 잘 설명되어 있으므로 통역사가 작성한 언어로 수행 할 수 있습니다.

그건 그렇고 : 프로그래머가 아닌 사람이 사용할 수있는 프로그래밍 언어를 만드는 것은 1964 년 이후 (Dartmouth BASIC) 시도한 것입니다. 지금까지 우리는 실패했습니다. 어쨌든 행운을 빈다.


14
+1 감사합니다. 당신은 저에게 오류를 던지도록 설득했고, 지금 당신의 대답을 읽었으므로 나는 왜 주저했는지 이해할 수 없습니다. PHP나에게 나쁜 영향을 미쳤다.
Reactgular

24
네, 그것은이. 귀하의 질문을 읽었을 때, 나는 잘못된 출력을 생산하고 오류가 발생할 때 트럭 운송을 계속하는 것이 PHP와 매우 흡사하다고 생각했습니다. PHP가 예외 인 이유는 여러 가지가 있습니다.
Joel

4
기본 댓글에 +1 NaN초보자의 언어로 사용 하는 것은 좋지 않지만 일반적으로 큰 대답입니다.
로스 패터슨

8
@Joel 그가 오래 살았다면, Dijkstra는 아마도 [[PHP]의 사용은 마음을 망칠 것이므로 그 가르침은 범죄 행위로 간주되어야합니다. "
로스 패터슨

12
@ 로스. "컴퓨터 과학 오만 나노 Dijkstras로 측정됩니다"- 앨런 케이 (Alan Kay)

33

1-오류를 무시 0하고 결과로 생성 하십시오. 가능하면 경고를 기록합니다.

그건 좋은 생각이 아니다. 조금도. 사람들은 그것에 따라 시작하고 그것을 고쳐야한다면 많은 코드를 깨뜨릴 것입니다.

2- NaN숫자의 가능한 값으로 추가 하되 NaN, 언어의 다른 영역에서 값 을 처리하는 방법에 대한 질문 을합니다.

다른 언어의 런타임이 수행하는 방식으로 NaN을 처리해야합니다. 추가 계산을 수행하면 NaN이 생성되고 모든 비교 (NaN == NaN도 포함)는 false를 생성합니다.

나는 이것이 수용 가능하지만 반드시 새로운 친근한 것은 아닙니다.

3-프로그램 실행을 종료하고 심각한 오류가 발생한 경우 사용자에게보고하십시오.

이것이 내가 생각하는 최고의 솔루션입니다. 이러한 정보를 보유한 사용자는 0을 처리 할 수 ​​있어야합니다. 특히 밤에 한 번 실행하려는 경우 테스트 환경을 제공해야합니다.

네 번째 옵션도 있습니다. 나누기를 삼항 연산으로 만듭니다. 이 두 가지 중 하나가 작동합니다.

  • div (분자, 분자, alternative_result)
  • div (분자, 분자, alternative_denumerator)

당신이 만드는하지만 NaN == NaNfalse, 당신은 추가해야합니다 isNaN()사용자가 감지 할 수 있도록 기능을 NaN들.
AJMansfield

2
@AJMansfield : 또는 사람들이 직접 구현합니다 : isNan(x) => x != x. 그래도 NaN프로그래밍 코드가 나오면 isNaN검사 추가를 시작하지 말고 원인을 추적하여 필요한 검사를 수행해야합니다. 따라서 NaN완전히 전파 하는 것이 중요합니다 .
back2dos

5
NaNs는 주로 반 직관적입니다. 초보자의 언어로, 그들은 도착하자 죽었습니다.
로스 패터슨

2
@RossPatterson 그러나 초보자는 쉽게 말할 수 있습니다 1/0-당신은 그것에 뭔가를해야합니다. Inf또는 NaN프로그램에 오류를 더 전파시키는 것 이외의 유용한 결과는 없습니다 . 그렇지 않으면 유일한 해결책은이 시점에서 오류와 함께 중지하는 것입니다.
Mark Hurd

1
옵션 4는 함수의 호출을 허용하여 개선 될 수 있으며, 이는 예기치 않은 0 제수에서 복구하는 데 필요한 모든 조치를 수행 할 수 있습니다.
CyberFonic

21

극단적 인 편견으로 실행중인 응용 프로그램을 종료하십시오. (적절한 디버그 정보를 제공하는 동안)

그런 다음 제수가 0 일 수있는 조건 (사용자가 입력 한 값 등)을 식별하고 처리하도록 사용자를 교육하십시오.


13

Haskell (및 스칼라와 유사)에서 예외를 던지거나 널 참조를 리턴하는 대신 랩퍼 유형 MaybeEither사용할 수 있습니다. 으로 Maybe사용자 그가 얻은 값이 "빈"의 경우 테스트 할 수있는 기회를 가지고, 또는 그는 "풀기"기본값을 제공 할 수 있습니다. Either비슷하지만 문제가있는 경우 문제를 설명하는 개체 (예 : 오류 문자열)를 반환하는 데 사용할 수 있습니다.


1
그러나 Haskell은 이것을 0으로 나누는 데 사용하지 않습니다. 대신 모든 하스켈 유형은 암시 적으로 가능한 값으로 "하단"을가집니다. 이것은 종료에 실패한 표현식의 "값"이라는 점에서 널 포인터와 다릅니다. 물론 종료되지 않은 값은 테스트 할 수 없지만 운영 의미론에서 종료에 실패한 경우는 표현식의 의미의 일부입니다. Haskell에서이 "bottom"값 error "some message"은 평가중인 함수 와 같은 추가 오류 사례 결과도 처리합니다 .
Steve314

개인적으로 전체 프로그램을 중단 한 효과가 유효한 것으로 간주되면 순수한 코드가 예외를 던지는 효과를 가질 수없는 이유는 모르겠지만 Haskell순수한 식은 예외를 throw 할 수 없습니다.
Steve314

예외를 던지는 것 외에도 제안 된 모든 옵션이 사용자에게 실수를 한 것으로 의사 소통하지 않기 때문에 이것이 좋은 생각이라고 생각합니다. 기본 아이디어는 사용자가 프로그램에 제공 한 값으로 실수를하므로 프로그램이 사용자에게 잘못된 입력을했다고 알려 주어야합니다 (그런 다음 사용자는 해결 방법을 생각할 수 있음). 사용자에게 자신의 실수를 알려주지 않으면 어떤 해결책이라도 너무 이상하게 느껴집니다.
정보 : A

나는 이것이 갈 길이라고 생각한다 ... Rust 프로그래밍 언어는 그것을 표준 라이브러리에서 광범위하게 사용한다.
aochagavia

12

다른 답변은 이미 아이디어의 상대적인 장점을 고려했습니다. 나는 또 다른 것을 제안합니다 : 변수 가 0 일 있는지 여부를 결정하기 위해 기본 흐름 분석을 사용하십시오 . 그런 다음 잠재적으로 0 인 변수로 나누기를 허용하지 않을 수 있습니다.

x = ...
y = ...

if y ≠ 0:
  return x / y    // In this block, y is known to be nonzero.
else:
  return x / y    // This, however, is a compile-time error.

또는 변하지 않는 변수를 설정하는 지능적인 어설 션 함수를 사용하십시오.

x = ...
require x ≠ 0, "Unexpected zero in calculation"
// For the remainder of this scope, x is known to be nonzero.

이는 정의되지 않은 작업을 완전히 없애는 런타임 오류를 발생시키는 것만큼이나 좋지만, 잠재적 인 오류가 노출되기 위해 코드 경로에 도달 할 필요가 없다는 이점이 있습니다. 불변량을 추적하고 확인하기 위해 중첩 된 타이핑 환경으로 프로그램의 모든 분기를 평가하여 일반적인 유형 검사와 매우 유사합니다.

x = ...           // env1 = { x :: int }
y = ...           // env2 = env1 + { y :: int }
if y ≠ 0:         // env3 = env2 + { y ≠ 0 }
  return x / y    // (/) :: (int, int ≠ 0) → int
else:             // env4 = env2 + { y = 0 }
  ...
...               // env5 = env2

또한 null언어에 그러한 기능이있는 경우 자연스럽게 범위와 검사 까지 확장됩니다 .


4
깔끔한 아이디어이지만 이러한 유형의 구속 조건 해결은 NP-complete입니다. 같은 것을 상상해보십시오 def foo(a,b): return a / ord(sha1(b)[0]). 정적 분석기는 SHA-1을 반전시킬 수 없습니다. Clang에는 이러한 유형의 정적 분석 기능이 있으며 얕은 버그를 찾는 데 유용하지만 처리 할 수없는 경우가 많습니다.
Mark E. Haase

9
이것은 NP- 완료가 아니며 불가능합니다. 그러나 정적 분석기는이 문제를 해결할 필요가 없으며, 이와 같은 문장을 긁어 내고 명시 적 주장이나 장식을 추가해야합니다.
MK01

1
@ MK01 : 즉, 분석은 "보수적"입니다.
존 퍼디

11

숫자 1 (삽입 할 수없는 0 삽입)은 항상 잘못되었습니다. # 2 (전파 NaN)와 # 3 (프로세스 중단) 중에서 선택하는 것은 컨텍스트에 따라 다르며 Numpy와 마찬가지로 전역 설정이 이상적입니다.

하나의 큰 통합 계산을 수행하는 경우 NaN을 전파하는 것은 결국 전체 계산에 영향을 미쳐서 영향을 미치기 때문에 나쁜 생각입니다. 아침에 결과를보고 모두 NaN임을 알면 d 결과를 버리고 어쨌든 다시 시작해야합니다. 프로그램이 종료되면 한밤중에 전화를 받고 문제를 해결하는 것이 더 좋았을 것입니다. 적어도 시간 낭비라는 말입니다.

지도 축소 또는 난해한 병렬 계산과 같이 대부분 독립적 인 작은 계산을 많이하고 NaN으로 인해 사용할 수없는 비율을 허용 할 수있는 것이 가장 좋은 방법 일 것입니다. 프로그램을 종료하고 99 %를 잘못하고 1 %로 잘못되고 0으로 나눠서 유용하고 유용한 것은 실수 일 수 있습니다.

NaN과 관련된 다른 옵션 : 동일한 IEEE 부동 소수점 사양은 Inf 및 -Inf를 정의하며, NaN과 다르게 전파됩니다. 예를 들어, Inf> any number 및 -Inf <any number는 제로가 작은 숫자로 가정되어 0으로 나누기가 발생하면 원하는 것입니다. 입력이 반올림되고 측정 오류 (예 : 손으로 측정 한 물리적 측정)가 발생하는 경우 두 대량의 차이가 0이 될 수 있습니다. 0으로 나누지 않으면 큰 숫자를 얻었을 것입니다. 이 경우 In 및 -Inf는 올바른 결과입니다.

공식적으로도 정확할 수 있습니다. 확장 된 영역에서 작업 중이라고 말하면됩니다.


그러나 분모가 양수인지 음수인지는 알 수 없으므로 -inf가 필요할 때 + inf가 나올 수 있으며 그 반대도 마찬가지입니다.
다니엘 루바 로프

사실, 측정 오류가 너무 작아 + inf와 -inf를 구분할 수 없습니다. 이것은 리만 구체와 가장 유사하며, 전체 복잡한 평면은 정확히 하나의 무한 점 (원점과 정반대 인 점)이있는 공에 매핑됩니다. 매우 큰 양수, 매우 큰 음수 및 매우 큰 허수 및 복소수는 모두 하나의 무한 점에 가깝습니다. 약간의 측정 오류가 있으면이를 구별 할 수 없습니다.
Jim Pivarski

이러한 종류의 시스템에서 작업하는 경우, 이진 표현이 다르더라도 +0과 -0을 동등한 것으로 식별해야하는 것처럼 + inf와 -inf를 동등한 것으로 식별해야합니다.
Jim Pivarski

8

3. 프로그램 실행을 종료하고 심각한 오류가 발생한 경우 사용자에게보고하십시오.

[이 옵션]은 실용적이지 않습니다…

물론 실용적이다 : 실제로 이해되는 프로그램을 작성하는 것은 프로그래머의 책임이다. 0으로 나누는 것은 의미가 없습니다. 따라서, 프로그래머가 나누기를 수행하는 경우, 제수가 제로가 아닌지 미리 확인하는 것은 또한 자신의 책임입니다 . 프로그래머가 유효성 검사를 수행하지 못하면, 그 실수를 즉시 인식해야합니다. 비정규 화 (NaN) 또는 부정확 한 (0) 계산 결과는 그 점에서 도움이되지 않습니다.

옵션 3은 가장 간단하고 정직하며 수학적으로 올바른 것으로 btw에게 추천 한 것입니다.


4

오류가 무시되는 환경에서 중요한 작업 (예 : "야간 크론")을 실행하는 것은 나에게 나쁜 생각 인 것 같습니다. 이것을 기능으로 만드는 것은 끔찍한 생각입니다. 이것은 옵션 1과 2를 배제합니다.

옵션 3이 유일하게 수용 가능한 솔루션입니다. 예외는 언어의 일부일 필요는 없지만 현실의 일부입니다. 종료 메시지는 오류에 대해 가능한 구체적이고 유익해야합니다.


3

IEEE 754는 실제로 문제에 대한 솔루션을 잘 정의했습니다. http://en.wikipedia.org/wiki/IEEE_floating_point#Exception_handling 을 사용하지 않고 예외 처리exceptions

1/0  = Inf
-1/0 = -Inf
0/0  = NaN

이런 식으로 모든 작업이 수학적으로 이해됩니다.

\ lim_ {x \ to 0} 1 / x = Inf

내 의견으로는 IEEE 754에 따르면 컴퓨터에서 계산하는 것이 정확하고 다른 프로그래밍 언어의 동작과 일치하기 때문에 계산이 가장 적합합니다.

발생하는 유일한 문제는 Inf와 NaN이 결과를 오염시키고 사용자가 문제의 원인을 정확히 알 수 없다는 것입니다. Julia와 같은 언어를 잘 살펴보십시오.

julia> 1/0
Inf

julia> -1/0
-Inf

julia> 0/0
NaN

julia> a = [1,1,1] ./ [2,1,0]
3-element Array{Float64,1}:
   0.5
   1.0
 Inf

julia> sum(a)
Inf

julia> a = [1,1,0] ./ [2,1,0]
3-element Array{Float64,1}:
   0.5
   1.0
 NaN

julia> sum(a)
NaN

나누기 오류는 수학 연산을 통해 올바르게 전파되지만 결국 사용자는 오류가 발생한 작업을 알 필요는 없습니다.

edit:Jim Pivarski의 대답의 두 번째 부분을 보지 못했습니다. 기본적으로 위에서 말한 것입니다. 내 잘못이야.


2

프로그래머가 아닌 사람이 가장 널리 사용하는 언어 인 SQL은 가치가있는 모든 것을 위해 # 3을 수행합니다. 프로그래머가 아닌 사람이 SQL을 작성하는 것을 관찰하고 지원하는 내 경험에서,이 동작은 일반적으로 잘 이해되고 쉽게 보상됩니다 (사례 진술 등). 예를 들어 Postgres 9에서 "오류 : 0으로 나누기"라는 오류 메시지가 매우 직접적인 경향이 있습니다.


2

문제는 "초보 사용자를 대상으로합니다.-> 따라서 지원이 없습니다."

초보 사용자에게 예외 처리가 문제라고 생각하는 이유는 무엇입니까?

더 나쁜 것은 무엇입니까? "어려운"기능이 있거나 왜 어떤 일이 발생했는지 모릅니다. 무엇을 더 혼란스럽게 할 수 있습니까? 코어 덤프 또는 "치명적 오류 : 0으로 나누기"와 충돌이 발생합니까?

대신, 큰 메시지 오류를 목표로하는 것이 더 좋다고 생각합니다. 대신 "잘못된 계산, 나누기 0 / 0"(즉, 문제의 종류 가 아니라 항상 문제를 일으키는 DATA를 표시하십시오 ). PostgreSql이 메시지 오류를 처리하는 방법을 살펴보십시오. 이는 훌륭한 IMHO입니다.

그러나 다음과 같은 예외를 처리하는 다른 방법을 살펴볼 수 있습니다.

http://dlang.org/exception-safe.html

나는 또한 언어를 구축하는 꿈을 가지고 있으며,이 경우 일반적인 예외와 함께 어쩌면 / 선택을 혼합하는 것이 가장 좋을 것이라고 생각합니다.

def openFile(fileName): File | Exception
    if not(File.Exist(fileName)):
        raise FileNotExist(fileName)
    else:
        return File.Open()

#This cause a exception:

theFile = openFile('not exist')

# But this, not:

theFile | err = openFile('not exist')

1

내 관점에서 귀하의 언어는 오류를 감지하고 처리하는 일반적인 메커니즘을 제공해야합니다. 프로그래밍 오류는 컴파일 타임에 (또는 가능한 빨리) 감지되어야하며 일반적으로 프로그램 종료로 이어져야합니다. 예기치 않은 또는 잘못된 데이터 또는 예기치 않은 외부 조건으로 인해 발생하는 오류를 감지하여 적절한 조치를 취해야하지만 가능할 때마다 프로그램을 계속 진행할 수 있도록하십시오.

그럴듯한 조치에는 (a) 종료 (b) 사용자에게 조치 프롬프트 (c) 오류 기록 (d) 수정 된 값으로 대체 (e) 코드에서 테스트 할 표시기 설정 (f) 오류 처리 루틴 호출. 이 중 어느 것이 사용 가능하고 어떤 수단으로 선택해야합니까.

내 경험상, 잘못된 변환, 0으로 나누기, 오버플로 및 범위를 벗어난 값과 같은 일반적인 데이터 오류는 양성이며 기본적으로 다른 값을 대체하고 오류 플래그를 설정하여 처리해야합니다. 이 언어를 사용하는 (비 프로그래머)는 잘못된 데이터를보고 오류를 확인하고 처리해야 할 필요성을 신속하게 이해합니다.

[예를 들어, Excel 스프레드 시트를 고려하십시오. 숫자가 넘치거나 다른 이유로 Excel에서 스프레드 시트를 종료하지 않습니다. 셀은 이상한 값을 얻습니다. 이유를 찾아서 고칩니다.]

따라서 귀하의 질문에 대답하기 위해 반드시 종료해서는 안됩니다. NaN을 대체 할 수도 있지만 계산을 완료하지 말고 계산이 완료되고 이상한 높은 값을 생성해야합니다. 그리고 필요한 사용자가 오류가 발생했음을 확인할 수 있도록 오류 플래그를 설정하십시오.

공개 : 나는 그러한 언어 구현 (Powerflex)을 만들었고 1980 년대 에이 문제 (그리고 다른 많은 것들)를 정확하게 해결했습니다. 지난 20 년 동안 프로그래머가 아닌 사람들을위한 언어는 거의 또는 전혀 발전하지 않았으며, 시도에 대한 비판을 많이받을 것입니다. 그러나 저는 여러분이 성공하기를 바랍니다.


1

나는 분자가 0 인 경우 대체 값을 제공하는 삼항 연산자를 좋아했습니다.

내가 보지 못한 또 하나의 아이디어는 일반적인 "유효하지 않은"값을 생성하는 것입니다. 일반적인 "이 변수는 프로그램이 나쁜 일을했기 때문에 값을 가지지 않습니다"는 자체적으로 전체 스택 추적을 수행합니다. 그런 다음 어디에서나 해당 값을 사용하면 새로운 작업을 맨 처음 시도하여 결과가 다시 유효하지 않습니다 (예 : 유효하지 않은 값이 표현식에 표시되면 전체 표현식이 유효하지 않으며 함수 호출이 시도되지 않습니다. 예외는 부울 연산자이어야 함-true 또는 invalid는 true 및 false 및 invalid는 false-다른 예외도있을 수 있습니다. 해당 값이 더 이상 어디에서나 참조되지 않으면 문제가 발생한 전체 체인에 대한 자세한 설명을 기록하고 평소처럼 비즈니스를 계속하십시오. 추적을 프로젝트 책임자에게 보내거나 이메일로 보낼 수 있습니다.

Maybe 모나드와 같은 것이 기본적으로 있습니다. 그것은 실패 할 수있는 다른 것들과 함께 작동하며 사람들이 자신의 무효를 구성하도록 허용 할 수 있습니다. 그리고 오류가 너무 심하지 않는 한 프로그램이 계속 실행될 것입니다.


1

0으로 나누는 데는 두 가지 근본적인 이유가 있습니다.

  1. 정수와 같은 정확한 모델에서는 입력이 잘못되어 DBZ를 0으로 나눕니다. 이것은 우리 대부분이 생각하는 DBZ입니다.
  2. 부동 소수점과 같은 비 정밀 모델에서는 입력이 유효하더라도 반올림 오류로 인해 DBZ가 발생할 수 있습니다. 이것이 우리가 일반적으로 생각하지 않는 것입니다.

1. 사용자는 자신이 책임이 있고 상황을 해결하는 방법을 가장 잘 알고 있기 때문에 실수를했다는 사실을 사용자에게 다시 알려야합니다.

2의 경우 이것은 사용자 결함이 아니며 알고리즘, 하드웨어 구현 등을 가리킬 수 있지만 사용자의 결함이 아니므로 프로그램을 종료하거나 예외를 던지지 않아야합니다 (이 경우 허용되지 않는 경우). 따라서 합리적인 해결책은 합리적인 방식으로 작업을 계속하는 것입니다.

이 질문을하는 사람이 사례 1을 요청한 것을 볼 수 있습니다. 따라서 사용자에게 다시 연락해야합니다. 부동 소수점 표준 인 Inf, -Inf, Nan, IEEE를 사용하면이 상황에 맞지 않습니다. 근본적으로 잘못된 전략.


0

언어로 금지하십시오. 즉, 일반적으로 먼저 테스트하여 0이 아닐 때까지 숫자로 나누지 마십시오. 즉.

int div = random(0,100);
int b = 10000 / div; // Error E0000: div might be zero

이를 위해서는 정수가 아닌 새로운 숫자 유형 인 자연수가 필요합니다. 다루기가 어려울 수 있습니다.
Servy

@Servy : 아뇨. 왜 당신은? 가능한 값을 결정하려면 컴파일러에 논리가 필요하지만 어쨌든 (최적화 이유로) 원하는 것입니다.
MSalters

다른 유형, 0과 1이 아닌 값을 가지지 않으면 일반적인 경우 문제를 해결할 수 없습니다. 당신은 오탐 (false positive)을 가지고 있으며 사용자가 실제보다 더 자주 제로에 대해 확인하도록 강요하거나, 여전히 제로로 나눌 수있는 상황을 만듭니다.
Servy

@ Servy : 당신은 실수입니다 : 컴파일러는 그러한 유형을 필요로하지 않고 해당 상태를 추적 할 수 있습니다. 예를 들어 GCC는 이미 그렇게합니다. 예를 들어 C 유형 int은 0 값을 허용하지만 GCC는 여전히 코드에서 특정 정수가 0이 될 수없는 위치를 결정할 수 있습니다.
MSalters

2
그러나 특정한 경우에만; 모든 경우에 100 % 정확도로 그렇게 할 수는 없습니다. 당신은 오탐 또는 오탐을 가질 것입니다. 이것은 사실입니다. 예를 들어, 완료 되거나 완료 되지 않은 코드 스 니펫을 만들 수 있습니다 . 컴파일러가 완료되었는지조차 알 수 없다면 결과 int가 0이 아닌지 어떻게 알 수 있습니까? 그것은 명백한 간단한 경우를 잡을 수 있지만 모든 경우는 아닙니다 .
Servy

0

프로그래밍 언어를 작성할 때 사실을 활용하고 0 상태로 고안을위한 조치를 포함시켜야합니다. a <= n / c : 0 div-0-동작

방금 제안한 것은 PL에 'goto'를 추가하는 것입니다.

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