4

[x.00, x.99]의 십진수의 경우 x이 임의의 정수인 경우 (여기에서 컨텍스트의 일부로 추측 할 수 있음) 일반적으로 부동 소수점 데이터 유형은 상당히 부정확하고 때로는 위험한 것으로 간주됩니다. 대신 10 진수 데이터 유형이있는 언어에서는 소수가 선호되는 경우가 많습니다. SQL은 그러한 언어 중 하나입니다.SQL Server에서 부동 소수점 필드에서 .00과 .99 사이의 모든 소수 자릿수가 정확하게 표시되는 이유는 무엇입니까?

1.1 
2.2 
2.2 

되어서는 안된다는 오른쪽 :

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [dbo].[Table_1](
    [SomeFloat] [float] NOT NULL 
) ON [PRIMARY] 

GO 

INSERT INTO Table_1 VALUES (1.1) 
SELECT SomeFloat FROM Table_1 
SELECT SomeFloat + SomeFloat FROM Table_1 
UPDATE Table_1 SET SomeFloat = SomeFloat + SomeFloat 
SELECT SomeFloat FROM Table_1 

이 다음 반환

말했다되는 것을 여기에 SQL Server의 흥미로운 작은 실험입니까? x.1은 SQL이 아닌 부동 소수점 숫자로 저장 될 수 있다고 가정합니다. 많은 언어가 아닙니다. 대신, base-2로 작업 할 때 제한으로 인해 반올림해서는 안됩니까?

하지만 그렇지 않습니다. 형태가 다른 것도 없습니다 [x.00, x.99]. 그들은 모두 float 데이터 유형을 사용하고 있음에도 불구하고 정확하게 표현되었습니다.

처음에는 문제가 있음을 정당화 할 수 없다면 float에서 decimal까지 일부 내용을 변경할 수 없습니다. SQL Server 2012를 사용하고 있습니다. 자동으로이 문제를 해결하고이 숫자를 내부적으로 varchar으로 변환합니까? 얼마나 신뢰할 수 있니? 감사.

+2

해당 숫자 *는 반올림됩니다. 소수점 이하 15 자리까지 정확하기 때문에 말할 수 없습니다. – Gabe

+0

MSDN에서 "부동 소수점 값은 정수형으로 변환 될 때 잘립니다."부동 소수점 값이 부정확하다는 사실은 1.1 + 1.1보다 약간 복잡합니다. – Luaan

+0

플로트 형식으로 저장하고 싶지 않은 이유 때문에이 게시물을 살펴보십시오. http://decipherinfosys.wordpress.com/2009/04/29/floating-point-arithmetic/ –

답변

3

floatvarchar으로 변환하면 SQL Server에 maximum of 6 digits by default이 표시됩니다. float은 약 15 자리를 저장할 수 있습니다. 그것은 도트 뒤에 최대 여섯 자리 숫자 인 1.1을 저장할 정도로 충분합니다.

정밀도가 낮은 float 인 real 유형의 부정확성을 표시하기 쉽습니다. 당신이 the 2 style of convert to show 16 digits를 사용하는 경우 :

select convert(varchar(max), cast(1.1 as real), 2); 
--> 
1.100000023841858e+000 

float을 표시 할만큼의 제로가 더 정확한 :

1.100000000000000e+000 

지금 print가 0 변환 스타일 사용하는 것 같다

select convert(varchar(max), cast(1.3 as real), 0) 
,  convert(varchar(max), cast(1.3 as real), 1) 
,  convert(varchar(max), cast(1.3 as real), 2); 
--> 
1.3 1.3000000e+000 1.299999952316284e+000 

을 아마도 이것은 뭔가 "6 자리로 반올림하여 후미 0을 버리는" 나는 잘 모르겠다. 실험을해야 할 것이다.

SSMS를 16 자리 이상으로 표시하는 방법을 찾지 못했습니다. 그러나 충분히 정확한 클라이언트는 float이 정확도의 손실없이 1.1을 저장할 수 없음을 보여줄 수 있습니다.