#sql #sql-server #floating-point #rounding
#sql #sql-server #с плавающей запятой #округление
Вопрос:
Я сталкиваюсь с этой странной проблемой в SQL Server при разделении числа с плавающей запятой, которое хранится в переменной, против, когда просто используется значение.
Случай следующий:
DECLARE @FLOAT FLOAT = 6.80
print ROUND(@FLOAT / 2, 2, 0);
print ROUND(@FLOAT / 2, 2, 1);
Он печатает:
3.4
3.39
Второй РАУНД, который усекает значение, дает неправильное значение. Оно должно быть 3.4, а не 3.39.
Но когда я использую значение без переменной, оно работает правильно:
print ROUND(6.80 / 2, 2, 0);
print ROUND(6.80 / 2, 2, 1);
Он печатает:
3.400000
3.400000
Кто-нибудь может помочь мне разобраться в этой проблеме?
Заранее спасибо.
Комментарии:
1. В этом нет ничего странного, вы используете a
float
для первого выражения и adecimal
для второго, вы должны ожидать такого поведения. Базовые числа 2 и 10 действуют совершенно по-разному.2. Спасибо за ваш быстрый комментарий. Извините, но я не думаю, что понял, что вы подразумеваете под «Базовыми числами 2 и 10 действуют совершенно по-разному», связанными с float .
3. Основание 2 или двоичные числа против основания 10 или десятичных чисел. Нецелые значения часто не могут быть точно сохранены с помощью первого. Например, прочитайте здесь .
Ответ №1:
Такое поведение ожидается. В первом выражении вы используете a float
, а в последнем литерале decimal
. Эти два типа данных очень разные. Первое значение имеет базовое значение 2, а второе — базовое значение 10.
6.80
невозможно сохранить точно с использованием базы 2, и поэтому его фактическое значение ближе к значению 6.79999999999999982236431605997495353221893310546875
. Как вы можете видеть, это немного меньше, чем, 6.8
и поэтому, когда вы делите это число на 2
, вы получаете число 3.40
, которое, вероятно 3.399999999999999911182158029987476766109466552734375
, немного меньше, чем.
В результате ROUND
округляется число правильно, так как приведенное выше значение, округленное до 2 цифр 3.39
, нет 3.40
.
Для литерала 6.80
оно представлено точно, и so is 6.80 / 2
( 3.40
) поэтому, когда вы снова округляете это число до 2 знаков после запятой, вы все равно получаете 3.40