Order of operations c# - c#

I'm struggling with understanding why the following returns this value. Any help would be appreciated.
int ans = 10, v1 = 5, v2 = 7, v3 = 18;
ans += v1 + 10 * (v2-- / 5) + v3 / v2;
Console.WriteLine(ans);// prints 28
My thinking would be brackets first, division, multiplication then addition. So the steps would be:
v1 + 10 * (v2-- / 5) + v3 / v2
(v2-- / 5)= 1.4, v2 is then set to 6.
v3 / v2 = 3
10 * (v2-- / 5) = 14
5 + (14) +(3) = 12
Therefore, (ans += 12) = 22?

v2-- / 5)= 1.4 and there is your problem. Integer division will never return a non integer value.
1/2 equals 0, not 0.5 and 7/5 equals 1, not 1.4.

Martin: Step 1. is incorrect because both variables are integers the result will be an integer, (v2-- / 5) = 1. To get the answer of 1.4 one would need to change the variables to type double.
"So you are effectively left with 10 += 5 + 10 * 1 + 3= 28"

Related

What does 1.e0 mean in the following code

What does 1.e0 mean in the following code
product *=
((1.e0-pow((double)2,i-32))*(1.e0-pow((double)2,i-32)))/(1.e0-pow((double)2,i-r));
It is c++ code, and how i can write 1.e0 in c#
<number>e<power> = <number> * 10^<power>
Where the power is a power of ten. Basically the number after e tells you how many zeroes you have to append if it is positive. Negative powers make the number move by one digit to the right.
Examples
1.2e-3 = 1.2 * 10^-3 = 1.2 * 0.001 = 0.0012
1.2e-2 = 1.2 * 10^-2 = 1.2 * 0.01 = 0.012
1.2e-1 = 1.2 * 10^-1 = 1.2 * 0.1 = 0.12
1.2e0 = 1.2 * 10^0 = 1.2 * 1 = 1.2
1.2e1 = 1.2 * 10^1 = 1.2 * 10 = 12
1.2e2 = 1.2 * 10^2 = 1.2 * 100 = 120
1.2e3 = 1.2 * 10^3 = 1.2 * 1000 = 1200
You can see this notation on calculators. When the result is too large and would not fit into the display otherwise, the calculator automatically switches to the exponential notation.
In C# you would write the formula like this:
product *= (1 - Math.Pow(2, i - 32)) * (1 - Math.Pow(2, i - 32)) /
(1 - Math.Pow(2, i - r));
The conversions to double happen automatically. One pair of parentheses is superfluous. One sub-expression occurs twice, you could write:
double temp = 1 - Math.Pow(2, i - 32);
product *= temp * temp / (1 - Math.Pow(2, i - r));
See:
- Math.Pow Method (Double, Double) (msdn)
Providing that pow is raising into power, C# code will be
product *= (1.0 - Math.Pow(2, i - 32)) *
(1.0 - Math.Pow(2, i - 32)) /
(1.0 - Math.Pow(2, i - r));
As you can see 1.e0 is just 1.0 - double representation of 1

c# rules about: a mod b, while a is bigger than b

