Context: .Net, C#
I want to print a complex number made from two doubles. The sign needs to show on the imaginary part. I'd like to use the default double formatting for each part to minimize the number of characters.
I tried using String.Format("{0:+G;-G}{1:+G;-G}j", real, imaginary) but this ended up printing: "+G-Gj". Not quite what I wanted.
Is there any way to do this using the G specifier or do I need to do a custom format which would sacrifice auto-switching the exponent, e.g. {1:+#.######e###;-#.######e###}j"
it is unusual, but you can easily override your Complex class's ToString method. For example:
class Complex {
private double mReal, mImaginary;
public Complex(double real, double imag) { mReal = real; mImaginary = imag; }
private string WithSign(double value) {
return value >= 0 ? "+" + value.ToString("N") : value.ToString("N");
}
public override string ToString() {
return WithSign(mReal) + "i" + WithSign(mImaginary);
}
}
Sample usage:
static void Main(string[] args) {
var c = new Complex(1, -1);
Console.WriteLine(c.ToString());
Console.ReadLine();
}
Output:
+1.00i-1.00
Tweak as necessary.
This is probably way off...
How about something like:
String.Format("+{0:g}-{0:g}{1:g}-{1:g}j", real, imaginary)
Related
Every time we need a high decimal-precision, we use decimals to do the calculations. Is there any way to check if the precision did suffice for the calculation?
I would like to make the following code throw an exception:
decimal almostMax = Decimal.MaxValue - 1;
decimal x = almostMax + 0.1m; // This should create an exception, since x equals almostMax.
Assert.AreEqual(x, almostMax); // This does NOT fail.
It doesn't really matter in real code, but it would be nice to be safe.
This extension method should help. It reverses the operation and checks if the input arguments can be calculated correctly from the result. If that's not the case then the operation caused precision loss.
public static decimal Add(this decimal a, decimal b)
{
var result = a + b;
if (result - a != b || result - b != a)
throw new InvalidOperationException("Precision loss!");
return result;
}
Working example: https://dotnetfiddle.net/vx6UYY
If you want to use the regular operators like + etc, you have to go with Philipp Schmid's solution and implement the operators on your own decimal type.
You could make a SaveDecimal class and overload the + operator
https://msdn.microsoft.com/en-us/library/aa288467%28v=vs.71%29.aspx
public class SafeDecimal
{
private decimal DecValue;
public SafeDecimal(decimal Value)
{
DecValue = Value;
}
public decimal GetValue()
{
return DecValue;
}
public static SafeDecimal operator +(SafeDecimal A, SafeDecimal B)
{
decimal almostMax = Decimal.MaxValue - 1;
checked
{
if (almostMax <= A.GetValue() + B.GetValue())
throw new Exception("----scary error message----");
}
return new SafeDecimal(A.GetValue() + B.GetValue());
}
}
I'm using the MiscUtils library (thanks Marc G. and Jon S.) and am trying to add a generic Sqrt function to it. The problem can be easily reproduced with this:
class N<T>
{
public N(T value)
{
Value = value;
}
public readonly T Value;
public static implicit operator T(N<T> n)
{
return n.Value;
}
public static implicit operator N<T>(T value)
{
return new N<T>(value);
}
public static T operator /(N<T> lhs, T rhs)
{
// Operator.Divide is essentially a wrapper around
// System.Linq.Expressions.Expression.Divide
return Operator.Divide(lhs.Value, rhs);
}
}
// fails with: No coercion operator is defined
// between types 'System.Double' and 'N`1[System.Single]'.
var n = new Numeric<float>(1f);
var x = Operator.DivideAlternative(n, 1.0);
// this works as the N<T> is first converted to a
// float via the implicit conversion operator
var result = n / 1.0;
Now, I realize why this is happening, but I have not yet been able to think of a way around it. For reference, here is the current Sqrt implementation. I have little experience building expression trees.
public static double Sqrt<T>(T value)
{
double oldGuess = -1;
double guess = 1;
while(Abs(guess - oldGuess) > 1)
{
oldGuess = guess;
// the first evaluated call to DivideAlternative throws
guess = Operator.Divide(
Operator.AddAlternative(guess,
Operator.DivideAlternative(value, guess)),
2);
}
return guess;
}
EDIT: Ok, so I solved this on my own, but in an attempt to keep the question as simple as possible I apparently went too far and spent far too much time answering questions from confused people trying to help.
So, this is the problem in its entirety.
I two classes; one that performs transformations and another which performs statistical analysis of image data (pixels). Let's focus on the latter as the problem is the same:
abstract class ImageStatistics
{
private readonly object _pixels;
public ImageStatistics(object pixelArray)
{
Pixels = pixelArray;
}
// calculate the standard deviation of pixel values
public double CalcStdDev();
}
The array of pixels can be any numeric type. In practice, it will be either float, int, ushort, or byte. Now, because generics cannot do things like this:
public T Add<T>(T lhs, T rhs)
{
return lhs + rhs; // oops, no operator + for T
}
I cannot perform any sort of statistical analyses on the pixel values themselves without casting to the proper array type. So, I need to have N sub-classes of ImageProcessor to support N pixel types.
Well, that sucks. I would love to just have a generic ImageProcessor<T> class which has a T[] of pixel data. So, I looked into the MiscUtils library which would allow just this.
Math.Sqrt needs a double, so why not just provide it with one?
public static double Sqrt<T>(T value)
{
return Math.Sqrt(Convert.ToDouble(value));
}
You might also consider casting to dynamic.
public static double Sqrt<T>(T value)
{
return Math.Sqrt((dynamic) value);
}
This technique can also be used for operators like addition:
public static T Add<T>(T a, T b)
{
return (dynamic) a + (dynamic) b;
}
Console application creating array of objects (unknown types) and calculating square route (double)
using System;
namespace GenericSqrt
{
class Program
{
static void Main(string[] args)
{
var array = new object[] { "2", null, 4.1f, 4.444D, "11.3", 0, "Text", new DateTime(1, 1, 1) };
foreach (var value in array)
{
try
{
Console.WriteLine(Sqrt(value));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.ReadLine();
}
private static double Sqrt(object value)
{
double converterValue = Convert.ToDouble(value);
return Math.Sqrt(converterValue);
}
}
}
Output looks like this:
1.4142135623731
0
2.02484564958235
2.10807969488822
3.36154726279432
0
Input string was not in a correct format.
Invalid cast from 'DateTime' to 'Double'.
If type is indeed any of number types, as you stated, there is no problem to solve.
Let me preface this by saying it probably isn't worth the effort, considering how this code would need to be maintained. I wrote this in about 10 minutes, so don't expect anything too spectacular.
// You'll need this
public interface ISquareRootHelper
{
double Sqrt<T>(T value)
where T : struct;
}
class Program
{
private static ISquareRootHelper helper;
// Build the helper
public static void BuildSqrtHelper()
{
// Let's use a guid for the assembly name, because guid!
var assemblyName = new AssemblyName(Guid.NewGuid().ToString());
// Blah, blah, boiler-plate dynamicXXX stuff
var dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var dynamicModule = dynamicAssembly.DefineDynamicModule(assemblyName.Name);
var dynamicType = dynamicModule.DefineType("SquareRootHelper");
// Let's create our generic square root method in our dynamic type
var sqrtMethod = dynamicType.DefineMethod("Sqrt", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual);
sqrtMethod.SetReturnType(typeof(double));
// Well, I guess here is where we actually make the method generic
var genericParam = sqrtMethod.DefineGenericParameters(new[] {"T"});
genericParam[0].SetGenericParameterAttributes(GenericParameterAttributes.NotNullableValueTypeConstraint);
// Add a generic parameter, and set it to override our interface method
sqrtMethod.SetParameters(genericParam);
dynamicType.DefineMethodOverride(sqrtMethod, typeof(ISquareRootHelper).GetMethod("Sqrt"));
// Magic sauce!
var ilGenerator = sqrtMethod.GetILGenerator();
// Math.Sqrt((double)value);
ilGenerator.Emit(OpCodes.Ldarg_1); // arg_0 is this*
ilGenerator.Emit(OpCodes.Conv_R8);
var mathSqrtMethodInfo = typeof(Math).GetMethod("Sqrt");
ilGenerator.EmitCall(OpCodes.Call, mathSqrtMethodInfo, null);
ilGenerator.Emit(OpCodes.Ret);
// Since we're overriding the interface method, we need to have the type
// implement the interface
dynamicType.AddInterfaceImplementation(typeof(ISquareRootHelper));
// Create an instance of the class
var sqrtHelperType = dynamicType.CreateType();
helper = (ISquareRootHelper)Activator.CreateInstance(sqrtHelperType);
}
public static void Main(string[] args)
{
BuildSqrtHelper();
Console.WriteLine(helper.Sqrt((short)64)); // Works!
Console.WriteLine(helper.Sqrt((ushort)64)); // Works!
Console.WriteLine(helper.Sqrt((int)64)); // Works!
Console.WriteLine(helper.Sqrt((uint)64)); // Works*!
Console.WriteLine(helper.Sqrt((byte)64)); // Works!
Console.WriteLine(helper.Sqrt((sbyte)64)); // Works!
Console.WriteLine(helper.Sqrt((float)64)); // Works!
Console.WriteLine(helper.Sqrt((double)64)); // Works!
Console.WriteLine(helper.Sqrt((long)64)); // Works!
Console.WriteLine(helper.Sqrt((ulong)64)); // Works*!
// Let's try non-primitives!
Console.WriteLine(helper.Sqrt(DateTime.Now)); // Doesn't fail, but doesn't actually work
Console.WriteLine(helper.Sqrt(Guid.NewGuid())); // InvalidProgramException!
}
}
Anyway, I guess this proves it can be done. Just make sure when you use it, you only pass in primitive types, otherwise all fail will break loose. Actually, it will only throw an exception when you pass in a struct that is a greater size that 8 bytes, since that will unbalance the stack. You can't do a check like sizeof(T) in the method though, because it would fail during the JITing process.
Also, there are some *s next to some of the types up there. There is some extra logic done by the compiler and/or Math.Sqrt when you pass in unsigned numbers vs signed numbers, and how this related to negative numbers. For example:
Console.WriteLine(Math.Sqrt(unchecked((uint)-2))); // 65535.9999847412
Console.WriteLine(helper.Sqrt(unchecked((uint)-2))); // NaN :(
You could improve it and checks above to catch that, though. Also, I don't recommend this solution, especially if you're not comfortable with IL. Plus, this is probably more verbose and complicated than just writing a bunch of different methods to handle the operations you want.
This works, but it's a bit ugly:
public static implicit operator Numeric<T>(double value)
{
return new Numeric<T>((T)Convert.ChangeType(value, typeof(T)));
}
public static implicit operator double(Numeric<T> n)
{
return Convert.ToDouble(n.Value);
}
It will have to be repeated for each supported type, which makes this a lot less generic. I slapped an IConvertible constraint on there for good measure. If anyone has a better solution I'm all ears.
I'm playing around with a very simple program to take an array of doubles and return the standard deviation. This part worked but I wanted to make the code more reusable. I would like to make it so the method can accept a parameter of any type that could be considered numeric and return the standard deviation instead of hardcoding a double type (like I initially did in this program). How does one go about this and what is the proper term for it?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
double[] avg = { 3.4, 55.6, 10.0, 4.5, 2, 2 };
double x = avg.Average();
//first round of testing
Console.WriteLine("The average of the first array is below ");
Console.WriteLine(x);
Console.WriteLine("below should be the standard deviation!");
Console.WriteLine(CalculateStandardDeviation(avg));
Console.ReadLine();
int[] intAvg = { 4, 3, 5, 6, 2 };
double secondAvg = intAvg.Average();
Console.WriteLine("The average of the second array is below ");
Console.WriteLine(secondAvg);
//this is where the error is happening
//CalculateStandardDeviation(secondAvg);
}
//this is where I tried to make the query more reusable
public static double CalculateStandardDeviation(IEnumerable<double> values)
{
double avg = values.Average();
double sum = 0;
foreach (double d in values)
{
sum += Math.Pow((d - avg), 2);
}
return Math.Pow(sum / (values.Count() - 1),.5);
}
}
}
You could use something like this:
public static decimal CalculateStandardDeviation<T>(IEnumerable<T> values)
{
IEnumerable<decimal> decimalValues = values.Select(v => Convert.ToDecimal(v));
decimal result = 0;
// calculate standard deviation on decimalValues
return result;
}
It will throw an exception if values contains values that can't be converted to a decimal, but will work if the values are of an appropriate type, and I think that makes perfect sense.
Unfortunately, there is no base class for all numbers. You can do this with a generic run-time checking method, or a compile-time safe set of overloads.
Generic Method:
public static T CalculateStandardDeviation(IEnumerable<T> values)
{
var valueArray = values.Select(Convert.ToDecimal).ToArray();
//...
return (T)standardDeviation;
}
The problem with using a single generic method is that you can't put a type constraint on the type parameter that would restrict it to only numeric types. You would have to resort to failing at run-time. There would be nothing to stop you from calling the method with an array of strings, or objects, or Colors, or HttpWebRequests, etc. and unless you do in fact know how to calculate the standard deviation of a color, you should probably stick to individual overrides for a particular numeric type:
I would recommend using the decimal type as your main implementation, and then casting everything to it.
Type-Specific Overloads:
public static decimal CalculateStandardDeviation(IEnumerable<decimal> values)
{
//...
}
public static double CalculateStandardDeviation(IEnumerable<double> values)
{
return (double)CalculateStandardDeviation(values.Select(Convert.ToDecimal));
}
public static int CalculateStandardDeviation(IEnumerable<int> values)
{
return (int)CalculateStandardDeviation(values.Select(Convert.ToDecimal));
}
// etc...
Use C# Generics.
Your function signature will be:
public static T CalculateStandardDeviation(IEnumerable<T> values)
And you can use it like:
int stdDev = CalculateStandardDeviation([int-array]);
double stdDev = CalculateStandardDeviation([double-array]);
Please follow this link:
http://msdn.microsoft.com/en-us/library/ms379564%28VS.80%29.aspx
Edit:
To resolve the Average issue on the generic types, please take a look in this library:
How to Implement Generic Method to do Math calculations on different value types
Obs: Suggestion from Brian.
EDIT
You should use JLRishe's answer, it's much more elegant than this.
You should probably start by adding generics to your method and use the type converter to transform your unknown input into doubles like so :
public static double CalculateStandardDeviation<TSource>(IEnumerable<TSource> inputs)
{
var converter = TypeDescriptor.GetConverter(typeof (double));
if (!converter.CanConvertFrom(typeof(TSource)))
return 0;
var values = new List<double>();
foreach (var value in inputs)
{
values.Add((double) converter.ConvertFrom(value));
}
// Your logic here ...
return ...;
}
I did not tested this snippet but you get the idea.
Foreword:
this answer builds on
How to verify whether a type overloads/supports a certain operator?
and
http://www.codeproject.com/Articles/87438/TinyLisp-A-Language-and-Parser-to-See-LINQ-Express
The second link shows how to compile and evaluate linq expressions.
In short you could forego static type safety and check for the ability of a type to support specific operations at runtime (first link), in case it does not you could throw an exception as the following sample demonstrates:
void Main()
{
DoAdd<float>(5,6);
DoAdd<int>(5,6);
DoAdd<bool>(true,false);
}
// Define other methods and classes here
static void DoAdd<T>(T in1, T in2){
if(!HasAdd<T>()){throw new Exception("Unsupported Type!");}
var c1 = Expression.Constant(in1, typeof(T));
var c2 = Expression.Constant(in2, typeof(T));
var expression=Expression.Add(c1, c2);
Expression<Func<T>> lExpression = Expression.Lambda<Func<T>>(expression);
Func<T> fExpression = lExpression.Compile();
Console.WriteLine(fExpression());
}
static bool HasAdd<T>() {
var c = Expression.Constant(default(T), typeof(T));
try {
Expression.Add(c, c); // Throws an exception if + is not defined
return true;
} catch {
return false;
}
}
Passing an IEnumerable of Numeric Values as a parameter to method will be supported in C# 6.0
Is it possible to modify the standard Numeric Format "G" so that the exponent is used when the number contains more than 2 zeros after the decimal place. If not, alternative solutions will be appreciated
e.g. Console.WriteLine("{0:G}", -0.001960231155763821); outputs 1.96023115576382E-03
I cannot use the "E" formatter because for i have to also format double like 0.1326402168430582 for which the output should be 0.132640216843058
It seems that exponents are used in the "G" formatter when the number contains more than 4 zeros after the decimal place e.g. Console.WriteLine("{0:G}", 0.000023); outputs 2.3E-05
You can write extension method. Bellow is the code that you can copy and paste in LINQPad and run it. Dump() method is LINQPad extension method. So if you copy your code to VS, just ignore it.
void Main()
{
var x = -0.00160231155763821;
var x2 = 0.099;
var x3 = -0.001;
x.G2Format().Dump("x");
x2.G2Format().Dump("x2");
x3.G2Format().Dump("x3");
}
public static class Extensions
{
public static string G2Format(this double value)
{
var format = (0.01 > value) ? "{0:e}" : "{0:G}";
return string.Format(format, value);
}
}
It will gives you this result:
x
-1.602312e-003
x2
0.099
x3
-1.000000e-003
Is that what you are looking for?
I have a Double which could have a value from around 0.000001 to 1,000,000,000.000
I wish to format this number as a string but conditionally depending on its size. So if it's very small I want to format it with something like:
String.Format("{0:.000000000}", number);
if it's not that small, say 0.001 then I want to use something like
String.Format("{0:.00000}", number);
and if it's over, say 1,000 then format it as:
String.Format("{0:.0}", number);
Is there a clever way to construct this format string based on the size of the value I'm going to format?
Use Math.Log10 of the absolute value of the double to figure out how many 0's you need either left (if positive) or right (if negative) of the decimal place. Choose the format string based on this value. You'll need handle zero values separately.
string s;
double epislon = 0.0000001; // or however near zero you want to consider as zero
if (Math.Abs(value) < epislon) {
int digits = Math.Log10( Math.Abs( value ));
// if (digits >= 0) ++digits; // if you care about the exact number
if (digits < -5) {
s = string.Format( "{0:0.000000000}", value );
}
else if (digits < 0) {
s = string.Format( "{0:0.00000})", value );
}
else {
s = string.Format( "{0:#,###,###,##0.000}", value );
}
}
else {
s = "0";
}
Or construct it dynamically based on the number of digits.
Use the # character for optional positions in the string:
string.Format("{0:#,###,##0.000}", number);
I don't think you can control the number of decimal places like that as the precision of the double will likely mess things up.
To encapsulate the logic of deciding how many decimal places to output you could look at creating a custom formatter.
The first two String.Format in your question can be solved by automatically removing trailing zeros:
String.Format("{0:#,##0.########}", number);
And the last one you could solve by calling Math.Round(number,1) for values over 1000 and then use the same String.Format.
Something like:
String.Format("{0:#,##0.########}", number<1000 ? number : Math.Round(number,1));
Following up on OwenP's (and by "extension" tvanfosson):
If it's common enough, and you're on C# 3.0, I'd turn it into an extension method on the double:
class MyExtensions
{
public static string ToFormmatedString(this double d)
{
// Take d and implement tvanfosson's code
}
}
Now anywhere you have a double you can do:
double d = 1.005343;
string d_formatted = d.ToFormattedString();
If it were me, I'd write a custom wrapper class and put tvanfosson's code into its ToString method. That way you could still work with the double value, but you'd get the right string representation in just about all cases. It'd look something like this:
class FormattedDouble
{
public double Value { get; set; }
protected overrides void ToString()
{
// tvanfosson's code to produce the right string
}
}
Maybe it might be better to make it a struct, but I doubt it would make a big difference. You could use the class like this:
var myDouble = new FormattedDouble();
myDouble.Value = Math.Pi;
Console.WriteLine(myDouble);