Кажущаяся арифметическая c ошибка при преобразовании в tinyint только для одной строки - PullRequest
2 голосов
/ 13 марта 2020

Иметь таблицу строковых чисел, где все значения находятся в диапазоне от 0,80 до 1,10 Преобразование в индекс поиска tinyint дает арифметическую ошибку c только для одного значения ... '1,06', и я не могу понять, почему.

select @@version
select 1.06 * 200
select convert(tinyint, 1.06 * 200)
select convert(real, '1.06') * 200
select convert(tinyint, convert(real, '1.06') * 200)

дает ...

Microsoft SQL Server 2014 (SP3-CU-GDR) (KB4535288) - 12.0.6372.1 (X64)
212.00
212
212
211

Ответы [ 2 ]

1 голос
/ 13 марта 2020

Кажется, это классический случай ошибок округления.

Проверьте этот код:

declare @val float = convert(real, '1.06') * 200;
select @val; --211,999984741211

Вы можете рассмотреть преобразование в float вместо real, но даже тогда может случиться так, что вы получите ошибки округления.

Вы можете рассмотреть возможность преобразования в decimal или numeric, так как эти типы ведут себя несколько иначе в отношении округления. Но эти типы используют больше памяти и работают медленнее, чем real и float.

. Возможно, вы также захотите проверить, есть ли функции округления (например, ROUND и FLOOR) может быть полезным для вас.

С точки зрения дизайна, почти всегда будет лучшим выбором хранить числовые данные в числовых типах вместо строк. (Числовые данные предназначены для использования в целях выполнения расчетов. Кроме того, преобразование значения цифры 1027 * в строку технически проще и более гибко, чем преобразование строки в числовое значение.)

Вы должны исследовать эти (и другие?) Возможные решения, а затем выбрать, какое решение лучше всего подойдет для вашей проблемы.

0 голосов
/ 13 марта 2020
select convert(tinyint, convert(decimal(3,2), '1.06') * 200)
select convert(tinyint, convert(real, '1.06000001') * 200)

оба дают правильное значение 212.

Я буду использовать десятичную дробь, но смущен, почему такая ошибка округления, когда используются только 2 десятичных знака.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...