Combining methods that are the same but take in different variables - c#

I have a method I use to take in a number and return the number in a notation format. I'm using doubles, floats, and ints in my code so I have three of the same methods written with only the intake variable different for them. Is there a way I can get the same effect with only 1 method?
To try and explain further. I want to create a method that accepts multiple variable types to it. Instead of the method calling for a double, I'd like it to accept a variable if it's an int, a float, or a double without casting. Right now I have 3 copies of the same method, each one accepting a different variable. I don't want to change all the variables I'm using to doubles for other reasons within the code.
Is there any way I can use one method that accepts all three variable types instead of having 3, each one accepting only one variable type.
public string NotationMethod(double x, string y)
{
if (x > 1000)
{
var exponent = Math.Floor(Math.Log10(Math.Abs(x)));
var mantissa = x / Math.Pow(10, exponent);
return mantissa.ToString("F2") + "e" + exponent;
}
return x.ToString("F0");
}
public string NotationMethod(int x, string y)
{
if (x > 1000)
{
var exponent = Math.Floor(Math.Log10(Math.Abs(x)));
var mantissa = x / Math.Pow(10, exponent);
return mantissa.ToString("F2") + "e" + exponent;
}
return x.ToString("F0");
}
public string NotationMethod(float x, string y)
{
if (x > 1000)
{
var exponent = Math.Floor(Math.Log10(Math.Abs(x)));
var mantissa = x / Math.Pow(10, exponent);
return mantissa.ToString("F2") + "e" + exponent;
}
return x.ToString("F0");
}

I noticed that you are using Math.Floor() in each case. I think you can simply use the method with first parameter Double data type. You will just need to convert the inputs to Double while calling the method.

Related

I can't imagine what the code should be to solve these kinds of problems

Given the limit of changing the value of variables, calculate the function according to the formula.
enter image description here
This function is a little more difficult to imagine, before that I made a regular function and I can not imagine the essence of complex functions.
class Program
{
static void Main(string[] args)
{
double x <= 1.4;
Console.WriteLine("Enter the value of x:");
double x = Convert.ToDouble(Console.ReadLine());
double result = Math.sqr(x)-(7 / x);
double result2 = a * Math.pow(3, x) + 7 * Math.Sqrt(x);
double result3 = Math.log10(x + 7);
Console.WriteLine("The result of the function is: ");
}
}
Probably you should create a method for this function like:
public double f(double x)
{
if (x < 0.7 || x > 2)
throw new ArgumentOutOfRangeException(...);
if (x < 1.4)
return ...
else if (x == 1.4)
return ...
else
return ...
}
And then you can call this method from your Main() method, where you can get the value of x from user input, as you already do, and call f(x) to calculate the result.
There is an issue though. Floating point numbers are represented only approximately. E.g. value 1.4 can be actually stored as 1.399999999998... or 1.40000000000013..., so x == 1.4 comparison is not really correct.
Usually floating point values are checked against some interval, something like Math.Abs(x - 1.4) < 1E-15.
Another option is to use decimal type (see Difference between decimal, float and double in .NET?)

Creating a power function in C# without using Math.Pow(x, y) [duplicate]

