수학 계산 snippet

Prentice의 이미지

http://en.wikipedia.org/wiki/Heptadecagon

17각형 작도법에 대한 얘기를 보고, 확인을 해보고 싶어서 검산을 해봤습니다.

#include <stdio.h>
#include <math.h>
int main(void)
{
	long double calced;
	long double summed;
	long double root17;
	long double root_neg_34;
	long double root_pos_34;
	long double root_triple;

	root17 = sqrt(17);
	root_neg_34 = sqrt(34-2*root17);
	root_pos_34 = sqrt(34+2*root17);
	root_triple = sqrt(17+3*root17-root_neg_34-2*root_pos_34);

	calced = 16 * cos((2*M_PI)/17);

	summed = -1 + root17 + root_neg_34 + 2*root_triple;

	printf("Calced: %.99Lf\n", calced);
	printf("Summed: %.99Lf\n", summed);

	return 0;
}

결과:
AMD64 pure64
Calced: 14.919555670469692998381106008309870958328247070312500000000000000000000000000000000000000000000000000
Summed: 14.919555670469692998381106008309870958328247070312500000000000000000000000000000000000000000000000000

AMD64 chroot x86
Calced: 14.919555670469692899501867877631866576848551630973815917968750000000000000000000000000000000000000000
Summed: 14.919555670469692998381106008309870958328247070312500000000000000000000000000000000000000000000000000

AMD64 cygwin x86
Calced: 14.919555670469692901236591353608673671260480000000000000000000000000000000000000000000000000000000000
Summed: 14.919555670469692998381106008309870958328250000000000000000000000000000000000000000000000000000000000

#!/usr/bin/python

import math;
root17 = math.sqrt(17);
root_neg_34 = math.sqrt(34-2*root17);
root_pos_34 = math.sqrt(34+2*root17);
root_triple = math.sqrt(17+3*root17-root_neg_34-2*root_pos_34);

calced = 16 * math.cos((2*math.pi)/17);

summed = -1 + root17 + root_neg_34 + 2*root_triple;

print calced;
print summed;

C에서 고정밀도 연산을 하려면 어떻게 해야 할지 궁금합니다. 다음에 시간이 생기면 먼저 python에서 어떻게 하는지를 알아볼 생각입니다.

Forums: 
kkb110의 이미지

C에서 고정밀도 연산을 하려면...
long double 같은 형을 쓰지 말고 수치 class를 직접 정의해서 더큰 bit로 곱셈 나눗셈 덧셈 뺄셈 그리고 필요한 다른 연산들을 다 구현해줘야겠지요 -_-;;

제가알고있는 곱셈 라이브러리중 하나인데 혹시 참고가 되실지도..
http://cr.yp.to/zmult.html

BuzzLy의 이미지

프로그래밍에 대해서는 잘 모르지만 코멘트를 하나 하고 싶은게 있습니다.

sine함수와 제곱근 계산이 모두 근사(approximation)이기 때문에
동일한 compiler 안에서 sine 함수를 직접계산한 것과 제곱근을 이용해
계산한 결과 사이의 차이점은 먼저 이 함수들이 기반한 알고리즘의 오차를
먼저 알아보는게 좋지 않을까요? 파이(pi) 역시 근사값이지요.

구현 방법상의 오차가 long double type에서
표현할 수 있는 값보다 작으면 kkb110님의 말씀처럼 새로운 변수형을 정의해서
계산하는게 필요하겠지만 반대의 경우라면 더 오차가 더 작은 계산 방법(함수)을
이용하는 게 중요할 것 같네요.

lifthrasiir의 이미지

파이썬 2.4에 추가된 Decimal 모듈을 사용한 코드입니다. 좀 느리긴 합니다. -_-;;;

파이썬 레퍼런스에 있는 recipe를 좀 참고했습니다. (sqrt 함수는 제가 만들었습니다만)

from decimal import Decimal, getcontext

def pi():
	getcontext().prec += 2
	ss, t, s, n, na, d, da = 0, Decimal(3), 3, 1, 0, 0, 24
	while s != ss:
		n, na = n + na, na + 8
		d, da = d + da, da + 32
		t = (t * n) / d
		s, ss = s + t, s
	getcontext().prec -= 2
	return +s