I was examining a code about operator overloading, and I saw an interesting way of use of % to convert seconds to minutes if second variable is bigger than 59.
It seems while a<b (both int) a%b returns a, I havent read a rule about this before, I wanna learn why it returns a, is it about they are declared as integers, are there any more rules about %?
Thanks
% is the modulo operator. The modulo operation a % b returns the remainder z in the division
a / b = x, remainder z
In other words, it returns y in this equation:
x * b + y = a
*The second equation also shows why this works for fractional numbers too.**
Thus, the following examples (not complete) are true:
-5 % 4 = -1
-4 % 4 = 0
-3 % 4 = -3
...
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
...
101.4 % 100.3 = 1.1
In your example converting seconds to minutes and seconds, you probably read something like this:
int totalseconds = 72;
int minutes = totalseconds / 60; // == 1
int seconds = totalseconds % 60; // == 12
This is the same thing: the minutes are calculated as totalseconds / 60, which is an integral division that "rounds" to the lower integer for positive numbers, thus the result of 1. The seconds left are calculated as the remainder of 72 and 60.
You could also calculate the seconds like
int seconds = totalseconds - (minutes * 60)
In general, for any a and any b:
a / b = (SomeConstant * b) + RemainderOfb*
So if a = 2 and b = 5 means a < b then:
How many SomeConstant do you need to multiply b with, in order to get close to a? And once you get close, what is your remainder?
so if
a / b = (5 * 0) + 2
Means Remainder = 2 out of 5.
Then: a % b means the Remainder with respect to b, which is = 2.
And if a = 3 and b = 2 means a > b then:
If you remove all the "b"s from a, what is the Remainder? You can do
it the easy way: Subtract "a" from "b" till you can't subtract
anymore. Or:
a / b = SomeConstant * a (which is how many "a"s did you subtract) + Remainder
Substitute:
a / b = (1 * 2) + 1
Means Remainder = 1 out of the 2
Then a % b equals the Remainder with respect to a, which is = 1
a mod b is the remainder of a a / b, therefore if a < b AND a > -b the remainder is always a.
The following rules are valid for C#, but might differ in other languages, refer to Modulo operation page on Wikipedia for more information.
0 mod 3 = 0
1 mod 3 = 1
2 mod 3 = 2
3 mod 3 = 0
4 mod 3 = 1
-1 mod 3 = -1 // 2 in some languages
-2 mod 3 = -2 // 1 in some languages
-3 mod 3 = 0
-4 mod 3 = -1 // 2 in some languages
// if your language supports mod of floats
1.5 mod 3 = 1.5
5.5 mod 3 = 2.5
-1.5 mod 3 = -1.5 // 1.5 in some languages
-5.5 mod 3 = -2.5 // 0.5 in some languages

Wilson Score for 1-5 star rating in C#

