2015-04-23 4 views
1

У нас есть ряд полей, определяемых как числовые (38,20) - поскольку данные перемещаются в ORACLE db с этой шкалой/точностью.Работа с десятичной точностью

При выполнении расчетов округление имеет тенденцию происходить между 12 и 14 знаками после запятой (в зависимости). Я тестировал различные комбинации поплавков/десятичных знаков в надежде сохранить точность и сохранить обратно в числовые (38,20)

, например.

введите код здесь

declare @dtest20 decimal(38,20) = cast(1.44444444441234567892 as decimal(38, 20)) 
declare @ftest20 float = cast(1.44444444441234567892 as float) 
declare @f100 float = cast(100.0 as float) 
declare @d100 decimal(38,20) = cast(100.0 as decimal(38,20)) 

select @dtest20 * @d100 as 'dtest20 x d100' 
, cast(@dtest20 * @d100 as decimal(38,20)) as 'dtest20 x d100' 
, @ftest20 * @f100 as 'ftest20 x f100' 
, cast(@ftest20 * @f100 as decimal(38,20)) as 'ftest20 x f100' 

dtest20 x d100 dtest20 x d100 ftest20 x f100 ftest20 x f100 144.444444 144.44444400000000000000 144.444444441235 144.44444444123457000000 

Я знаю, что это действительно MS-SQL вещь, но есть ли работа вокруг/рекомендации для выполнения вычислений на больших точных цифр и избежать непреднамеренного округление?

Спасибо!

+0

SQL не является подходящей платформой для выполнения точных вычислений, но, как правило, вы должны хранить значения в виде десятичных знаков, но выполнять вычисления с использованием поплавков. – Jaco

+1

@JacodeGroot - «... хранить значения как десятичные числа, но выполнять вычисления с использованием поплавков» - мне действительно нужно задать вопрос, почему вы хотите сохранить результаты в DECIMAL, а затем выбрасывайте точность и точность с помощью FLOAT в вычислениях? (͏the͏ anći͜e͡nt ̷evìl͢ ҉a͝w̴a̸k͢en̵s͞.͜..̡) Это безумие! (H̷ę̛ ̶͝c̵̸o͝m҉̸͜e̷͝͠s..͝.͝) ͠ Отвернитесь! Вернуться!! C̢̢҉͏҉͏҉͏̷̛͜҉̡͝͠҉̡͝͠҉̡͝͠҉̡͝͠҉̡͝͠҉̶̶̶̶̴̶̴̶̵̡̨̨̨̨̢̨̢̨̛̛̛̛̛̛̛̛͘͘̕͜͜͜͟͟͜͝͠͞͞͞͞͞͞͞͠͠ ̢͟͜͟ Бегите от неимоверного террора в FPU !!! ĮĮ̵̧! ̴̧̕ ̶̛Į̵̵̵a̡͜͠! ͡ ̡̢̛͘C̷̨̡͞t͏͝҉҉h͜u̷̶l̸h̕͞ù͘͟͠! ̸! ̵̧̛ ҉̕͢͞҉C̵̡͘͢͞t͝҉͜h͟u̵͘l̢̡h̡̡͢͜͢͜ư̶̵ ̵͟͟f̷̶͞͝h̸̛͜͠҉ţ̷a̸̛̛͞g̸̨n͏҉̸̨! ҉! ̵! ͡ –

+0

Если вы запустили это на MS SQL, почему он помечается 'mysql'? – dnoeth

ответ

1

Правило, которое должно выполняться: Используйте точные числовые типы данных для всех значений. Не превышайте точность и масштаб. (Синтаксис PostgreSQL следующим образом.)

select cast(1.44444444441234567892 as decimal(38, 20)) as cast_decimal; 
 
cast_decimal 
numeric(38,20) 
-- 
1.44444444441234567892 

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

select cast(1.44444444441234567892 as float) as cast_float; 
 
cast_float 
double precision 
-- 
1.44444444441235 

Умножение десятичных чисел на целое число возвращает десятичное. Таким образом, смешивание десятичных и целочисленных типов данных при умножении дает неудивительные результаты. Это то, что мы хотим - неудивительные результаты.

select cast(1.44444444441234567892 as decimal(38, 20)) * 100 as dec_x_int; 
 
dec_x_int 
numeric 
-- 
144.44444444123456789200 

Деление десятичной целым числом дает неудивителен результаты. Но это деление потеряло цифру, потому что число цифр в фактическом результате больше 20. Это не должно быть неожиданностью.

select cast(1.44444444441234567892 as decimal(38, 20))/100 as dec_div_int; 
 
dec_div_int 
numeric 
-- 
0.01444444444412345679 

Умножение десятичных чисел с плавающей точкой по возвращает определенную реализацией приблизительный числовой. (См. Ниже.) Мы потеряли точность, не соблюдая правила, которые должны соблюдаться.

select cast(1.44444444441234567892 as numeric(38,20)) * 100::float as dec_x_flt; 
 
dec_x_flt 
double precision 
-- 
144.444444441235 

SQL Стандарты

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

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

Смежные вопросы