네가 수학에 불합격했을 때

그것은 자정이 지난 후여서 나는 잠을 잘 수가 없었다.나는 핸드폰에서 크롬을 켰고 저녁 일찍 켰다an editorial about COBOL. 이것은 나로 하여금 우리 컴퓨터가 실제로 어떻게 수학을 하는지 생각하게 했다.저자는 an article 부동점 수학에 관한 모든 문제와 그로 인해 발생한 몇 가지 문제를 링크했다.얼마나 많은 문제가 이 점을 의식하지 못했기 때문인지 놀라게 될 것이다0.1 can't be exactly represented in binary.따라서 본고의 예시를 살펴보기로 했습니다. 테스트 값은 x=77617, y=33096입니다.

포맷해 주셔서 감사합니다!

스피드 라텍스 시도해 보다


나는 그들의 발견을 복제할 수 있는지 보고 싶다.
계산 정밀도
결과
하나밖에 없었어
1.172603...
이중적
1.1726039400531...
확장
1.172603940053178...
실제 값
-0.827396059946
그래서 저는 Clojure에서 이 기능을 실현했습니다.
(defn trial-double [x y] 
    (+ 
        (* 333.75 (Math/pow y 6))
        (* x x (- 
                (* 11 x x y y)
                (Math/pow y 6)
                (* 121 (Math/pow y 4))
                2.0))
        (* 5.5 (Math/pow y 8))
        (/ x 2 y)))
호출(trial-double 77617 33096) 결과 -1.1805916207174113E21.이상하게도 이것은 그들이 문장에서 얻은 잘못된 답안이 아니다.내 것은 21개 수량급의 차이와 잘못된 표지다!나도 엑셀에서 테스트를 했는데...
=333.75 * y^6 + x^2 * (11*x^2*y^2 - y^6 - 121 * y^4 - 2) + 5.5 * y^8 + x/2/y)
... 제가 Clojure랑 같은 번호를 잘못 걸었어요!
그러나 글에서 언급한 바와 같이 이것은 결코 정확한 답안이 아니다.그래서 나는 정확한 답안을 계산하기 시작했다.마지막으로 Clojure의 Ratio 유형과 Java의 BigInteger 유형의 조합을 시도했습니다(Clojure의 BigInt에 문제가 있기 때문).
(defn trial-rational [^java.math.BigInteger x ^java.math.BigInteger y] 
    (+ 
        (* 1335/4 (.pow y 6))
        (* x x (- 
                (* 11 x x y y)
                (.pow y 6)
                (* 121 (.pow y 4))
                2))
        (* 11/2 (.pow y 8))
        (/ x 2 y)))