I found this really well explained calculation but I really don't know if it's correct or not. I've seen a lot of posts on the subject I havent seen one calculate for 5
the most important part is this:
Stars Negative Positive Total
0 0 0 0
1 1 0 1
2 0.75 0.25 1
3 0.5 0.5 1
4 0.25 0.75 1
5 0 1 1
SET new.total = new.positive + new.negative,
new.stars = ROUND( (((new.positive / new.total) * 4) + 1) * 2, 0) / 2,
new.lower_bound = ((new.positive + 1.9208) / (new.positive + new.negative) - 1.96 * SQRT((new.positive * new.negative) / (new.positive + new.negative) + 0.9604) / (new.positive + new.negative)) / (1 + 3.8416 / (new.positive + new.negative))
which I converted to C# as the following
double posf = model.stars == 1 ? 0 :
model.stars == 2 ? 0.25 :
model.stars == 3 ? 0.5 :
model.stars == 4 ? 0.75 :
model.stars == 5 ? 1 : 0;
double negf = model.stars == 1 ? 1 :
model.stars == 2 ? 0.75 :
model.stars == 3 ? 0.5 :
model.stars == 4 ? 0.25 :
model.stars == 5 ? 0 : 0;
rating.positif += posf;
rating.negatif += negf;
rating.ratingcount += 1;
rating.ratingavg = Math.Round((((rating.positif / rating.ratingcount) * 4) + 1) * 2, 0) / 2;
rating.calcSort = ((rating.positif + 1.9208) / (rating.positif + rating.negatif) - 1.96 * Math.Sqrt((rating.positif * rating.negatif) / (rating.positif + rating.negatif) + 0.9604) / (rating.positif + rating.negatif)) / (1 + 3.8416 / (rating.positif + rating.negatif));
Can someone help me if this coding is correct conversion and if the sql version is actually correct.
You can store the lower-bound value as a double, there is no need to round it. The C# function can be turned into something like this:
private static double WilsonAlgorithm(double positive, double negative)
{
return ((positive + 1.9208) / (positive + negative) -
1.96 * Math.Sqrt((positive * negative) / (positive + negative) + 0.9604) /
(positive + negative)) / (1 + 3.8416 / (positive + negative));
}
(credits to: http://www.evanmiller.org/how-not-to-sort-by-average-rating.html, most of it came from the sql code on his page)
To convert from stars --> positive/negative, you can calculate them without over-using the ternary operator for readability.
// constants
const int maxRating = 5;
const int minRating = 1;
const double shareRating = 0.25;
// conversions
var stars = 5;
var positive = (stars - minRating) * shareRating;
var negative = (maxRating - stars) * shareRating;
// ..
// usage?
var lowerBoundRating = WilsonAlgorithm(totalPositive, totalNegative);

Get value between a range of two values from percentage

Let's say I have a range of two values:
5...........98
and let's assume the user position's the slider at value 40
Now I want to get the value from another range of values at the exact percentage position as from range 1
let's say the second range of values are 10.........80
int nRange1 = 98 - 5;
int nRange2 = 80 - 10;
int nValue1 = 40;
int nPercentOnRange1 = ((nValue1 - 5) / nRange1)*100;
Now I have to get the value from Range2 at the exact percentage as nPercentOnRange1, but I don't know how
First need to find % from first range and apply that % to new range.
Here is what I will do:
Range1(A to B) Selected value: c
Range2(E to F)
Range1 % = (C-A) / (B-A) * 100
Range 2 corresponding value = ((F - E) * (Range 1 %) / 100) + E
C#:
int Range1Min = 5, Range1Max=90, Range1SelectedValue = 40;
int Range2Min = 6, Range2Max=80;
decimal range1Percent = (Range1SelectedValue-Range1Min ) / (Range1Max-Range1Min) * 100.0
decimal range2NewValue = (Range2Max - Range2Min) * range1Percent / 100 + Range2Min;
Watch out for
int nPercentOnRange1 = ((nValue1 - 5)/ nRange1) * 100;
ending up as zero since nValue1 and nRange1 are integers. This might be better:
int nPercentOnRange1 = ((nValue1 - 5) * 100 / nRange1);
Then you can do
int nValue2 = 10 + nPercentOnRange1*nRange2/100;
The value you need is
x = 10 + nRange2 * nPercentOnRange1 / 100.0
Let me explain why. You need a number x such that
((x - 10) / nRange2) * 100.0 = nPercentOnRange1
Therefore, just solve for x.
((x - 10) / nRange2) * 100.0 = nPercentOnRange1 =>
((x - 10) / nRange2) = nPercentOnRange1 / 100.0 =>
x - 10 = nRange2 * nPercentOnRange1 / 100.0 =>
x = 10 + nRange2 * nPercentOnRange1 / 100.0
And note that this actually makes intuitive sense. We're saying take the percentage, scale that into the length of the second range (that's what nRange2 * nPercentOnRange1 / 100.0) is doing and then add that to the lower bound of the second range. Basically we are saying step nPercentOnRange1 percent into the second range. That's exactly what the formula is expressing.
Perhaps this will work:
nValue2 = nPercentage1 * nRange2 / 100 + 10

How do I round to the nearest 0.5?

