Database calculations are wrong - sql-server

Here is what I'm setting:
result = price / (case when tax = 0 then #tax1h / 100 else #tax2 / 100 end + 1)
These are the values:
price = 17.5
tax = 1
tax2 = 6
17.5 / (6 / 100 + 1) = 16.5
And this returns 17.5 Why is this happening and how to solve it?

Integer division:
select (6 / 100 + 1)
The result of the above is 1.
However, the result of:
select (6 / 100.0 + 1)
Is 1.06.

Related

C arithmetic precedence

I stumbled upon a question about arithmetic precedence in a test and I cannot wrap my head at all around its answer.
float x = 5 % 3 * + 2 - 4.5 / 5 * 2 + 2;
My "understanding" right now is that multiplication must take place first before division and modulus, yet when I try using that approach, the answer is 6.55 instead of 4.20. I tried playing around with the expression (adding brackets here and there), and it turns out that 5 % 3 takes place first before everything else. I just don't understand why since, according to the precedence table I was provided, that shouldn't be the case. Could someone clear this up for me?
Please refer to the documentation here.
The precedence of multiplication, division and remainder operators are higher than those of sum and subtraction.
When multiplication, division or remainder operators go one after another, then they are left-associated, meaning they will be executed one by one in the given order.
In your example 5 % 3 will be performed first, then the multiplication (by whatever number there is), then the division 4.5 / 5, then multiplication of the result by 2, and only after all that will the sum and subtraction be performed.
Your C code:
x = 5 % 3 * + 2 - 4.5 / 5 * 2 + 2;
First, unary plus and unary minus has the highest precedence:
x = 5 % 3 * (+ 2) - 4.5 / 5 * 2 + 2;
Second, multiplication, division, and remainder have the same precedence, associated from left to right:
x = ((5 % 3) * (+ 2)) - ((4.5 / 5) * 2) + 2;
Last, addition and subtraction have the same precedence, associated from left to right:
x = ((((5 % 3) * (+ 2)) - ((4.5 / 5) * 2)) + 2);
Now we evaluate the expression:
x = (((2 * (+ 2)) - ((4.5 / 5) * 2)) + 2);
x = (((2 * 2) - ((4.5 / 5) * 2)) + 2);
x = ((4 - ((4.5 / 5) * 2)) + 2);
x = ((4 - (0.9 * 2)) + 2);
x = ((4 - 1.8) + 2);
x = (2.2 + 2);
x = 4.2;
you can refers this link for more detail
http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm

Round 916.984800 to 916.99

Is it possible to round 916.984800 to 916.99 in SQL Server?
I've tried as below but I don't want '+ 0.1' as my solution.
Round((((424.53 - 0) * 36) * (6 / 100)),2) + .01 as [Amount]
or
Round((((424.53 - 0) * 36) * (0.06)),2) + .01 as [Amount]
Thanks
This produces expected output:
SELECT CEILING((424.53 - 0) * 36 * 0.06 * 100) / 100 AS [Amount]
Amount
----------
916.990000
What happens?
SELECT (424.53 - 0) * 36 * 0.06 * 100
This returns 91698.4800, CEILING returns the smallest integer greater than, or equal to, the specified numeric expression, in your case 91699, and later I just divide it by 100, which brings expected result.

Divide by zero exception of average of columns in a row in SQL Server

I have some code made for calculate the average of a row in a table. The problem is now that the sum of MinTwee, MinEen, nul, PlusEen and PlusTwee (are column names) is equal to zero, it gives me a divide by zero exception (what is normal of course). How can you protect it that it given't that? I will that if the sum is equal to zero the average is also equal to zero of that row. I use SQL server 2014.
select top 5
id, mintwee, mineen, nul, pluseen, plustwee, naam
from
topic
where
CategorieID = 7 and verwijderd = 0
order by
round(cast((mintwee * (-2) + mineen * (-1) + nul * 0 + pluseen * 1 + PlusTwee * 2) as float) / (MinTwee + MinEen + nul + PlusEen + PlusTwee), 1) desc, creatie desc
You can test for 0 value with a case when
select top 5 id, mintwee, mineen, nul, pluseen, plustwee, naam
from topic
where CategorieID = 7 and verwijderd = 0
order by
case when (MinTwee + MinEen + nul + PlusEen + PlusTwee) = 0 then creatie
else
round(cast((mintwee * (-2) + mineen * (-1) + nul * 0 + pluseen * 1 + PlusTwee * 2) as float) / (MinTwee + MinEen + nul + PlusEen + PlusTwee), 1)
end
desc,
creatie desc
I think the easiest way to avoid an error is nullif():
order by
coalesce(round(cast((mintwee * (-2) + mineen * (-1) + nul * 0 + pluseen * 1 + PlusTwee * 2) as float) /
nullif(MinTwee + MinEen + nul + PlusEen + PlusTwee, 0), 1), 0) desc,
creatie desc

Why is the value of j in "j= 2 * 3 / 4 + 2.0 / 5 + 8/5;" set to 2 and not 3?

In this program, j is assigned the value 2
j = 2 * 3 / 4 + 2.0 / 5 + 8/5;
but if same expression is calculated with calculator it will come be 3.5 so in integer it will become 3.
I want to ask why j is assigned to 2? What am I missing?
C program:
#include <stdio.h>
int main()
{
int i,j,k=0;
int line=0;
j = 2 * 3 / 4 + 2.0 / 5 + 8/5;
printf(" %d --------- \n", j);
k -= --j;
printf(" %d --------- \n", k);
for(i=0;i<5;i++)
{
switch(i+k)
{
case 1:
case 2:
printf("\n %d", i+k);
line++;
case 3:
printf("\n %d", i+k);
line++;
default:
printf("\n %d", i+k);
line++;
}
}
printf("\n %d", line);
return 0;
}
Output is:
2 ---------
-1 ---------
-1
0
1
1
1
2
2
2
3
3
10
Something like:
j= 2 * 3 / 4 + 2.0 / 5 + 8/5;
2 * 3 / 4 Produce 1 -> it's integer
2.0 / 5 Produce 0.4 -> float
8/5 Produce -> 1.6 -> but in integer 1
Sum: 1 + 0.4 + 1 -> 2.4 -> converted to integer it's 2.
You have to typecast or say in other way it's float, 2 integers at dividing, produce integer.
j= 2 * 3 / 4 + 2.0 / 5 + 8/5;
2 * 3 / 4 and 8 / 5 are integer divisions.
Use:
2 * 3 / 4.0 and 8 / 5.0 to have floating point divisions.
Let's analyse this step by step:
2*3/4 + 2.0 /5 + 8/5 // 8/5 gives 1, not 1.6 because it's integer division
6/4 + 0.4 + 1 // 2.0/5 is float division, so decimal place is left
1 + 0.4 + 1 // 6/4 gives 1, not 1.5 because it's integer division
2.4
2 //part after decimal point removed since j is int
2 * 3 / 4 + 2.0 / 5 + 8/5
* and / are calculated before +and - which leasd to 3 1st steps:
integer calculation (as all operants as integer)
2 * 3 / 4 = 6 / 4 = 1
floating point calculation (as at least one operant is floating point)
2.0 / 5 = 2. / 5. = 0.4
integer calculation (as all operants as integer)
8 / 5 = 1
Finally the result from (1. and 2. and 3.) is:
floating point calculation (as at least one operant is floating point)
1. + 0.4 + 1. = 2.4
assigned to an integer (truncation downwards)
int j = 2.4
results in j being equal to 2.

Understanding CEILING macro use cases

I've found the following macro in a utility header in our codebase:
#define CEILING(x,y) (((x) + (y) - 1) / (y))
Which (with help from this answer) I've parsed as:
// Return the smallest multiple N of y such that:
// x <= y * N
But, no matter how much I stare at how this macro is used in our codebase, I can't understand the value of such an operation. None of the usages are commented, which seems to indicate it is something obvious.
Can anyone offer an English explanation of a use-case for this macro? It's probably blindingly obvious, I just can't see it...
Say you want to allocate memory in chunks (think: cache lines, disk sectors); how much memory will it take to hold an integral number of chunks that will contain the X bytes? If the chuck size is Y, then the answer is: CEILING(X,Y)
When you use an integer division in C like this
y = a / b
you get a result of division rounded towards zero, i.e. 5 / 2 == 2, -5 / 2 == -2. Sometimes it's desirable to round it another way so that 5 / 2 == 3, for example, if you want to take minimal integer array size to hold n bytes, you would want n / sizeof(int) rounded up, because you want space to hold that extra bytes.
So this macro does exactly this: CEILING(5,2) == 3, but note that it works for positive y only, so be careful.
Hmm... English example... You can only buy bananas in bunches of 5. You have 47 people who want a banana. How many bunches do you need? Answer = CEILING(47,5) = ((47 + 5) - 1) / 5 = 51 / 5 = 10 (dropping the remainder - integer division).
Let's try some test values
CEILING(6, 3) = (6 + 3 -1) / 3 = 8 / 3 = 2 // integer division
CEILING(7, 3) = (7 + 3 -1) / 3 = 9 / 3 = 3
CEILING(8, 3) = (8 + 3 -1) / 3 = 10 / 3 = 3
CEILING(9, 3) = (9 + 3 -1) / 3 = 11 / 3 = 3
CEILING(10, 3) = (9 + 3 -1) / 3 = 12 / 3 = 4
As you see, the result of the macro is an integer, the smallest possible z which satisfies: z * y >= x.
We can try with symbolics, as well:
CEILING(k*y, y) = (k*y + y -1) / y = ((k+1)*y - 1) / y = k
CEILING(k*y + 1, y) = ((k*y + 1) + y -1) / y = ((k+1)*y) / y = k + 1
CEILING(k*y + 2, y) = ((k*y + 2) + y -1) / y = ((k+1)*y + 1) / y = k + 1
....
CEILING(k*y + y - 1, y) = ((k*y + y - 1) + y -1) / y = ((k+1)*y + y - 2) / y = k + 1
CEILING(k*y + y, y) = ((k*y + y) + y -1) / y = ((k+1)*y + y - 1) / y = k + 1
CEILING(k*y + y + 1, y) = ((k*y + y + 1) + y -1) / y = ((k+2)*y) / y = k + 2
You canuse this to allocate memory with a size multiple of a constant, to determine how many tiles are needed to fill a screen, etc.
Watch out, though. This works only for positive y.
Hope it helps.
CEILING(x,y) gives you, assuming y > 0, the ceiling of x/y (mathematical division). One use case for that would be a prime sieve starting at an offset x, where you'd mark all multiples of the prime y in the sieve range as composites.

Resources