MSAccess 2013 странное округление в запросах

#sql #ms-access-2013 #rounding-error

Вопрос:

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

По сути, у меня есть значение [Сумма] типа Single, которое часто имеет 5-значную точность, но в некоторых запросах я хочу округлить его до двух цифр, в других случаях оно равно 5. Я нахожу, что даже если фактические данные [Сумма] состоят только из двух знаков после запятой, запрос возвращает 12 или 13, почти как при работе в обратном порядке, где он «отменяет» их до немного меньшего числа…смотреть ниже. Я даже попытался использовать функцию округления целых чисел, которая сначала умножает значение на 100000, затем принимает целое число, затем делит на 100000, и я вижу аналогичное поведение: это похоже на то, что Access хранит данные с другой точностью, чем на самом деле их представляет

Никогда не видел этого раньше, не уверен, как это исправить и сделать так, как ожидалось. Кстати, если я использую тот же запрос и создам из него таблицу, эти 12-значные значения будут помещены в новую таблицу.

Любые идеи оценены по достоинству, потому что я пытаюсь исправить свою математику до 5 цифр в некоторых местах, и эта неточность делает невозможным узнать, какова должна быть реальная ценность. Я поместил несколько выборочных значений выше начального 2-значного числа, чтобы вы могли видеть, насколько запутанным является поведение.

SQL:

 SELECT amount, Round([amount],2) AS Round_2_Digits, Round([amount],5) AS Round_5_digits, Int([amount]*100000)/100000 AS Integer_5 digits from FCS
 
 amount     Round_2_Digits     Round_5_digits    Integer_5 digits
95.88       95.879997253418     95.879997253418     95.87999
95.88001    95.879997253418     95.880012512207     95.88001
95.881      95.879997253418     95.8809967041016    95.88099
95.889      95.8899993896484    95.8889999389648    95.88899
 

Обновление: когда я писал это, я задавался вопросом, был ли проблемой Один тип данных, и когда я изменил его дважды, сначала исходные данные [Amojnt] определенно изменились, как показано ниже, затем, когда я исправил исходный [Объем] на исходный, функция округления работала идеально. На самом деле это работало даже со странными данными, так как их было так мало, что они были отключены.

Так является ли виновником Один тип данных? Я использовал его, потому что пытался свести к минимуму хранение данных, но ясно, что двойной — это правильный путь. кто-нибудь знает, почему? Спасибо!

Вот обновленный запрос после того, как я изменил тип данных на двойной:

 amount         Round_2_Digits   Round_5_digits  Integer_5 digits
95.879997253418     95.88       95.88           95.87999
95.880012512207     95.88       95.88001        95.88001
95.8809967041016    95.88       95.881          95.88099
95.8889999389648    95.89       95.889          95.88899
 

Вот запрос после того, как я сбросил исходные данные до того, какими они должны были быть

 amount     Round_2_Digits   Round_5_digits  Integer_5 digits
95.88       95.88            95.88          95.88
95.88001    95.88            95.88001       95.88001
95.881      95.88            95.881         95.881
95.889      95.89            95.889         95.889
 

Ответ №1:

Вы никогда не должны полагаться на собственные Round данные для получения каких-либо точных данных, так как они довольно глючные. Кроме того, он выполняет округление Банкира, которое может быть не тем, что вы хотите.

В вашем случае вы можете использовать RoundMid функцию, найденную в VBA.Round.

Комментарии:

1. спасибо за вашу информацию, интересную о функции roundmid, обязательно ознакомьтесь с ней. но похоже, что это скорее функция одного типа данных, чем функция округления. отлично работает, если данные типа Double, просто странные данные для одного и того же запроса и другого кода, использующего Single.

2. Сингл всегда следует использовать с осторожностью. Но такая осторожность не делает круглую работу идеальной; она полезна только для некритического округления.