SQL 轮函数

发布于 2024-07-26 04:02:54 字数 111 浏览 4 评论 0原文

round(45.923,-1) 给出的结果是 50。这是为什么? 它是如何计算的?

(抱歉,我错误地认为这个问题的早期版本建议值为 46)

round(45.923,-1) gives a result of 50. Why is this? How it is calculated?

(sorry guys i was mistaken with earlier version of this question suggesting value was 46)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

記憶穿過時間隧道 2024-08-02 04:02:54

SQL ROUND() 函数将数字舍入为精度...

例如:

round(45.65, 1) 给出结果 = 45.7

round(45.65, -1) 给出结果 = 50,

因为这种情况下的精度是根据小数计算的观点。 如果为正,则它会考虑右侧数字,如果 >= 5,则向上舍入;如果 <=4,则向下舍入...同样,如果为负,则计算左侧的精度小数点...如果它 >= 5

例如 round(44.65, -1) 给出 40
但 round(45.65, -1) 给出 50...

The SQL ROUND() function rounds a number to a precision...

For example:

round(45.65, 1) gives result = 45.7

round(45.65, -1) gives result = 50

because the precision in this case is calculated from the decimal point. If positive then it'll consider the right side number and round it upwards if it's >= 5, and if <=4 then round is downwards... and similarly if it's negative then the precision is calculated for the left hand side of decimal point... if it's >= 5

for example round(44.65, -1) gives 40
but round(45.65, -1) gives 50...

故人如初 2024-08-02 04:02:54

ROUND(748.58, -1) 750.00

第二个参数:Lenght,是 numeric_expression 要舍入的精度。 length 必须是tinyint、smallint 或int 类型的表达式。 当 length 为正数时, numeric_expression 将四舍五入到 length 指定的小数位数。 当 length 为负数时,numeric_expression 将按 length 指定的方式在小数点左侧四舍五入。

来自

ROUND(748.58, -1) 750.00

the second parameter: Lenght, is the precision to which numeric_expression is to be rounded. length must be an expression of type tinyint, smallint, or int. When length is a positive number, numeric_expression is rounded to the number of decimal positions specified by length. When length is a negative number, numeric_expression is rounded on the left side of the decimal point, as specified by length.

From

当梦初醒 2024-08-02 04:02:54

预计为 50。

round(45.923, 0) => 46

解释:最后一个非十进制数字四舍五入(5),决定基于下一个数字(9)
9 位于上半部分,因此 5 向上舍入为 6

round(45.923, 1) => 45.9

解释:第一个小数位四舍五入(9),决定基于下一个数字(2)
2 在下半部分,因此 9 保持 9

你的情况:
回合(45.923, 1-) => 45.92

expl:倒数第二个非十进制数字被四舍五入(4),决定基于下一个数字(5)
5 在上半部分,因此 4 向上舍入为 5,数字的其余部分用 0 填充

It is expected to be 50.

round(45.923, 0) => 46

expl: the last non-decimal digit is rounded (5), the desicion is based on the next digit (9)
9 is in the high half, ergo 5 is rounded up to 6

round(45.923, 1) => 45.9

expl: the first decimal digit is rounded (9), the desicion is based on the next digit (2)
2 is in the low half, ergo 9 stays 9

your case:
round(45.923, 1-) => 45.92

expl: the secon-last non-decimal digit is rounded (4), the desicion is based on the next digit (5)
5 is in the top half, ergo 4 is rounded up to 5, the rest of the digist are filled with 0s

清欢 2024-08-02 04:02:54

至于如何进行,首先考虑如何将(正)浮点数舍入为最接近的整数。 将 float 转换为 int 会截断它。 当我们想要向上舍入时(当小数部分 >= 0.5 时),向(正)浮点数添加 0.5 将精确地增加整数部分。 这给出了以下内容:

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

