Articles

를 사용하는 위험 부유물 또는 실제 데이터 유형

가 농담에 관한 부동 소수점 연산:

“나는 절에서 세 가지,각각의 조각이 0.33 의 케이크입니다. 나는 나에게 케이크의 0.99 를 제공 함께 다시 세 조각을 스틱 경우. 케이크의 나머지 부분은 어디로 갔습니까?”
—”간단합니다. 는 조금에 붙어 칼”

부동 소수점 연산은 모두에 대한 견뎌하고 관리하는 근사치를 방지하기 위해서 오버플로우에서 오류를 계산합니다. 현실 세계에서,우리는 일반적으로 관리에 대한 정밀 번호와 것입니다,대신 희생은 공간과 자원을 피하기 위해서 오버플로우가 발생합니다.

과학은 오류 마진 내에서 행복하게 작동하는 반면,정밀도는 비즈니스 회계에서 중요합니다. 었을 때 새끼 프로그래머,나는 이렇게 기록하셨습니다 무슨 생각을 완벽하게 적합하를 계산하는 방법에 대한 이익의 주식 거래. 백만 파운드에서,그것은 페니 또는 2 밖으로 최대량이었다. 나는 잘 기뻐했다. 그것은 금융 패키지를 개발하기 위해 당시에 사용했던 PL/1 컴파일러에 내재 된 계산을 사용했습니다. 나는 그들에게 정밀하게 만들어진 응용 프로그램을 보여 주었고,그들은 소름 끼쳤다. 백만 파운드에 페니 밖으로 무모한 하드 보일드 도시 상인에 보였다. 그들은 그것을 가지지 않았을 것입니다. 정확하게 정확한 어셈블러 코드에 bcd(binary-coded-decimal)패키지를 작성해야했습니다.

SQL 프롬프트가 있는 코드를 분석 규칙(BP023)는 경우의 사용FLOATREAL데이터 형식으로 인해 중요한 부정확한 그들이 할 수 있게 소개하는 종류의 계산에는 많은 조직이 일상적으로 수행하에서 자신의 SQL 서버 데이터입니다.

대략적인 번호 데이터의 유형

부동 소수점 연산을 고안되었을 때 그것이 우선 순위를 저장하는 메모리를 제공하면서 다양한 방법으로 일을 계산하는 참여 더 많은 포인트를 수집합니다. 하지만 그것은 여전히 유용한 다양한 유형의 과학적 계산,특히 그들을 준수하는 이중 정밀도 IEEE754 표준에 대한 부동 소수점 연산,그것은,필요성,는 타협이다. 단서는이 유형의 데이터와 산술의 이름에 있습니다:’대략적인’. 부동 소수점 수 없을 정확하게 나타내는 모두 실제 숫자:또한,부동 소수점 연산할 수 없을 정확하게 나타내는 모든 산술 작업입니다. 그러나,범위의 크기의 번호를 저장할 수 있습니다 그들은 큰 보상이 가능한 다른 숫자 형식도 그렇지 않은 경우 항상 정확하게 개최됩니다.

발생하는 문제에의 사용에서 부동 소수점 연산이 때문에 라운드오프 동안 복잡한 계산,그리고 가장 많이 볼 수있는 경우에 데이터가’아픈컨’,그래서 작은 변화에서의 입력이 확대되 출력됩니다. 부정확성은 숫자의 표현의 정밀도가 증가함에 따라 훨씬 덜 명백하지만 그럼에도 불구하고 여전히 존재합니다. 거기에는 또한 어떤 비전의 사용에 제한이는 숫자가 유효한 그러나 수 없이 표현에서 부동 소수점과 같은 황갈색(π/2)지만,이러한 가능성이 있는 자만 수학자.

SQL Server 부동 소수점 데이터 유형

SQL 표준은 세 개의 부동 소수점 대략적인 데이터 유형REALDOUBLEPRECISIONFLOAT(n). SQL Server 준수하는 이외에는 없DOUBLEPRECISIONFLOAT(53)FLOAT(24)FLOAT(53)데이터 유형에 해당하 Binary32(Single)및 Binary64(double)에 IEEE754 표준,그리고 저장하에서 4 과 8 바이트이며,7 16 자리이 개최합니다. 계산이 IEEE754 를 사용하는.NET framework 를 사용하는 응용 프로그램과 동일한 결과를 생성하는 것이 중요 할 때 유용합니다. 배정밀도 유형은 또한 숫자가DECIMALWHERE절과 같은 모든 평등 테스트에서 안정적으로 사용될 수 없습니다.

실제 데이터 유형(단 정밀도)을 사용한 계산

REALFLOAT(24)데이터 유형 또는 더 작은 것은 같은 방식으로 반응합니다. 첫 번째 것은 때를 기억하는 것을 실험하는 부동 소수점의 숫자에서 SQL 서버는 SSMS 렌더링하는 부동 소수점 수는 방식으로 위장 작은 차이가 있습니다. 예를 들어,

1
변환 선택(부,0.100000001490116119384765625)

…제 0.1

을 더 정확하게 볼 수 어떤 가치에 저장되는 부동 소수점 수,당신은 당신을 사용하여 STR()함수를 지정하는 정밀도는 당신이 실제로 원한다.

1
2
3
4
5
/*나는 조금 불공정기, 기 때문에 소수의 0.1 표현할 수 없는
에서 부동 소수점;정확한 표현을 바이너리가”1100″sequence
계속 끊임없이:*/
선언@FirstApproximate 부=0.1
선택 Str(@FirstApproximate,20,16)–0 보다 커야 합니다.나는 이것이 내가 할 수있는 일이 아니라는 것을 알고 있지만,나는 이것이 내가 할 수있는 일이 아니라는 것을 알고 싶다. 우리는 우리 후,모든 처리하는 데이터는 수백만의 행은 그래서 작은 오류를 쌓을 것입니다하지 않는 한,다음과 같’은행림’,그들은 평균니다. 그 오류는 이미 소개에서 언급 한’백만 파운드의 페니'(1/240000000)에 가깝습니다!

