Непонимание о SQL серверных плавающих и возвращении SQLCMD - PullRequest
0 голосов
/ 06 апреля 2020

В соответствии с документацией , двойной в SQL Сервер представляет собой число с плавающей запятой n = 53 (8 байт, точность 15 цифр).

Однако, когда я работаю SQLCMD чтобы получить строку из моей БД, результат не возвращает 15-значную точность double / float, а 17-разрядную.

Например: 0.58974358999999998

Десятичная дробь длиной 17 цифр, почему не 15, как указано в документации?

Редактировать: это мой SQL запрос:

SELECT TOP(1) * 
FROM TABLE 
WHERE object_key = '28499'

1 Ответ

2 голосов
/ 06 апреля 2020

Число, которое вы видите: округлено .

Под капотом SQL Сервер не хранит числа с плавающей запятой в виде десятичных цифр. Поскольку ваш номер находится между 0.5 и 1, он будет сохранен как:

2^(-1) * (1 + 0 * 1/2 + 0*1/4 + ..... + [0 or 1] * 1/(2^52) )  

Что важно, точность вашего номера будет сохранена в виде срезов, таких как 1/(2^53), что : 1.1102230246251565404236316680908e-16. Тогда это будет округлено. SQL Сервер, SSMS и SQLCMD могут решать, как округлить это число при отображении или преобразовании. Например, они изменили правила округления до десятичного числа во время преобразования в версии 2016.

Суммирующие, действительные и числа с плавающей запятой никогда не сохраняются как точные числа. Скорее, они всегда являются округленным результатом двоичного деления. Вы можете найти больше информации о внутреннем хранилище в Википедии:

Double-precision_floating-point_format

...