Precomputation of constants (Is there a performance difference?) [duplicate] - c#

This question already has answers here:
Does C# Compiler calculate math on constants?
(2 answers)
Closed 1 year ago.
Is the compiler 'smart enough' to precompute this, or will it have a performance impact?
const float num = 0.8660254f; // Sqrt(3) / 2
while(true)
{
float h = num * GetSomeNumber();
}
vs
while(true)
{
float h = (Sqrt(3) / 2 ) * GetSomeNumber();
}
vs
const float num = 1.7320508f; // Sqrt(3)
while(true)
{
float h = (num / 2) * GetSomeNumber();
}
And is there any reason to (not) precompute?

First, the compiler does not do any computation. Computation or execution of the code is a runtime thing. The compiler is smart enough to do multiple adjustments to the code for performance, but it does not have any idea about what method you are calling at runtime. So it won't know how your method Sqrt behaves at runtime. And hence, it will not be able to perform calculations beforehand during compilation.

Related

Dividing one smaller number with the bigger one doesn't work without special decleration c# [duplicate]

This question already has answers here:
Why do these division equations result in zero?
(10 answers)
Closed 2 years ago.
This:
float a = 2 / 4;
return a;
Will output as 0, while this:
float a = 2;
float b = 4;
float c = a / b;
return c;
Will give a correct output 0.5.
Why am I getting this result?
C# interprets 2 and 4 as plain integers, 2/4 is 0 using integer math (floor of 0.5).
Try using 2f and 4f instead to have floating point numbers. Refer to this documentation to see all possible number literals https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types#real-literals.
Code below works as expected:
public static void Main()
{
float a = 2f / 4f;
Console.WriteLine(a);
}
Because 2 and 4 are the type of integer.
Type type1 = 2.GetType();
Type type2 = 4.GetType();

Does Roslyn omit multiplication by 1 in cases where a value is known to be 1 at compile time?

Keeping in mind this similar question does C#/Roslyn omit multiplication by 1 in cases where a variable is hard coded to 1? The similar question's answers suggest Roslyn would convert var x = 5 * 1 to var x = 5at compile time, but I wonder if this holds true for a more complex example.
Example:
var baseAmount = 25.10M;
var multiplier = 1;
var total = baseAmount * multiplier; // does this become just "baseAmount"?
Ultimately I am trying to determine if adding * 1 or an equivalent will result in performance impacts at scale (code hit millions of times). Being explicit and verbose with the * 1 multiplication in this case would result in more readable, "self-commenting" code for people new to the codebase.
Looking at the disassembly of the following code:
public int test()
{
int baseAmount = 25;
var multiplier = 1;
var total = baseAmount * multiplier;
return total;
}
you can see that the imul is still there:
Replacing multiplier by the constant 1 removes the imul:
Changing the type of baseAmount from int to Decimal creates assembly code that is a bit more complex. With multiplier variable:
Without multiplier:
Looking at the assembly code, it seems that in both cases the multiply subroutine (next to the yellow arrow) is being called. So the compiler will not optimize the constant 1 in this case.

The result of calculation deviates after some digits [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
Result of calculation shown below should be equal to 0,007306897 (I referred from 2 books) . But when i check result from Watch 1, i see that result is equal to 0,007306882. I split the process into some parts. And the problem is occurring when c is calculating.
///Declarations
double sigma = 1.00000000;
double a,b,e,c;
a = (1 / Math.Sqrt(2 * Math.PI)); //calculated properly
c = -(i * i + j * j) / 2.00000000 * (sigma * sigma); //i and j are equal to -2
e = Math.E; //calculated properly
b = Math.Pow(e, c);
result=a * b;
Unfortunately the double type is not highly accurate. The link below shows that some numbers like 1.05 can not be stored accurately by the double type.
http://www.binaryconvert.com/convert_double.html
For normal usage it is usually accurate enough, if you need accuracy to the level you describe you probably need to use something like binary coded decimal. That will mean the normal math library won't work. You could try asking on some physics sites to see what they use when modelling complex systems to maintain accuracy.

Casting Results of Float Multiplication Produces Differing Results if the Float is First Saved to a Variable? [duplicate]

This question already has answers here:
C# Float expression: strange behavior when casting the result float to int
(8 answers)
Closed 6 years ago.
The code here is straight forward but I don't understand the results:
float percent = 0.69f;
int firstInt = (int)(percent*100f);
float tempFloat = percent*100f;
int secondInt = (int)tempFloat;
Debug.Log(firstInt + " " + secondInt);
Why is firstInt 68 but secondInt is 69?
It looks like the compiler has figured out the value of the
percent*100f
expression using double math, and optimized away the computation. This is not allowed when intermediate results are saved in a float variable.
Since .69 does not have anexact representation in float or in double, the two representations "land" on different sides of an int: double is slightly above, while float is slightly below the actual value of .69.

Simple division [duplicate]

This question already has answers here:
Why returns C# Convert.ToDouble(5/100) 0.0 and not 0.05
(7 answers)
Closed 9 years ago.
I must be doing something dumb:
float ans = (i/3);
So why when i = 7 is ans coming out at 2.0?
i is an int
It's because the / operator is performing an integer division if both operands are integers. You could do this:
float ans = (i / 3.0f);
You need to make one of the operands a float, otherwise the calculation is done with integers first (which always results in an integer), before converting the result to a float.
float ans = ((float) i) / 3;
It's doing integer division because i is an int and 3 is an int. Try this:
float ans = ((float)i/3.0f);
use float ans = (i / 3.0) or float ans = (i / 3f) or float ans = ((float)i / 3). / does an integer division if both sides are of type integer.
Very simple: in C#, int / int = int.
What you're looking for is:
float ans = ((float)i/3);
Otherwise you're taking two integers and dividing them to find the number of whole times the divisor goes in to the dividend. (As mentioned, an int/int=int regardless of the destination type. And, to the compiler, "3" is another integer (unless you specify it as 3.0f))
I am assuming that you have this in a loop of some sort. You could specify your i variable as a float instead.
for (float i = 0; i < 10; i++)
{
float ans = (i/3);
// statements
}
Just another solution.

Categories