SQL Round Function - sql

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)

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...

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

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

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);
}

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)

And on Sql Server 2005:
select round(45.923,-1)
------
50.000
What database are you running this on?

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

Related

How to write in vb.net a decimal number without rounding the 12 digits after the decimal point?

I try to write the result of the division of the number 5991 by 2987 in vb.net, without rounding the decimal or floating point, strictly equal to 2.005691329092 on 12 digits after the decimal point. The decimal part (0.05691329092) is also noted 17/2987 in scientific notation. My tests always led me to 2.005691329093 rounding!
2 17/2987
Actual value is correct, issue is how to format value to display it as expected.
There are no built-in method, but you can multiply value by required amount of digits after decimal point and truncate it.
Dim value As Double = 5991.0 / 2987.0
value = Math.Truncate(value * Math.Pow(10, 12)) / Math.Pow(10, 12)
Console.WriteLine($"Result: {value:F12}")

SQL server round down wit 0.5 step [duplicate]

I read all rounding functions of T-SQL like Round, Floor, and Ceil, but none of them has rounded down decimal numbers correctly for me.
I have 2 questions:
How to round down a decimal number (3.69 ==> 3.5)?
How to round up the last 3 digits of an integer (e.g. 142600 ==> 143000)?
1) select CAST(FLOOR(2 * 3.69) / 2 AS decimal(2, 1)) handles the first case - courtesy of an answer to a similar question on SQL Server Forums, which I adapted and quickly checked.
Note that if the numbers you are rounding to the nearest 0.5 could be bigger (e.g. 333.69 => 333.5), be sure to specify more decimal precision when you cast (e.g. select CAST(FLOOR(2 * 3.69) / 2 AS decimal(10, 1))), or you could get an overflow error:
Msg 8115, Level 16, State 8, Line 1
Arithmetic overflow error converting numeric to data type numeric.
Extra precision will not affect the bottom-line result (i.e. select CAST(FLOOR(2 * 3.69) / 2 AS decimal(10, 1)) and select CAST(FLOOR(2 * 3.69) / 2 AS decimal(2, 1)) both yield 3.5); but it is wasteful if the numbers you are rounding will always be smaller.
Online references with examples are available for T-SQL FLOOR, CAST, and decimal to help.
2) select ROUND(142600, -3) handles the second case.
A similar online reference is available for T-SQL ROUND.
As per #J0e3gan 's anwser, Sql Server's Round allows rounding to the nearest powers of 10 using the length parameter, where length is 10^(-length), e.g.
length = 0 : 10 ^ 0 = nearest 1
length = 3 : 10 ^ -3 = nearest .001
length = -3 : 10 ^ 3 = nearest 1000
etc
However, in general, with a simple 1-based rounding function - e.g. (Sql Round with Length=0) to round to an arbitrary value of "nearest N" - with the formula:
round(X / N) * N
e.g. nearest 100
select round(12345 / 100.0, 0) * 100.0 -- 12300
select round(-9876 / 100.0, 0) * 100.0 -- -9900
select round(-9849 / 100.0, 0) * 100.0 -- -9800
... Nearest 0.5
select round(5.123 / 0.5, 0) * 0.5 -- 5.000
select round(6.499 / 0.5, 0) * 0.5 -- 6.500
select round(-4.499 / 0.5, 0) * 0.5 -- -4.50
... Nearest 0.02
select round(5.123 / .02, 0) * .02 -- 5.12
select round(-9.871 / .02, 0) * .02 -- -9.88
etc
Remember that the type used for the divisors must be numeric / decimal or float.
The Oracle/PLSQL FLOOR function returns the largest integer value that is equal to or less than a number.
eg:
FLOOR(7.9)
Result: 7
FLOOR(30.29)
Result: 30
FLOOR(-7.9)
Result: -8

calculations in Objective-C

