2009-07-10 2 views
4

round(45.923,-1) дает результат 50. Почему это? Как он рассчитывается?Функция SQL Round

(извините, ребята, я ошиблась с более ранней версией этого вопроса предлагая значение было 46)

+0

Это дает 50 на MySQL 5.0.67-0ubuntu6, как описано в http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_round - то, что ты с помощью? –

+0

чувак ... я знаю, но почему? как оно рассчитывается – hrishi

+0

Возможно, вам нужна дополнительная информация о том, что вы пытаетесь сделать? Это некорректная информация о ней. –

ответ

11

SQL-ROUND() функция округляет число с точностью ...

Например:

раунд (45.65, 1) дает результат = 45,7

раунд (45.65, -1) дает результат = 50

потому что точность в этом случае вычисляется из десятичной точки. Если положительный, тогда он рассмотрит номер правой стороны и округляет его вверх, если это> = 5, и если < = 4, то раунд вниз ... и аналогично, если он отрицательный, тогда точность вычисляется для левой стороны десятичной пункт ... если это> = 5

, например раунде (44,65, -1) дает 40 но круглый (45,65, -1) дает 50 ...

+0

В вашем раунде вопросов (45,923, -1) будет получено 50 .. однако круглый (44,923, -1) будет равен 40. –

+0

Simillarly round (45.923, -2) даст 0,00 –

1

Это не для меня на MySQL:

mysql> select round(45.923,-1); 
+------------------+ 
| round(45.923,-1) | 
+------------------+ 
|    50 | 
+------------------+ 
1 row in set (0.00 sec) 
+0

То же самое на SQL Server – AdaTheDev

+0

Прикомандировано ... о хорошо. –

0

А на Sql Server 2005:

select round(45.923,-1) 
------ 
50.000 

В какой базе данных вы используете это?

4

ROUND (748,58, -1) 750,00

второй параметр: Длина, является точность, к которой numeric_expression округляется. длина должна быть выражением типа tinyint, smallint или int. Когда длина является положительным числом, числовое выражение округляется до количества десятичных позиций, заданных по длине. Когда длина является отрицательным числом, числовое выражение округляется в левой части десятичной точки, как указано длиной.

From

2

ожидается, что будет 50.

раунд (45,923, 0) => 46

Обосн: последний без десятичных цифр округляется (5), desicion основан на следующей цифре (9) 9 находится в верхней половине, эрго 5 округляется до 6

раунда (45.923, 1) => 45,9

Обосн: первая десятичная цифра округляется (9), то desicion основан на следующей цифре (2) 2 находится в нижней половине, эрго 9 остается 9

ваш случай: круглые (45.923, 1-) => 45.92

expl: секундная последняя десятичная цифра округлена (4), назначение основано на следующей цифре (5) 5 находится в верхней половине, эрго 4 округляется до 5, остальные of digic заполнены 0s

2

Что касается того, как, начните с рассмотрения того, как вы должны округлить (положительный) плав к ближайшему целому. Приведение float в int усекает его. Добавление 0.5 к (положительному) float будет увеличивать целую часть точно, когда мы хотим округлить (когда десятичная часть> = 0,5). Это дает следующее:

double round(double x) { 
    return (long long)(x + 0.5); 
} 

Чтобы добавить поддержку для параметра точности, заметит, что (для например round(123456.789, -3)), добавив 500 и усечения в месте тысяч, по существу, такие же, как при добавлении 0,5 и округления до ближайшего целого числа, это просто, что десятичная точка находится в другом положении. Чтобы перемещать точку радиуса вокруг, нам нужны операции сдвига влево и вправо, которые эквивалентны умножению на базу, поднятую до суммы сдвига. То есть, 0x1234 >> 3 такая же, как и 0x1234/2**30x1234 * 2**-3 в базе 2. В базе 10:

123456.789 >> 3 == 123456.789/10**3 == 123456.789 * 10**-3 == 123.456789 

Для round(123456.789, -3), это означает, что мы можем сделать выше умножение, чтобы переместить десятичную точку, добавить 0,5, усечение, а затем выполнить противоположное умножение для перемещения десятичной точки назад.

double round(double x, double p) { 
    return ((long long)((x * pow10(p))) + 0.5) * pow10(-p); 
} 

Округление добавлением 0,5 и усечения отлично работает для неотрицательных чисел, но округляет неправильный путь для отрицательных чисел. Есть несколько решений. Если у вас есть эффективный sign() функцию (которая возвращает -1, 0 или 1, в зависимости от того, является ли число < 0 == 0 или> 0, соответственно), вы можете:

double round(double x, double p) { 
    return ((long long)((x * pow10(p))) + sign(x) * 0.5) * pow10(-p); 
} 

Если нет, то есть :

double round(double x, double p) { 
    if (x<0) 
     return - round(-x, p); 
    return ((long long)((x * pow10(p))) + 0.5) * pow10(-p); 
}