2014-06-24 15 views
1

나는 mysql 데이터베이스로 부동 소수점 숫자를 전달하기 위해 Perl을 사용하고 있습니다. 펄에서 곱셈을 수행합니다 :Perl/mysql 부동 소수점 정확도가

$var = 0.001 * 3; 

이 값을 DOUBLE 유형의 열에있는 mysql 데이터베이스에 저장합니다. 나중에 결과를 검색 할 수에 더 곱셈과 추가를 수행하고 데이터베이스에 저장된 결과는 0.0045해야 데이터베이스

$previous_result_from_db += 0.001*1 + 0.001*0.5. 

에 다시 저장, 대신 내가 얻을 : 0.0045000000000000005. 나는 부정확의 원천이 어디인지 이해하려고 노력하고 있습니다. Perl이나 데이터베이스입니까? 이러한 종류의 부동 소수점 상호 작용을 처리하여 부정확성을 피하는 올바른 방법은 무엇입니까?

감사합니다.

+5

표준 응답 : [모든 컴퓨터 과학자가 부동 소수점 연산에 대해 알아야 할 사항] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html). 그것은 펄이나 데이터베이스가 아닙니다. 부동 소수점 연산입니다. – Miller

+0

"부정확을 피하기 위해 이러한 종류의 부동 소수점 상호 작용을 처리하는 올바른 방법은 무엇입니까?" - 이전에 대한 부식적인 반응 : 고정 소수점을 사용하십시오. – BRFennPocock

+2

@Miller, 덜 밀도있는 설명이 있습니다. http://floating-point-gui.de/ –

답변

3

"10.0 배, 0.1 좀처럼 1.0 없다"- 브라이언 커니 핸, 프로그래밍 스타일

그것은 그들이 부정확 한 숫자 데이터 유형은 FLOAT과 DOUBLE의 알려진 제한 사항입니다의 요소. 이것은 IEEE 754 형식의 설계에 내장되어 있습니다. 이 형식을 사용하여 부동 소수점 숫자를 저장하는 모든 프로그래밍 언어에 영향을줍니다.

MySQL은이 부록에서이 내용을 문서화합니다 : B.5.5.8 Problems with Floating-Point Values.

PHP 문서는 Warning: Floating point precision입니다.

이 반올림 동작을 피하는 스케일 된 숫자 데이터 형식을 MySQL에 사용하려면 DECIMAL을 사용하십시오.

+1

감사합니다. Bill, DECIMAL은 금전적 가치를 지닌 것처럼 보입니다. 답은 Perl쪽에 대해서는 언급하지 않지만 위의 사용자 의견에는 Perl에서이 문제를 처리하는 링크가 포함되어 있으므로 문제를 해결하는 것으로 받아 들일 것입니다. 링크는 다음과 같습니다. http://floating-point-gui.de/languages/perl/ –