def cos(x):
	getcontext().prec += 2
	i, ss, s, fact, n, sign = 0, 0, 1, 1, 1, 1
	while s != ss:
		i += 2; fact *= i * (i-1)
		n *= x * x; sign *= -1
		s, ss = s + n / fact * sign, s
	getcontext().prec -= 2
	return +s

def sqrt(x):
	getcontext().prec += 2
	ss, s = 0, x
	while s != ss:
		s, ss = (s + x/s) / 2, s
	getcontext().prec -= 2
	return +s

############################################################

getcontext().prec = 200

pi = pi()
value = 16 * cos(pi * 2 / 17)

sqrt17 = sqrt(Decimal(17))
sqrt34_r17 = sqrt(34 - 2 * sqrt17)
sqrt34r17 = sqrt(34 + 2 * sqrt17)
sqrtxxx = sqrt(17 + 3 * sqrt17 - sqrt34_r17 - 2 * sqrt34r17)
total = -1 + sqrt17 + sqrt34_r17 + 2 * sqrtxxx

결과:

>>> print value
14.91955567046969287316985426914501418020140444712187085197360018976857674511431
19700491954056068776156031890843512810176552356095332667245753245167489901211656
44035570018508582255823621749390514197650
>>> print total
14.91955567046969287316985426914501418020140444712187085197360018976857674511431
19700491954056068776156031890843512810176552356095332667245753245167489901211656
44035570018508582255823621749390514197650
>>> value == total
True

- 토끼군

doldori의 이미지

17각형 작도법... @.@ 놀랍군요. 그에 얽힌 얘기를 읽어보니 가우스가 19살때
일반적으로 (2^(2^n)+1)각형의 작도가 가능하다는 것을 증명했다고 하는데
그거 참... 말이 안나옵니다.

토끼군님이 작성하신 sqrt()는 Newton-Rhapson법을 쓰신 것 같군요. 제가 파이썬은
모르지만 대충 눈치를 보아하니 임의의 정밀도 계산이 가능한가 봅니다. 그런데
계산 시작하기 전에 정밀도를 2 올리는 이유는 뭔가요?

lifthrasiir의 이미지

doldori wrote:
17각형 작도법... @.@ 놀랍군요. 그에 얽힌 얘기를 읽어보니 가우스가 19살때
일반적으로 (2^(2^n)+1)각형의 작도가 가능하다는 것을 증명했다고 하는데
그거 참... 말이 안나옵니다.

토끼군님이 작성하신 sqrt()는 Newton-Rhapson법을 쓰신 것 같군요. 제가 파이썬은
모르지만 대충 눈치를 보아하니 임의의 정밀도 계산이 가능한가 봅니다. 그런데
계산 시작하기 전에 정밀도를 2 올리는 이유는 뭔가요?

Newton('s) method를 Newton-Rhapson method라고도 하는 군요. 정밀도를 올리는 이유는, 수렴 기준이 정밀도 안에서 수치가 변하지 않는 경우인데 이러다 보면 맨 마지막 자리가 잘못 나올 가능성이 있기 때문입니다. (미리 두 개 더 계산하고 절삭하면 별 문제 없겠죠 -,.-)

그나저나 pi() 함수가 좀 느린 것 같군요. 무슨 전개식인지 모르겠는데(recipe에서 가져 와서 -_-;) pi = 16arctan(1/5) - 4arctan(1/239)를 사용하니 수렴 속도가 꽤 개선되었습니다. pi 함수를 다음으로 고쳐 보세요. (다른 전개식도 많이 테스트해 봤는데 기본 연산만 쓰면서 속도 빠른 게 이것 정도더라는)

def pi():
	getcontext().prec += 2
	xx = Decimal(1)/5; yy = Decimal(1)/239
	x = xx * xx; y = yy * yy; i = 1; s = 0; g = 1; ss = 1
	while s != ss:
		ss = s; s += (16 * xx - 4 * yy) * g / i
		g *= -1; i += 2; xx *= x; yy *= y
	getcontext().prec -= 2
	return +s

- 토끼군

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.