CASE
возвращает значение первого (сверху вниз) выражения THEN
, которое имеет выражение WHEN
, которое оценивается как true (и ELSE
, если ничего не найдено). Поскольку ваше первое WHEN
также верно в случаях, когда второе верно, выбирается первое, а не второе. Всегда ставьте более узкий WHEN
перед менее узкими в CASE
.
CASE
WHEN (type_txt = 'ACCOUNT' AND status = 'ACTIVE' AND code = 483 AND open_date < CURRENT_DATE) THEN 0
WHEN (type_txt = 'ACCOUNT' AND status = 'ACTIVE' THEN 1
ELSE 0
END
У меня был шанс посмотреть на реализацию fdlibm. Комментарии описывают используемый алгоритм:
* n
* Method: Let x = 2 * (1+f)
* 1. Compute and return log2(x) in two pieces:
* log2(x) = w1 + w2,
* where w1 has 53-24 = 29 bit trailing zeros.
* 2. Perform y*log2(x) = n+y' by simulating muti-precision
* arithmetic, where |y'|<=0.5.
* 3. Return x**y = 2**n*exp(y'*log2)
сопровождаемый списком всех обработанных особых случаев (0, 1, inf, nan).
Самые интенсивные разделы кода, после всей обработки особого случая, включают log2
и 2**
вычисления. И нет никаких циклов ни в одном из тех. Так, сложность примитивов с плавающей точкой, несмотря на это, это похоже на асимптотически постоянно-разовый алгоритм.
Эксперты с плавающей точкой (которых я не один) могут прокомментировать.:-)
Можно использовать exp (n*ln (x)) для вычисления xn. И x и n могут быть двойной точностью, числами с плавающей точкой. Функция натурального логарифма и показательная функция могут быть вычислены с помощью Ряда Тейлора. Здесь можно найти формулы: http://en.wikipedia.org/wiki/Taylor_series
Обычный подход, для повышения до b, для целочисленной экспоненты, проходит примерно так:
result = 1
while b > 0
if b is odd
result *= a
b -= 1
b /= 2
a = a * a
Это обычно логарифмически в размере экспоненты. Алгоритм основан на инварианте "a^b*result = a0^b0", где a0 и b0 являются начальными значениями a и b.
Для отрицательного или экспонент нецелого числа, необходимы логарифмы и приближения и числовой анализ. Время выполнения будет зависеть от используемого алгоритма и для какой точности библиотека настраивается.
Править: С тех пор, кажется, существует некоторый интерес, вот версия без дополнительного умножения.
result = 1
while b > 0
while b is even
a = a * a
b = b / 2
result = result * a
b = b - 1
Если бы я писал функции головы предназначение для Intel, то я возвратил бы exp2 (log2 (x) * y). Микрокод Intel для log2, конечно, быстрее, чем что-нибудь, что я смог бы кодировать, даже если я мог бы помнить свое первое исчисление года и аспирантуру числовой анализ.
Если они не обнаружили лучший способ сделать это, я полагаю, что приближенные значения для аккуратных, логарифмических и показательных функций (для экспоненциального роста и затухания, например) обычно вычисляются с помощью арифметических правил и расширений Ряда Тейлора для приведения к приблизительному результату с точностью до в требуемой точности. (См. любую книгу Исчисления для получения дополнительной информации о степенном ряде, Ряде Тейлора и расширениях серии Maclaurin функций.) Обратите внимание на то, что это было некоторое время, так как я сделал любое из этого так, я не мог сказать Вам, например, точно как вычислить количество условий в ряду, который необходимо включать, гарантируют ошибку что достаточно маленький, чтобы быть незначительным в вычислении двойной точности.
Например, расширение серии Taylor/Maclaurin для e^x - это:
+inf [ x^k ] x^2 x^3 x^4 x^5
e^x = SUM [ --- ] = 1 + x + --- + ----- + ------- + --------- + ....
k=0 [ k! ] 2*1 3*2*1 4*3*2*1 5*4*3*2*1
При взятии всех условий (k от 0 до бесконечности), это расширение точно и завершено (никакая ошибка).
Однако, если Вы не берете все условия, идущие в бесконечность, но Вы останавливаетесь, после говорят, что 5 условий или 50 условий или что бы то ни было, Вы приводите к приблизительному результату, который отличается от фактического e^x значения функции остатком, который довольно легко вычислить.
Хорошие новости для экспоненциалов - то, что это сходится приятно, и условия его полиномиального расширения довольно легко кодировать многократно, таким образом, Вы могли бы (повторение, МОГ БЫ - помнить, это было некоторое время), даже не должен предварительно вычислять, сколько условий необходимо гарантировать, что ошибка является меньше, чем точность, потому что можно протестировать размер вклада при каждом повторении и остановиться, когда это становится достаточно близким к нулю. На практике я не знаю, жизнеспособна ли эта стратегия или не - я должен был бы попробовать ее. Существуют важные детали, о которых я давно забыл. Материал как: точность машины, ошибка машины и погрешность округления, и т.д.
Кроме того, обратите внимание на то, что если Вы не используете e^x, но Вы делаете рост/затухание с другой основой как 2^x или 10^x, приближающиеся изменения полиномиальной функции.