Функции POWER и SQRT

Функция SQL Server POWER(x, y) возводит x в степень y.

x является выражением типа FLOAT, или типа, неявно приводимого к FLOAT.

y - выражение числового типа.

Возвращаемое значение имеет тип выражения x.

Функция SQRT(x) вычисляет корень квадратный из x, при этом x является выражением типа FLOAT, или неявно приводимого к нему. Результат имеет тип FLOAT.

Функция SQRT является обратной к функции POWER(x, 2), т.е. SQRT(POWER(x, 2)) должна возвращать x.

Проверим это

select 3 x, power(3,2) y, sqrt(power(3,2)) sqrt_y;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]
xysqrt_y
393

Правильно. Однако

select 3.1 x, power(3.1,2) y, sqrt(power(3.1,2)) sqrt_y;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]

даст

xysqrt_y
3.19.63,09838667696593

Этот неожиданный результат, вероятно, связан с потерей точности при неявном преобразовании результата функции POWER (который соответствует типу аргумента, т.е. numeric) к типу данных FLOAT.

Действительно,

select SQL_VARIANT_PROPERTY(3.1,'BASETYPE') basetype
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]
basetype
numeric

Если применить эквивалентное преобразование, которое сохраняет тип NUMERIC для возвращаемого результата,

select 3.1 x, power(3.1,2) y, power(power(3.1,2),0.5) sqrt_y;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]

то получим ожидаемый результат

xysqrt_y
3.19.63.1

Аналогичный результат мы получим, применив преобразование типа данных аргумента функции POWER к FLOAT в примере с использованием SQRT. В этом случае функция POWER вернет значение типа FLOAT, и преобразование не потребуется. Действительно,

select 3.1 x, power(3.1,2) y, sqrt(power(cast(3.1 as float),2)) sqrt_y;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]
xysqrt_y
3.19.63,1

Если же изменить порядок применения функций, то никаких “чудес” не возникает:

select power(sqrt(9.6),2) power_;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]
power_
9,6

В этом примере функция SQRT возвращает результат типа FLOAT, что не требует преобразования.