Could anyone explain to me why this keeps returning 0 when it should return a value of 42? it works on paper so i know the math is right I'm just wondering as to why it isn't translating across?
int a = 60;
int b = 120;
int c = 85;
int progress;
progress = ((c-a)/(b-a))*100;
NSLog(#"Progess = %d %%",progress);
It's because your math is all using integers.
In particular, your inner expression is calculating 25 / 60, which in integer math is zero.
In effect you have over-parenthesised your expression, and the resulting order of evaluation is causing integer rounding problems.
It would have worked fine if you had just written the formula so:
progress = 100 * (c - a) / (b - a);
because the 100 * (c - a) would first evaluate to 2500, and would then be divided by 60 to give 41.
Alternative, if any one (or more) of your variables a, b, or c were a float (or cast thereto) the equation would also work.
That's because an expression in which either operand is a float will cause the other (integer) operand to be promoted to a float, too, at which point the result of the expression will also be a float.
c - a will give you 25
b - a will give you 60
Since a, b, and c are all integers, meaning they can't be decimals. Therefore, by doing (c-a)/(b-a), you will get 0, instead of 0.41666666 because in integer division, anything after the decimal point will get cut off, leaving the number before the decimal point.
To make it work the way you wanted it to, you should try casting (c-a) and (b-a) to either double or float:
progress = ((float)(c-a) / (float)(b-a)) * 100;
or
progress = ((double)(c-a) / (double)(b-a)) * 100;
a,b and c are ints. When you calculate ((c-a)/(b-a)), the result is also an int; the real value is a decimal (0.42), but an int can't take a decimal number, so it rounds to 0, which is multiplied by 100 to get 0.
Because (c - a) / (b - a) is computed using integer math.
To fix, cast to a float before dividing:
progress = (int)((((float)(c - a)) / ((float)(b - a))) * 100);

Objective-C Integer Arithmetic

I'm trying to calculate some numbers in an iPhone application.
int i = 12;
int o = (60 / (i * 50)) * 1000;
I would expect o to be 100 (that's milliseconds) in this example but it equals 0 as displayed by NSLog(#"%d", o).
This also equals 0.
int o = 60 / (i * 50) * 1000;
This equals 250,000, which is straight left-to-right math.
int o = 60 / i * 50 * 1000;
What's flying over my head here?
Thanks,
Nick
In Objective-C / performs integer division on integer arguments, so 4/5 is truncated to 0, 3/2 is truncated to 1, and so on. You probably want to cast some of your numbers to floating-point forms before performing division.
You're also running in to issues with precedence. In the expression
60 / (i * 50) * 1000
the term inside the parentheses is calculated first, so 60 is divided by 600 which produces the result 0. In
60 / i * 50 * 1000
the first operation is to divide 60 by 12 which gives the result 5 and then the multiplications are carried out.
An integer divided by an integer is an integer.
so 60/600 is not 0.1, it is 0.
Cast (or declare) some stuff as float instead.
It's doing integer math. 60 / (12 * 50) is 0.1, truncates to 0.
Should work if you force floating point and then cast back to an integer.
int o = (int)(60.0 / ((double) i / 50.0) * 1000.0;
Probably not really necessary to make everything a double.
Replace:
int o = (60 / (i * 50)) * 1000;
with:
int o = 1200/i;
By order of precedence, the operation:
60 / (12 * 50)
is performed before multiplying by 1000.
This value is less than 1 and is cast to an int, which truncates it to 0. And 0 times anything is 0.
Use a float or first multiply by 1000 to ensure you're not ending up with propagating a 0 in your calculations.
All the operations in your expression are performed in integer arithmetic, meaning that the fractional part of each intermediate result is truncated. This means that if you divide a smaller integer by a larger integer you will always get 0.
To get the result you want you must either make sure the operations are performed in a particular order, or you must use floats. For example the result of
int o = (60.0 / (i * 50.0)) * 1000.0;
should be o = 100.
I think you need to use float here instead of int. It will work the way you want! Will give you answer in decimals as well.

Objective-C Formatting CGFloat

Code
CGFloat a=3.45378;
I want change the result to
CGFloat a=3.45f; only 2 precision
I know how printf works. but I don't know how to do this just keep 2 precision.
To lose the extra precision, and round to the nearest two decimals, follow these steps:
Multiply your number by 100 : 345.378
Round your number to the nearest integer : 345
Divide your number by 100 : 3.45