0.1 을 피하고 부동 소수점의 괴물에 내려 놓자. 1 을 3 으로 나누면 어떨까요? 분명히 이것은 문제가 될 수 없었습니까?

1
2
3
4
5
알리는@보수는 진짜=1
알리는@약수는 진짜=3
선택 Str(@돈세탁/@약수,20,16)로 몫
–생산 0.3333333432674408
–해야 0.3333333333333333

죄송합니다. 그것은 그것을 잘못 얻었다. 좋아,그것은 작은 오류이지만 은행가에 대한 나의 이야기를 기억하십시오. 대답이 맞거나 틀리면 회색 정장을 입은 남성에게는 회색 음영이 없습니다. 비즈니스 스쿨에서는 진드기와 십자가 만 있습니다. ‘충분히 가깝다’는 의미는 없습니다.

간단한 테스트는 1 에서 20 까지의 숫자로 하나를 나누는 것입니다. 무엇이 잘못 될 수 있습니까?

우리는 저장할 수 있는 결과를 소수점 및 숫자 계산,두 문자열로 변환 우리는 다음을 비교할 문자열은(경고하는STR()를 넣을 수 있습에서 선도적인 공간을 만드는 위한 합병증).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

DECLARE @divisor REAL, @dividend REAL = 1
DECLARE @FloatingPointCalculations TABLE (Divisor INT, QuotientFloatingPoint VARCHAR(20), QuotientNumeric VARCHAR(20));
DECLARE @ii INT = 1;
DECLARE @iiMax INT = 20;
WHILE (@ii <= @iiMax)
BEGIN
SELECT @divisor = @ii;
INSERT INTO @FloatingPointCalculations (Divisor, QuotientFloatingPoint,
QuotientNumeric)
SELECT @ii AS divisor, Str(@Dividend / @divisor, 20, 16) AS QuotientFloatingPoint,
Convert(VARCHAR(20), 1.0000000 / @ii) AS QuotientNumeric;
SELECT @ii += 1;
END;
SELECT The.Divisor, The.QuotientFloatingPoint, The.QuotientNumeric
FROM @FloatingPointCalculations AS The;

Now, what if we list the rows where the numbers don’t match?

1
2
3

SELECT The.Divisor, The.QuotientFloatingPoint, The.QuotientNumeric
FROM @FloatingPointCalculations The
WHERE Left(LTrim(The.QuotientFloatingPoint),16)<> Left(LTrim(The.QuotientNumeric),16)

Ugh! 제수가 1,2,4,8 또는 16 인 경우에만 올바른 결과가있었습니다.

어떻게 든 플로트가 정확하고 숫자 버전이 아니길 바라는 경우에 대비하여 여기 Excel 에서 계산 된 숫자 지수가 있습니다:

는 계산용 플로트(25)또는(이중 정밀도)

사용하는 경우에 두 개의 정밀 부동 소수점,FLOAT(25)STR()기능을 할 수 있는 최대의 여섯 곳의 오른쪽에 소수점이다. 16 개가 넘으면 결과가 잘립니다. 이중 정밀도 데이터 유형에는 16 자리 숫자가 있지만 단 정밀도 데이터 유형에는 7 자리 숫자가 있습니다. 또한 단 정밀도 데이터 유형이 처음 7 자리 숫자를 올바르게 얻는 것을 보았을 것입니다. 마찬가지로 배정밀도는 처음 16 자리 숫자를 바로 얻습니다. 우리는 단지 근사치를보기 위해 숫자를 넓힐 수 있습니다.

1
2
선언@FirstApproximate 떠(53)=10000000000000000.1
선택 Str(@FirstApproximate,40,16) 로 BigNumberWithaDecimal

는 소수부가 사라졌다,그것을 하지 않았다? 그것은 아마도 작은 차이 일 뿐이지 만 일부 계산에서는 문제를 일으킬 수 있습니다.

결론

부동 소수점 연산이 빠르고 경제적인 저장에 제공하지만 대략적인 결과입니다. 그것은에 적합한 잘 과학 응용 프로그램지를 위한 재정 계산을 요구하는 다수 중 하나의 권리’또는’잘못된’. 그것은 또한 여분의 단점은 데이터베이스에서할 수 없기 때문에 안정적이고 지속적으로 테스트하는 두 대략적인 숫자에 대한 평등.

SQL 데이터 유형이나 산술에서 부동 소수점 숫자를 사용해서는 안된다고 말하는 것은 정확하지 않습니다. 대략적인 유형은 목적을 위해 SQL 표준에 있습니다. 나는 요즘 항상 적절한 요구 사항이있는 sql Server 의 배정밀도 부동 소수점 데이터 유형을 고수 할 것입니다. 그들은 이러한 목적으로 모델링 날씨,시스템 또는 음모를 꾸미 궤적지에 대한 유형의 계산한 평균 조직을 이용하기 위하여 확률이 높은 데이터베이스입니다.

경우에 당신은 잘못된 사용하여 이 유형의해야 합 스위치 적합한DECIMALNUMERIC유형을 대신 합니다. 당신이 알고있는 경우에 당신은 필요한 부동 소수점 연산과는 이유를 설명 할 수 있습니다,당신은 아마도 충분히 알고 있의 함정을 피하기 위해 부동 소수점 등에서 발생한 유명한 애국의 미사일 발사 실패하는 직접 주도하 28 죽음입니다.