테스트값(trial-rational (biginteger 77617) (biginteger 33096)으로 이를 평가해 점수-54767/66192를 얻었다.강제 double, 평가 -0.8273960599468214.나는 정확한 답을 얻었다!

이것은 무슨 뜻입니까?


비록 이 예는 부동점 연산이 극적인 방식으로 중단될 수 있다는 것을 분명히 보여 주지만, 우리는 그것을 단지 학술적 예시로 삼지 말아야 한다.반대로 네가 과거에 쓴 것을 생각해 보자.당신은 몇 번이나 어떤 값을 0.1 또는 0.01 증가하려고 시도했지만 결과적으로 오류가 발생했습니까?만약 내가 0.1(10Hz 데이터의 시뮬레이션에서 기대했던 것처럼)을 10번 더하면, 정밀도에 따라 나는 1.000000149011612 또는 0.999999999를 얻는다. 1.0이 아니라.90년대 걸프전에서 부동점수 오차의 누적으로 애국자 미사일이 목표를 명중시키지 못해 병사들이 사망했다.네가 군대에 대한 입장이 어떻든지 간에, 나는 우리가 사람이 죽어서는 안 된다고 생각한다. 왜냐하면 사람과 기계가 대표하는 숫자가 다르기 때문이다.

코볼에서 어떻게 왔어요?


이 모든 것을 생각하게 하는 사설은 왜 많은 금융 부문, 특히 미국 국세청이 여전히 COBOL을 사용하고 있는지 하는 것이다.사실은 부동점 계산이 정점 계산보다 이해하기 쉽다는 것을 증명한다. (당시 집행된 원가가 더 높았음에도 불구하고) 그래서 그들은 점차 승리를 거두었다.그러나 더 정확한 숫자 표시가 필요할 때 움직이지 않으면 일을 더 잘 할 수 있다는 사실이 증명된다.나는 이 사상연습센터의 공식이 더 정확할지 모르겠다. 설령 정답의 범위 내에 있다 하더라도 나는 그것이 항상 부동점 계산보다 우수하다고 말할 수 없다.

우리 어떡하지?


대부분의 응용 프로그램에 있어서 부동점은 일반적으로 충분히 정확하며, 부정확한 부동점이 표시하지 않는 숫자에 대해 덧셈/곱셈을 할 때만 정밀도가 떨어진다는 사실이 증명된다.하지만 당신이 반드시 정확해야 한다면 몇 가지 선택이 있습니다.

정수로 저장


만약 항상 소수점 자릿수가 일치하는 문제를 처리한다면, 값을 이미 알고 있는 비례 인자를 가진 정수로 저장하는 것을 고려할 수 있다.예를 들어, 통화 값은 "밀리 단위"로 저장됩니다.따라서 (USD) $123.45 스토리지는 1234.5억 달러입니다.왜 100이 아니야?몇몇 화폐 (요르단 디나르를 예로 들면) 가 소수점 뒤의 3위까지 정확하기 때문이다.이런 상황에서 사물을 축소 정수로 저장하고 필요에 따라 부동점으로 전환하면 계산 정밀도가 높아진다.

예산이 필요해요. 유리수를 사용하다


만약 당신이 점수를 자주 처리하는 것을 발견한다면, 유리수 라이브러리를 고려할 가치가 있을 것이다.어떤 언어들은 그것들을 내장하고 있다. Haskell과 Clojure가 바로 머릿속에 떠오를 것이다. 나는 또 다른 언어가 존재한다고 확신한다.백그라운드에서 유리수를 사용하고 필요할 때 부동점만 강제하면 잠입 계산의 오류량을 줄일 수 있습니다.

기호 계산


만약 당신이 자신이 많은 수치 방법을 처리하고 있다는 것을 발견한다면?상미분 방정식 해산기를 처리한 사람은 고정 보장 해산기의 부동점 오류를 걱정해야 한다. (수치 공식의 Runge Kutta 4, 누구 있습니까?)비록 사용자 적응 보장 구해기 (연속 함수가 있다고 가정) 로 이동할 수 있지만, 우리는 기호 계산을 실행할 수 있는 계산 능력이 있습니다.이렇게 생각할 수 있습니다 . 그러나 프로그램에 내장되어 있습니다.도수의 멱율을 기억하십니까?기호 계산 엔진도 마찬가지다.제럴드 수스만의 많은 고전 역학 개념과 고전 역학의 구조와 해석을 Scheme에서 Clojure로 이식한다.만약 네가 그렇게 멀리 갈 필요가 없다면, Wolfram Alpha 아마 매우 좋을 것이다.

자동 미분 결론


부동점 계산은 통상적으로 충분히 정확하다.더 높은 정확성이 필요하다면, 고맙게도 탐색할 수 있는 몇 가지 옵션이 있습니다.고객이 필요로 하는 정밀도 수준 (또는 더 중요한 것은 고객이 필요로 하는 것) 을 확인하고 이러한 요구에 가장 적합한 계산 유형을 선택하는 데 시간을 들이는 것을 기억하십시오.행운을 빌어요, 인코딩이 즐거워요!

좋은 웹페이지 즐겨찾기