要添加对精度参数的支持,请注意(例如 round(123456.789, -3))添加 500 并在千位上截断与添加 0.5 和四舍五入到最接近的整数,只是小数点位置不同。 要移动小数点,我们需要左移和右移操作,这相当于乘以基数乘以移动量。 即,0x1234 >>> 3 与基数 2 中的 0x1234 / 2**30x1234 * 2**-3 相同。基数 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);
}

As for how, start by considering how you'd round a (positive) float to the nearest integer. Casting a float to an int truncates it. Adding 0.5 to a (positive) float will increment the integer portion precisely when we want to round up (when the decimal portion >= 0.5). This gives the following:

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

To add support for the precision parameter, note that (for e.g. round(123456.789, -3)) adding 500 and truncating in the thousands place is essentially the same as adding 0.5 and to rounding to the nearest integer, it's just that the decimal point is in a different position. To move the radix point around, we need left and right shift operations, which are equivalent to multiplying by the base raised to the shift amount. That is, 0x1234 >> 3 is the same as 0x1234 / 2**3 and 0x1234 * 2**-3 in base 2. In base 10:

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

For round(123456.789, -3), this means we can do the above multiplication to move the decimal point, add 0.5, truncate, then perform the opposite multiplication to move the decimal point back.

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

Rounding by adding 0.5 and truncating works fine for non-negative numbers, but it rounds the wrong way for negative numbers. There are a few solutions. If you have an efficient sign() function (which returns -1, 0 or 1, depending on whether a number is <0, ==0 or >0, respectively), you can:

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

If not, there's:

double round(double x, double p) {
    if (x<0) 
      return - round(-x, p);
    return ((long long)((x * pow10(p))) + 0.5) * pow10(-p);
}
渡你暖光 2024-08-02 04:02:54

它不适合我的 MySQL:

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

It doesn't for me on MySQL:

mysql> select round(45.923,-1);
+------------------+
| round(45.923,-1) |
+------------------+
|               50 |
+------------------+
1 row in set (0.00 sec)
画离情绘悲伤 2024-08-02 04:02:54

在 Sql Server 2005 上:

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

您在什么数据库上运行它?

And on Sql Server 2005:

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

What database are you running this on?

小情绪 2024-08-02 04:02:54

有一件事是,round 函数中的第一个参数是数字,第二个参数是小数点后的精度索引。

这意味着如果精度索引为0,则位于第一个小数,-1表示小数点之前的第一个数字,1表示第一个小数的右侧,即第二个小数

例如

round(111.21,0)---------> return 111
round(115.21,-1)--------->return 120
round(111.325,2)---------->return 111.33
round(111.634,1)-----------> return 111.6

one thing is in the round function first parameter is the number and the second parameter is the precision index from the decimal side.

That means if precision index is 0 it is at the first decimal, -1 means before the decimal first number, 1 means right side of the first decimal i.e second decimal

For example

