SQL Server Автоматическое округление? - PullRequest
2 голосов
/ 12 июня 2009

Меня очень смущают следующие результаты:

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 ...

Ответы [ 6 ]

7 голосов
/ 12 июня 2009

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

4 голосов
/ 12 июня 2009

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

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
3 голосов
/ 12 июня 2009

Полагаю, у типа "FLOAT" есть предел точности. Books Online говорит, что с FLOAT (53) вы должны получить до 15 цифр точности - не уверен, есть ли внутреннее ограничение, до или после десятичного разделителя.

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

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

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

0.0174532925199433

Марк

1 голос
/ 12 июня 2009

PRINT 3.1415926535897931 /180 оценивается как десятичное число.

Float разрешает только до 15 значащих цифр. У вас есть 17, поэтому он не может быть плавающим. Значение 180 становится десятичным в результате неявного преобразования из-за приоритета типа данных , а выходной масштаб и точность основаны на этих правилах

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

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

В c # это все удваивается, потому что у вас нет фиксированной точки (если вы не скажете компилятору?)

Похожие вопросы:

Выбор подходящей точности для десятичной дроби (x, y)

В SQL как я могу преобразовать денежный тип данных в десятичную?

SQL Server, где сравнения предложений с различными типами и поведение приведения по умолчанию

1 голос
/ 12 июня 2009

Из электронной документации по SQL Server 2005 Преобразование типов данных тема:

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

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

DECLARE @whatTheHell NUMERIC(21, 20)
SET @whatTheHell = 3.1415926535897931 / 180
PRINT @whatTheHell
0 голосов
/ 12 июня 2009

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

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

Пример:

C # Double = 8 байт Sql Float = 4 байта

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

...