I have to display ratings and for that, I need increments as follows:
Input
Rounded
1.0
1
1.1
1
1.2
1
1.3
1.5
1.4
1.5
1.5
1.5
1.6
1.5
1.7
1.5
1.8
2.0
1.9
2.0
2.0
2.0
2.1
2.0
and so on...
Is there a simple way to compute the required values?
Multiply your rating by 2, then round using Math.Round(rating, MidpointRounding.AwayFromZero), then divide that value by 2.
Math.Round(value * 2, MidpointRounding.AwayFromZero) / 2
Multiply by 2, round, then divide by 2
if you want nearest quarter, multiply by 4, divide by 4, etc
Here are a couple of methods I wrote that will always round up or down to any value.
public static Double RoundUpToNearest(Double passednumber, Double roundto)
{
// 105.5 up to nearest 1 = 106
// 105.5 up to nearest 10 = 110
// 105.5 up to nearest 7 = 112
// 105.5 up to nearest 100 = 200
// 105.5 up to nearest 0.2 = 105.6
// 105.5 up to nearest 0.3 = 105.6
//if no rounto then just pass original number back
if (roundto == 0)
{
return passednumber;
}
else
{
return Math.Ceiling(passednumber / roundto) * roundto;
}
}
public static Double RoundDownToNearest(Double passednumber, Double roundto)
{
// 105.5 down to nearest 1 = 105
// 105.5 down to nearest 10 = 100
// 105.5 down to nearest 7 = 105
// 105.5 down to nearest 100 = 100
// 105.5 down to nearest 0.2 = 105.4
// 105.5 down to nearest 0.3 = 105.3
//if no rounto then just pass original number back
if (roundto == 0)
{
return passednumber;
}
else
{
return Math.Floor(passednumber / roundto) * roundto;
}
}
There are several options. If performance is a concern, test them to see which works fastest in a large loop.
double Adjust(double input)
{
double whole = Math.Truncate(input);
double remainder = input - whole;
if (remainder < 0.3)
{
remainder = 0;
}
else if (remainder < 0.8)
{
remainder = 0.5;
}
else
{
remainder = 1;
}
return whole + remainder;
}
decimal d = // your number..
decimal t = d - Math.Floor(d);
if(t >= 0.3d && t <= 0.7d)
{
return Math.Floor(d) + 0.5d;
}
else if(t>0.7d)
return Math.Ceil(d);
return Math.Floor(d);
Sounds like you need to round to the nearest 0.5. I see no version of round in the C# API that does this (one version takes a number of decimal digits to round to, which isn't the same thing).
Assuming you only have to deal with integer numbers of tenths, it's sufficient to calculate round (num * 2) / 2. If you're using arbitrarily precise decimals, it gets trickier. Let's hope you don't.
These lines of code snap a float dx to nearest snap:
if (snap <= 1f)
dx = Mathf.Floor(dx) + (Mathf.Round((dx - Mathf.Floor(dx)) * (1f / snap)) * snap);
else
dx = Mathf.Round(dx / snap) * snap;
So if snap is 0.5, value gets rounded to nearest 0.5 value (1.37 goes to 1.5), if it is 0.02, value is rounded to nearest 0.02 ((1.37 goes to 1.38)). If snap is 3, value is rounded to nearest 3 (7.4 goes to 6, 7.6 goes to 9) etc... I use it to quickly snap objects on scene in unity because unity default snapping doesn't seem to work well for me.
Public Function Round(ByVal text As TextBox) As Integer
Dim r As String = Nothing
If text.TextLength > 3 Then
Dim Last3 As String = (text.Text.Substring(text.Text.Length - 3))
If Last3.Substring(0, 1) = "." Then
Dim dimcalvalue As String = Last3.Substring(Last3.Length - 2)
If Val(dimcalvalue) >= 50 Then
text.Text = Val(text.Text) - Val(Last3)
text.Text = Val(text.Text) + 1
ElseIf Val(dimcalvalue) < 50 Then
text.Text = Val(text.Text) - Val(Last3)
End If
End If
End If
Return r
End Function
This answer is taken from Rosdi Kasim's comment in the answer that John Rasch provided.
John's answer works but does have an overflow possibility.
Here is my version of Rosdi's code:
I also put it in an extension to make it easy to use. The extension is not necessary and could be used as a function without issue.
<Extension>
Public Function ToHalf(value As Decimal) As Decimal
Dim integerPart = Decimal.Truncate(value)
Dim fractionPart = value - Decimal.Truncate(integerPart)
Dim roundedFractionPart = Math.Round(fractionPart * 2, MidpointRounding.AwayFromZero) / 2
Dim newValue = integerPart + roundedFractionPart
Return newValue
End Function
The usage would then be:
Dim newValue = CDec(1.26).ToHalf
This would return 1.5
I had difficulty with this problem as well.
I code mainly in Actionscript 3.0 which is base coding for the Adobe Flash Platform, but there are simularities in the Languages:
The solution I came up with is the following:
//Code for Rounding to the nearest 0.05
var r:Number = Math.random() * 10; // NUMBER - Input Your Number here
var n:int = r * 10; // INTEGER - Shift Decimal 2 places to right
var f:int = Math.round(r * 10 - n) * 5;// INTEGER - Test 1 or 0 then convert to 5
var d:Number = (n + (f / 10)) / 10; // NUMBER - Re-assemble the number
trace("ORG No: " + r);
trace("NEW No: " + d);
Thats pretty much it.
Note the use of 'Numbers' and 'Integers' and the way they are processed.
Good Luck!

Categories