round(111.21,0)---------> return 111
round(115.21,-1)--------->return 120
round(111.325,2)---------->return 111.33
round(111.634,1)-----------> return 111.6
爱你是孤单的心事 2024-08-02 04:02:54
SELECT 
    c.mac_address,
    COUNT(*) AS total_streams,
    CASE 
        WHEN SUM(CASE WHEN s.quality = '720p' THEN s.traffic ELSE 0 END) >= 1024 * 1024
        THEN CONCAT(ROUND(SUM(CASE WHEN s.quality = '720p' THEN s.traffic ELSE 0 END) / (1024 * 1024), 2), ' GiB')
        ELSE CONCAT(ROUND(SUM(CASE WHEN s.quality = '720p' THEN s.traffic ELSE 0 END) / 1024, 2), ' MiB')
    END AS traffic_720p,
    CASE 
        WHEN SUM(CASE WHEN s.quality = '1080p' THEN s.traffic ELSE 0 END) >= 1024 * 1024
        THEN CONCAT(ROUND(SUM(CASE WHEN s.quality = '1080p' THEN s.traffic ELSE 0 END) / (1024 * 1024), 2), ' GiB')
        ELSE CONCAT(ROUND(SUM(CASE WHEN s.quality = '1080p' THEN s.traffic ELSE 0 END) / 1024, 2), ' MiB')
    END AS traffic_1080p,
    CASE 
        WHEN SUM(CASE WHEN s.quality = '1440p' THEN s.traffic ELSE 0 END) >= 1024 * 1024
        THEN CONCAT(ROUND(SUM(CASE WHEN s.quality = '1440p' THEN s.traffic ELSE 0 END) / (1024 * 1024), 2), ' GiB')
        ELSE CONCAT(ROUND(SUM(CASE WHEN s.quality = '1440p' THEN s.traffic ELSE 0 END) / 1024, 2), ' MiB')
    END AS traffic_1440p,
    CASE 
        WHEN SUM(CASE WHEN s.quality = '2160p' THEN s.traffic ELSE 0 END) >= 1024 * 1024
        THEN CONCAT(ROUND(SUM(CASE WHEN s.quality = '2160p' THEN s.traffic ELSE 0 END) / (1024 * 1024), 2), ' GiB')
        ELSE CONCAT(ROUND(SUM(CASE WHEN s.quality = '2160p' THEN s.traffic ELSE 0 END) / 1024, 2), ' MiB')
    END AS traffic_2160p
FROM 
    streams s
JOIN 
    clients c ON s.client_id = c.client_id
GROUP BY 
    c.mac_address;
SELECT 
    c.mac_address,
    COUNT(*) AS total_streams,
    CASE 
        WHEN SUM(CASE WHEN s.quality = '720p' THEN s.traffic ELSE 0 END) >= 1024 * 1024
        THEN CONCAT(ROUND(SUM(CASE WHEN s.quality = '720p' THEN s.traffic ELSE 0 END) / (1024 * 1024), 2), ' GiB')
        ELSE CONCAT(ROUND(SUM(CASE WHEN s.quality = '720p' THEN s.traffic ELSE 0 END) / 1024, 2), ' MiB')
    END AS traffic_720p,
    CASE 
        WHEN SUM(CASE WHEN s.quality = '1080p' THEN s.traffic ELSE 0 END) >= 1024 * 1024
        THEN CONCAT(ROUND(SUM(CASE WHEN s.quality = '1080p' THEN s.traffic ELSE 0 END) / (1024 * 1024), 2), ' GiB')
        ELSE CONCAT(ROUND(SUM(CASE WHEN s.quality = '1080p' THEN s.traffic ELSE 0 END) / 1024, 2), ' MiB')
    END AS traffic_1080p,
    CASE 
        WHEN SUM(CASE WHEN s.quality = '1440p' THEN s.traffic ELSE 0 END) >= 1024 * 1024
        THEN CONCAT(ROUND(SUM(CASE WHEN s.quality = '1440p' THEN s.traffic ELSE 0 END) / (1024 * 1024), 2), ' GiB')
        ELSE CONCAT(ROUND(SUM(CASE WHEN s.quality = '1440p' THEN s.traffic ELSE 0 END) / 1024, 2), ' MiB')
    END AS traffic_1440p,
    CASE 
        WHEN SUM(CASE WHEN s.quality = '2160p' THEN s.traffic ELSE 0 END) >= 1024 * 1024
        THEN CONCAT(ROUND(SUM(CASE WHEN s.quality = '2160p' THEN s.traffic ELSE 0 END) / (1024 * 1024), 2), ' GiB')
        ELSE CONCAT(ROUND(SUM(CASE WHEN s.quality = '2160p' THEN s.traffic ELSE 0 END) / 1024, 2), ' MiB')
    END AS traffic_2160p
FROM 
    streams s
JOIN 
    clients c ON s.client_id = c.client_id
GROUP BY 
    c.mac_address;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文