System.Numerics.BigInteger lets you multiply large integers together, but is there anything of the same type for floating point numbers? If not, is there a free library I can use?
//this but with floats
System.Numerics.BigInteger maxint = new BigInteger(int.MaxValue);
System.Numerics.BigInteger big = maxint * maxint * maxint;
System.Console.WriteLine(big);
Perhaps you're looking for BigRational? Microsoft released it under their BCL project on CodePlex. Not actually sure how or if it will fit your needs.
It keeps it as a rational number. You can get the a string with the decimal value either by casting or some multiplication.
var r = new BigRational(5000, 3768);
Console.WriteLine((decimal)r);
Console.WriteLine((double)r);
Or with a simple(ish) extension method like this:
public static class BigRationalExtensions
{
public static string ToDecimalString(this BigRational r, int precision)
{
var fraction = r.GetFractionPart();
// Case where the rational number is a whole number
if(fraction.Numerator == 0 && fraction.Denominator == 1)
{
return r.GetWholePart() + ".0";
}
var adjustedNumerator = (fraction.Numerator
* BigInteger.Pow(10, precision));
var decimalPlaces = adjustedNumerator / fraction.Denominator;
// Case where precision wasn't large enough.
if(decimalPlaces == 0)
{
return "0.0";
}
// Give it the capacity for around what we should need for
// the whole part and total precision
// (this is kinda sloppy, but does the trick)
var sb = new StringBuilder(precision + r.ToString().Length);
bool noMoreTrailingZeros = false;
for (int i = precision; i > 0; i--)
{
if(!noMoreTrailingZeros)
{
if ((decimalPlaces%10) == 0)
{
decimalPlaces = decimalPlaces/10;
continue;
}
noMoreTrailingZeros = true;
}
// Add the right most decimal to the string
sb.Insert(0, decimalPlaces%10);
decimalPlaces = decimalPlaces/10;
}
// Insert the whole part and decimal
sb.Insert(0, ".");
sb.Insert(0, r.GetWholePart());
return sb.ToString();
}
}
If it's out of the precision range of a decimal or double, they will be cast to their respective types with a value of 0.0. Also, casting to decimal, when the result is outside of its range, will cause an OverflowException to be thrown.
The extension method I wrote (which may not be the best way to calculate a fraction's decimal representation) will accurately convert it to a string, with unlimited precision. However, if the number is smaller than the precision requested, it will return 0.0, just like decimal or double would.
It should be considered what the implications would be if there were a BigFloat type.
BigFloat x = 1.0;
BigFloat y = 3.0;
BigFloat z = x / y;
The answer would be 0.333333333333333333333333333333333333333333333333333333 recurring. Forever. Infinite. Out of Memory Error.
It is easy to construct an infinite BigFloat.
However, if you are happy to stick to rational numbers, those express by the dividing one integer with another than you can use BigInteger to build a BigRational type that can provide arbitrary precision for representing any real number.
BigRational x = 1;
BigRational y = 3;
BigRational z = x / y;
This works and gives us this type:
You can just NuGet BigRational and you'll find many implementations, including once from Microsoft.

How to make a method taking unknown amount of values?

To explain the question on a simple example, let's say:
I have a method which takes the average of two numbers:
private double TakeAverage(double n1,double n2)
{
average = (number1 + number2) / 2.0000;
return average;
}
And I call it like:
textBox3.Text = (TakeAverage(number1, number2)).ToString();
Q1:
How to make this function able to run without calling it multiple times like:
TakeAverage(number1, number2, number3, number4, number5) // as wanted number of times...
Q2:how to make this function changing return value by number of values which it takes?
For example
Substring(1) //if it takes just one value, it returns all the chars after first char but
Substring(1,2)//if it takes two values, it returns 2 characters after first char
Check this out:
public double TakeAverage(params double[] numbers)
{
double result = 0.0;
if (numbers != null && numbers.Length > 0)
result = numbers.Average();
return result;
}
As params allows the client to send nothing, we should test whether numbers exists and has items.
Usage:
double average = TakeAverage(1, 2, 3, 4.4); //2.6
double anotherAverage = TakeAverage(); //0
double yetAnotherAverage = TakeAverage(null); //0
UPDATE
Based on your comments, I understand that you're looking for something that's called overload: you want that a given method behaves differently based on its arguments.
I'll give an example, you must modify it to suit your needs.
Let's pretend that, besides our original TakeAverage method, we want another one that does an average and multiplies it for a given number. It would be something like:
public double TakeAverage(int factor, params double[] numbers)
{
double result = 0.0;
if (numbers != null && numbers.Length > 0)
result = numbers.Average() * factor;
return result;
}
Usage:
double average = TakeAverage(1.0, 2, 3, 4.4); //2.6
double notAnAverage = TakeAverage(1, 2, 3, 4.4); //3.1333...
Note that I had to explicitly say that the first number is a double (1.0), otherwise it would fall on the second overload and multiply it.
There is the params-keyword where you can say that you take a not-specified amount of arguments.
From MSDN
The params keyword lets you specify a method parameter that takes a variable number of arguments.
You can send a comma-separated list of arguments of the type specified in the parameter declaration, or an array of arguments of the specified type. You also can send no arguments.
No additional parameters are permitted after the params keyword in a method declaration, and only one params keyword is permitted in a method declaration.
Example:
private double TakeAverage(params double[] numbers)
{
double average = 0.0;
if(numbers != null && numbers.Length > 0){
foreach(double d in numbers)
average += d;
average /= numbers.Length;
}
return average;
}
In response to your substring function question.
If you specify one argument, sub string(5) for example, it will return all the characters AFTER the 5th character in the string.
if I have the string "elephant", it would return "ant".
If I add a second argument to the function, it will start at the first given argument, as above, and go on x amount of characters before stopping.
if we use the above example string, "elephant" and do sub string(5,1) it would return "a".
(a good way to work this out is to add both numbers, that will be the last character in your string!)
What I'm asking it to do is create a new string going from the 5th character in the given string, and for my new string to be 1 character long.
This is because the string class has overloaded the sub-string method.
See here : http://msdn.microsoft.com/en-us/library/system.string.substring(v=vs.71).aspx

Is there a BigFloat class in C#?

System.Numerics.BigInteger lets you multiply large integers together, but is there anything of the same type for floating point numbers? If not, is there a free library I can use?
//this but with floats
System.Numerics.BigInteger maxint = new BigInteger(int.MaxValue);
System.Numerics.BigInteger big = maxint * maxint * maxint;
System.Console.WriteLine(big);
Perhaps you're looking for BigRational? Microsoft released it under their BCL project on CodePlex. Not actually sure how or if it will fit your needs.
It keeps it as a rational number. You can get the a string with the decimal value either by casting or some multiplication.
var r = new BigRational(5000, 3768);
Console.WriteLine((decimal)r);
Console.WriteLine((double)r);
Or with a simple(ish) extension method like this:
public static class BigRationalExtensions
{
public static string ToDecimalString(this BigRational r, int precision)
{
var fraction = r.GetFractionPart();
// Case where the rational number is a whole number
if(fraction.Numerator == 0 && fraction.Denominator == 1)
{
return r.GetWholePart() + ".0";
}
var adjustedNumerator = (fraction.Numerator
* BigInteger.Pow(10, precision));
var decimalPlaces = adjustedNumerator / fraction.Denominator;
// Case where precision wasn't large enough.
if(decimalPlaces == 0)
{
return "0.0";
}
// Give it the capacity for around what we should need for
// the whole part and total precision
// (this is kinda sloppy, but does the trick)
var sb = new StringBuilder(precision + r.ToString().Length);
bool noMoreTrailingZeros = false;
for (int i = precision; i > 0; i--)
{
if(!noMoreTrailingZeros)
{
if ((decimalPlaces%10) == 0)
{
decimalPlaces = decimalPlaces/10;
continue;
}
noMoreTrailingZeros = true;
}
// Add the right most decimal to the string
sb.Insert(0, decimalPlaces%10);
decimalPlaces = decimalPlaces/10;
}
// Insert the whole part and decimal
sb.Insert(0, ".");
sb.Insert(0, r.GetWholePart());
return sb.ToString();
}
}
If it's out of the precision range of a decimal or double, they will be cast to their respective types with a value of 0.0. Also, casting to decimal, when the result is outside of its range, will cause an OverflowException to be thrown.
The extension method I wrote (which may not be the best way to calculate a fraction's decimal representation) will accurately convert it to a string, with unlimited precision. However, if the number is smaller than the precision requested, it will return 0.0, just like decimal or double would.
It should be considered what the implications would be if there were a BigFloat type.
BigFloat x = 1.0;
BigFloat y = 3.0;
BigFloat z = x / y;
The answer would be 0.333333333333333333333333333333333333333333333333333333 recurring. Forever. Infinite. Out of Memory Error.
It is easy to construct an infinite BigFloat.
However, if you are happy to stick to rational numbers, those express by the dividing one integer with another than you can use BigInteger to build a BigRational type that can provide arbitrary precision for representing any real number.
BigRational x = 1;
BigRational y = 3;
BigRational z = x / y;
This works and gives us this type:
You can just NuGet BigRational and you'll find many implementations, including once from Microsoft.

Truncate number of digit of double value in C#

How can i truncate the leading digit of double value in C#,I have tried Math.Round(doublevalue,2) but not giving the require result. and i didn't find any other method in Math class.
For example i have value 12.123456789 and i only need 12.12.
EDIT: It's been pointed out that these approaches round the value instead of truncating. It's hard to genuinely truncate a double value because it's not really in the right base... but truncating a decimal value is more feasible.
You should use an appropriate format string, either custom or standard, e.g.
string x = d.ToString("0.00");
or
string x = d.ToString("F2");
It's worth being aware that a double value itself doesn't "know" how many decimal places it has. It's only when you convert it to a string that it really makes sense to do so. Using Math.Round will get the closest double value to x.xx00000 (if you see what I mean) but it almost certainly won't be the exact value x.xx00000 due to the way binary floating point types work.
If you need this for anything other than string formatting, you should consider using decimal instead. What does the value actually represent?
I have articles on binary floating point and decimal floating point in .NET which you may find useful.
What have you tried? It works as expected for me:
double original = 12.123456789;
double truncated = Math.Truncate(original * 100) / 100;
Console.WriteLine(truncated); // displays 12.12
double original = 12.123456789;
double truncated = Truncate(original, 2);
Console.WriteLine(truncated.ToString());
// or
// Console.WriteLine(truncated.ToString("0.00"));
// or
// Console.WriteLine(Truncate(original, 2).ToString("0.00"));
public static double Truncate(double value, int precision)
{
return Math.Truncate(value * Math.Pow(10, precision)) / Math.Pow(10, precision);
}
How about:
double num = 12.12890;
double truncatedNum = ((int)(num * 100))/100.00;
This could work (although not tested):
public double RoundDown(this double value, int digits)
{
int factor = Math.Pow(10,digits);
return Math.Truncate(value * factor) / factor;
}
Then you simply use it like this:
double rounded = number.RoundDown(2);
This code....
double x = 12.123456789;
Console.WriteLine(x);
x = Math.Round(x, 2);
Console.WriteLine(x);
Returns this....
12.123456789
12.12
What is your desired result that is different?
If you want to keep the value as a double, and just strip of any digits after the second decimal place and not actually round the number then you can simply subtract 0.005 from your number so that round will then work. For example.
double x = 98.7654321;
Console.WriteLine(x);
double y = Math.Round(x - 0.005, 2);
Console.WriteLine(y);
Produces this...
98.7654321
98.76
There are a lot of answers using Math.Truncate(double).
However, the approach using Math.Truncate(double) can lead to incorrect results.
For instance, it will return 5.01 truncating 5.02, because multiplying of double values doesn't work precisely and 5.02*100=501.99999999999994
If you really need this precision, consider, converting to Decimal before truncating.
public static double Truncate(double value, int precision)
{
decimal power = (decimal)Math.Pow(10, precision);
return (double)(Math.Truncate((decimal)value * power) / power);
}
Still, this approach is ~10 times slower.
I'm sure there's something more .netty out there but why not just:-
double truncVal = Math.Truncate(val * 100) / 100;
double remainder = val-truncVal;
If you are looking to have two points after the decimal without rounding the number, the following should work
string doubleString = doublevalue.ToString("0.0000"); //To ensure we have a sufficiently lengthed string to avoid index issues
Console.Writeline(doubleString
.Substring(0, (doubleString.IndexOf(".") +1) +2));
The second parameter of substring is the count, and IndexOf returns to zero-based index, so we have to add one to that before we add the 2 decimal values.
This answer is assuming that the value should NOT be rounded
For vb.net use this extension:
Imports System.Runtime.CompilerServices
Module DoubleExtensions
<Extension()>
Public Function Truncate(dValue As Double, digits As Integer)
Dim factor As Integer
factor = Math.Pow(10, digits)
Return Math.Truncate(dValue * factor) / factor
End Function
End Module
I use a little formatting class that I put together which can add gaps and all sorts.
Here is one of the methods that takes in a decimal and return different amounts of decimal places based on the decimal display setting in the app
public decimal DisplayDecimalFormatting(decimal input, bool valueIsWeightElseMoney)
{
string inputString = input.ToString();
if (valueIsWeightElseMoney)
{
int appDisplayDecimalCount = Program.SettingsGlobal.DisplayDecimalPlacesCount;
if (appDisplayDecimalCount == 3)//0.000
{
inputString = String.Format("{0:#,##0.##0}", input, displayCulture);
}
else if (appDisplayDecimalCount == 2)//0.00
{
inputString = String.Format("{0:#,##0.#0}", input, displayCulture);
}
else if (appDisplayDecimalCount == 1)//0.0
{
inputString = String.Format("{0:#,##0.0}", input, displayCulture);
}
else//appDisplayDecimalCount 0 //0
{
inputString = String.Format("{0:#,##0}", input, displayCulture);
}
}
else
{
inputString = String.Format("{0:#,##0.#0}", input, displayCulture);
}
//Check if worked and return if worked, else return 0
bool itWorked = false;
decimal returnDec = 0.00m;
itWorked = decimal.TryParse(inputString, out returnDec);
if (itWorked)
{
return returnDec;
}
else
{
return 0.00m;
}
}
object number = 12.123345534;
string.Format({"0:00"},number.ToString());

Categories

Resources