2009-06-12 3 views
2

Я очень смущен следующими результатами:Автоматическое округление SQL Server?

PRINT 3.1415926535897931 /180 

консоли результат = 0,01745329251994329500

DECLARE @whatTheHell float(53) 
SET @whatTheHell = 3.1415926535897931/180 
PRINT @whatTheHell 

консоли результат = 0,0174533

Я не понимаю, потому что имея в виду это:

http://msdn.microsoft.com/en-us/library/ms131092.aspx

Sql Server Float должен быть эквивалентен C# double. Но когда я вычисляю это в C#:

double hellYeah = 3.1415926535897931 /180; 

я 0.017453292519943295 ...

+0

Приятные имена переменных. +1 –

ответ

7

Я думаю, что вы получаете смущает тот факт, что PRINT неявно преобразует числовой к символу с настройкой по умолчанию для функции STR - длиной 10 см (MSDN). Попробуйте PRINT STR(@wth, 20, 16), и вы можете быть счастливее.

+0

Скорее «приоритет типа данных» и оценка констант и т. д. – gbn

3

Я думаю, тип "Float" просто имеет ограничение на точность. Книги в Интернете говорят, что с FLOAT (53) вы должны получить до 15 цифр точности - не уверены, существует ли ограничение по умолчанию, являются ли эти цифры до или после десятичного разделителя.

Попробуйте использовать десятичную вместо:

DECLARE @whatTheHell2 decimal(18,16) 
SET @whatTheHell2 = 3.1415926535897931/180 
PRINT @whatTheHell2 

дает мне результат:

0.0174532925199433 

Марк

+0

Но когда вы читаете эту документацию msdn: http://msdn.microsoft.com/en-us/library/ms131092.aspx Вы видите, что точность sql Float эквивалентна двойной точности C#. Или когда я вычислил это с помощью C#: double pipo = 3.1415926535897931/180; Я получаю: 0.017453292519943295 ??? – Roubachof

+0

Я знаю - это меня тоже озадачило - см. Другие ответы для дополнительной информации. Кажется, SQL-сервер принимает какую-то стандартную точность для FLOAT - вместо этого использует NUMERIC или DECIMAL с явными настройками точности –

+1

Alex Martelli и David B. правы! – Roubachof

1

С SQL Server 2005 Books Online Data Type Conversion тему:

В Операторы Transact-SQL, константа nt с десятичной точкой автоматически преобразуется в числовое значение данных, с использованием минимальной точности и шкалы . Например, константа 12,345 преобразуется в числовое значение с точностью до 5 и шкале из 3.

Так следующее является более представительным, что SQL Server делает неявно:

DECLARE @whatTheHell NUMERIC(21, 20) 
SET @whatTheHell = 3.1415926535897931/180 
PRINT @whatTheHell 
+0

, ссылаясь на этот http://msdn.microsoft.com/en-us/library/ms173773.aspx, float (53) должен иметь точность 15 цифр. Так же, как C# double: результат C# имеет 15 цифр. Поэтому я действительно не понимаю, почему я заканчиваю с точностью 6 цифр с поплавком (53) ... – Roubachof

+0

+1: Да, с этим числовым, он работает просто отлично –

4

Разделить не округление. ПЕЧАТЬ округляется.

DECLARE 
    @var1 float, 
    @var2 float, 
    @var3 float 

SET @var1 = 3.1415926535897931 
SET @var2 = 180 

SET @var3 = @var1/@var2 
SELECT @var1/@var2 as Computed, @var3 as FromVariable 

PRINT @var1/@var2 
PRINT @var3 
0

Когда вы говорите, что SQL-float сопоставляется с C# double, я думаю, вы считаете, что размер байта SQL-байта совпадает с размером байта C#.

Я бы сказал, что C# double является единственным типом данных с плавающей точкой, достаточно большим, на C#, для хранения SQL-поплавка.

Пример:

C# Double = 8 байт Sql поплавка = 4 байта

Простое исправление для вашей проблемы является использование десятичной или числовой в вашем SQL

+0

в моем случае это float (n) с (n = 53)> 24, поэтому он имеет точность в 8 байтов, как и aC# double. (см. http://msdn.microsoft.com/en-us/library/ms173773.aspx) – Roubachof

1

PRINT 3.1415926535897931 /180 в настоящее время оценивается как десятичные ,

Поплавок разрешает только 15 значащих цифр. У вас есть 17, поэтому он не может плавать. 180 становится десятичным через неявное преобразование из-за datatype precedence, а выходная шкала и точность is based on these rules

Выход 0,01745329251994329500 имеет также 17 сиг-фигов. Он должен быть десятичным.

SET @whatTheHell = 3.1415926535897931/180. Преобразование float происходит как часть оператора присваивания. До этого он также десятичный с правой стороны. Поплавок приблизительный, и округление.

В C# это все дублей, потому что у вас нет фиксированной точки

Похожие вопросы (если не сказать компилятор?):

Choosing the appropriate precision for decimal(x,y)

In SQL how can I convert a money datatype to a decimal?

SQL Server, where clauses comparisons with different types & default casting behaviour

Смежные вопросы