sql округление не всегда округление - PullRequest
4 голосов
/ 13 февраля 2012

Я пытаюсь сделать раунд в sql, но результат очень странный; вот что я делаю:

Я использую Mssql

У меня есть выбор:

Select num1, num2, num1 * num2, round(num1 * num2, 2)
from myTable

Тип данных:

число1 - это число с плавающей точкой

num2 - это деньги

если значение num1 равно 15 и значение num2 составляет 0,033 Вот мой набор результатов:

15, 0,033, 0,495, 0,5

Проблема в том, когда у меня есть эти значения:

если значение num1 равно 5 и значение num2 составляет 0,045 Вот мой набор результатов:

5, 0,045, 0,225, 0,22

У кого-нибудь есть идея?

Ответы [ 4 ]

5 голосов
/ 13 февраля 2012

Если вы посмотрите на этот работающий пример в режиме сетки (обратите внимание также, что текстовый режим отличается), вы должны увидеть проблему:

DECLARE @tbl AS TABLE (num1 float, num2 money);
INSERT INTO @tbl VALUES (15, 0.033), (5, 0.045);

Select num1, num2, num1 * num2, round(num1 * num2, 2)
from @tbl;

Обратите внимание, что на самом деле это число .224999999, которое округляется до .22 - вам нужно быть осторожным при взгляде на недвоичный вывод SQL Server - иногда он преобразует числа в текст, чего вы не ожидали. 1006 *

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

Вы должны рассмотреть, что это означает для вашего значения с плавающей запятой, и рассмотреть возможность использования вместо него десятичного числа, а посмотреть правила масштабирования и точности для десятичных операций . Обратите внимание, что деньги только в некоторой степени похожи на десятичные (19, 4)

1 голос
/ 13 февраля 2012

Вы можете попробовать использовать тип long вместо float.Я думаю, что это проблема точности с плавающей точкой.

0 голосов
/ 13 февраля 2012

Я конвертировал свою колонку с плавающей точкой в ​​деньги, и теперь она работает.

Спасибо всем вам!

0 голосов
/ 13 февраля 2012

Какую версию SQL вы используете?

Попробуйте этот код в Query Analyzer


DECLARE @num1 float
DECLARE @num2 money

SET @num1 = 15
SET @num2 = 0.033

SELECT
@Num1,
@Num2,
@Num1 * @Num2,
ROUND(@Num1 * @Num2,0),
ROUND(@Num1 * @Num2,1),
ROUND(@Num1 * @Num2,2),
ROUND(@Num1 * @Num2,3)

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


DECLARE @num1 decimal
DECLARE @num2 money

SET @num1 = 5
SET @num2 = 0.045

SELECT
@Num1,
@Num2,
@Num1 * @Num2,
ROUND(@Num1 * @Num2,2),
ROUND(CAST(@Num1 as money) * @Num2,2)
...