Функции 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;
[[ column ]] |
---|
NULL [[ value ]] |
x | y | sqrt_y |
---|---|---|
3 | 9 | 3 |
Правильно. Однако
select 3.1 x, power(3.1,2) y, sqrt(power(3.1,2)) sqrt_y;
[[ column ]] |
---|
NULL [[ value ]] |
даст
x | y | sqrt_y |
---|---|---|
3.1 | 9.6 | 3,09838667696593 |
Этот неожиданный результат, вероятно, связан с потерей точности при неявном преобразовании результата функции POWER (который соответствует типу аргумента, т.е. numeric) к типу данных FLOAT.
Действительно,
select SQL_VARIANT_PROPERTY(3.1,'BASETYPE') basetype
[[ column ]] |
---|
NULL [[ value ]] |
basetype |
---|
numeric |
Если применить эквивалентное преобразование, которое сохраняет тип NUMERIC для возвращаемого результата,
select 3.1 x, power(3.1,2) y, power(power(3.1,2),0.5) sqrt_y;
[[ column ]] |
---|
NULL [[ value ]] |
то получим ожидаемый результат
x | y | sqrt_y |
---|---|---|
3.1 | 9.6 | 3.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;
[[ column ]] |
---|
NULL [[ value ]] |
x | y | sqrt_y |
3.1 | 9.6 | 3,1 |
Если же изменить порядок применения функций, то никаких “чудес” не возникает:
select power(sqrt(9.6),2) power_;
[[ column ]] |
---|
NULL [[ value ]] |
power_ |
---|
9,6 |
В этом примере функция SQRT возвращает результат типа FLOAT, что не требует преобразования.