POWER не переворачивает LOG и наоборот - PullRequest
0 голосов
/ 03 января 2019

Проблема, с которой я столкнулся в POWER / LOG, заключается в том, что, хотя они, похоже, адаптируются к типу данных, которые вы отправляете (тип выходной переменной соответствует типу первой переменной), точность, похоже, останавливается близко к пределам типа float, что приводит к неправильному выводу.Пример:

DECLARE @ten numeric(18,4) = 10
declare @num numeric(18,4) = 234567890
SELECT power(@ten,log(@num,@ten))

Ouput = 234567890.0000 Что является правильным

Однако, если мы увеличим точность, выполните следующие действия:

DECLARE @ten numeric(18,6) = 10
declare @num numeric(18,6) = 234567890
SELECT power(@ten,log(@num,@ten))

Вывод = 234567889.999999 Что не правильно, но округление может это исправить (?)

Наконец, если вы измените точность на что-то вроде числового (18,9), проблема усугубится:

DECLARE @ten numeric(18,9) = 10
declare @num numeric(18,9) = 234567890
SELECT power(@ten,log(@num,@ten))

Output = 234567889.999999310 Какойне правильно, и округление не исправит это.

Я предполагаю, что проблема в том, что хотя функции POWER и Log могут принимать очень точные типы данных, их рабочие переменные должны быть плавающими?У кого-нибудь есть опыт работы с этим или опыт работы с ним?

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Это слишком долго для комментария.

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

Функция log() задокументирована как принимающая float в качестве аргумента и возвращающая float.power() ведет себя немного по-другому.Первый аргумент преобразуется в float, но он также определяет тип возвращаемого значения.Вот почему шкала типа возвращаемого значения определяется шкалой @ten.

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

В этом нет ничего удивительного.234567889.9999993145465850830 является производимой стоимостью.Это наиболее близко, что SQL Server может прийти к фактическому ответу - и достаточно близко для большинства работ.

0 голосов
/ 03 января 2019

Я думаю, что проблема заключается в типе возврата для LOG, равном FLOAT, а не к типу данных, который вы передаете. FLOAT, это данные приблизительного числатипы для использования с числовыми данными с плавающей запятой.Данные с плавающей точкой являются приблизительными;следовательно, не все значения в диапазоне типов данных могут быть представлены в точности .

С другой стороны, POWER принимает выражение типа float или типа, который может быть неявно преобразован в float. в качестве входных данных и возвращаеттип зависит от типа ввода выражения с плавающей запятой.Это означает, что он вернет DECIMAL для ввода DECIMAL.

Так что в вашем случае LOG возвращает FLOAT, который передается в POWER, который возвращает FLOAT, чтокак указано, не является точным.

...