Create an array that points to only part of another array? - c#

I have a huge array that contains reference type elements, and I want to create a lot of other arrays that essentially just point to specific parts of that one big array.
In other words, I want to create "indexers" or "pointers with lengths".
In C++ it's easy to do so using pointers and for each pointer assign a length, for example create a struct which contains a pointer with a length.
How can I achieve this in C#/.NET?
The whole point is to avoid copying anything, I just want pointers to specific parts in an array that already exists in memory.
Any ideas?

Jon's suggestion of using ArraySegment<T> is likely what you want. If however you are wanting to represent a pointer to the interior of an array, the way you can in C++, here's some code for that. No warranty is expressed or implied, use at your own risk.
This code does not track the "length" of the interior pointer in any way, but it is quite easy to add that feature if you want.
internal struct ArrayPtr<T>
{
public static ArrayPtr<T> Null { get { return default(ArrayPtr<T>); } }
private readonly T[] source;
private readonly int index;
private ArrayPtr(ArrayPtr<T> old, int delta)
{
this.source = old.source;
this.index = old.index + delta;
Debug.Assert(index >= 0);
Debug.Assert(index == 0 || this.source != null && index < this.source.Length);
}
public ArrayPtr(T[] source)
{
this.source = source;
index = 0;
}
public bool IsNull()
{
return this.source == null;
}
public static bool operator <(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index < b.index;
}
public static bool operator >(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index > b.index;
}
public static bool operator <=(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index <= b.index;
}
public static bool operator >=(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index >= b.index;
}
public static int operator -(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index - b.index;
}
public static ArrayPtr<T> operator +(ArrayPtr<T> a, int count)
{
return new ArrayPtr<T>(a, +count);
}
public static ArrayPtr<T> operator -(ArrayPtr<T> a, int count)
{
return new ArrayPtr<T>(a, -count);
}
public static ArrayPtr<T> operator ++(ArrayPtr<T> a)
{
return a + 1;
}
public static ArrayPtr<T> operator --(ArrayPtr<T> a)
{
return a - 1;
}
public static implicit operator ArrayPtr<T>(T[] x)
{
return new ArrayPtr<T>(x);
}
public static bool operator ==(ArrayPtr<T> x, ArrayPtr<T> y)
{
return x.source == y.source && x.index == y.index;
}
public static bool operator !=(ArrayPtr<T> x, ArrayPtr<T> y)
{
return !(x == y);
}
public override bool Equals(object x)
{
if (x == null) return this.source == null;
var ptr = x as ArrayPtr<T>?;
if (!ptr.HasValue) return false;
return this == ptr.Value;
}
public override int GetHashCode()
{
unchecked
{
int hash = this.source == null ? 0 : this.source.GetHashCode();
return hash + this.index;
}
}
public T this[int index]
{
get { return source[index + this.index]; }
set { source[index + this.index] = value; }
}
}
Now we can do stuff like:
double[] arr = new double[10];
var p0 = (ArrayPtr<double>)arr;
var p5 = p0 + 5;
p5[0] = 123.4; // sets arr[5] to 123.4
var p7 = p0 + 7;
int diff = p7 - p5; // 2

It sounds like you're looking for something like ArraySegment<T>. Contrary to my earlier thoughts, it does have an indexer and implement IEnumerable<T> etc - it's just done with explicit interfaces.
Sample code:
using System;
using System.Collections.Generic;
static class Test
{
static void Main()
{
string[] original = { "The", "quick", "brown", "fox", "jumped", "over",
"the", "lazy", "dog" };
IList<string> segment = new ArraySegment<string>(original, 3, 4);
Console.WriteLine(segment[2]); // over
foreach (var word in segment)
{
Console.WriteLine(word); // fox jumped over the
}
}
}
EDIT: As noted in comments, ArraySegment<T> is only really "fully functional" in .NET 4.5. The .NET 4 version doesn't implement any interfaces.

You could use LINQ:
yourArray.Skip(startIndex).Take(numberToTake)
The query is lazily evaluated.

Related

Use maxvalue if result too large for int

Is there a way in C# to use maxvalue when an int would be out of range.
For my purposes I can't use a long.
Example
int a = 842673832;
int b = 2131231321;
int t = a * b;
//if t out of range, t = Int32.MinValue;
You would need to test it before hand or create a very special kind of integer (like CheckedInt in the link).
Option A
To test it before hand, you need a data type which can handle big integer value (say, long):
long t = (long)a * b;
int r = t > int.MaxValue ? int.MaxValue : t < int.MinValue ? : int.MinValue : (int)t;
Option B
To use the special kind of integer, you may need to overload the basic operators too.
In the example in the link, the exception is thrown, but you could change the exception into implementing int.MaxValue or int.MinValue, something like this:
public struct CheckedInt {
private int Value { get; set; }
public CheckedInt(int value)
: this() {
Value = value;
}
public static implicit operator CheckedInt(int me) {
return new CheckedInt(me);
}
public static CheckedInt operator +(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value + (double)rhs.Value;
if (testResult > int.MaxValue)
return int.MaxValue;
if (testResult < int.MinValue)
return int.MinValue;
return new CheckedInt(lhs.Value + rhs.Value); //note that direct lhs+rhs will cause StackOverflow
}
public static CheckedInt operator -(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value - (double)rhs.Value;
if (testResult > int.MaxValue)
return int.MaxValue;
if (testResult < int.MinValue)
return int.MinValue;
return new CheckedInt(lhs.Value - rhs.Value); //note that direct lhs-rhs will cause StackOverflow
}
public static CheckedInt operator *(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value * (double)rhs.Value;
if (testResult > int.MaxValue)
return int.MaxValue;
if (testResult < int.MinValue)
return int.MinValue;
return new CheckedInt(lhs.Value * rhs.Value); //note that direct lhs*rhs will cause StackOverflow
}
public static CheckedInt operator /(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value / (double)rhs.Value;
if (testResult > int.MaxValue)
return int.MaxValue;
if (testResult < int.MinValue)
return int.MinValue;
return new CheckedInt(lhs.Value / rhs.Value); //note that direct lhs-rhs will cause StackOverflow
}
//Add any other overload that you want
public override string ToString() { //example
return Value.ToString();
}
public bool Equals(CheckedInt otherInt) { //example
return Value == otherInt.Value;
}
}
You can try this by enabling overflow checking
int t;
try
{
int a = 842673832;
int b = 2131231321;
t = checked(a * b);
}
catch (System.OverflowException e)
{
t = Int32.MaxValue;
}
If you want t to be an int and not a larger type like Ian's answer, you can catch at OverflowException and set t to MaxValue. Make sure to wrap the section in a checked keyword to allow overflow checking.
int t = 0;
checked {
try
{
int a = 842673832;
int b = 2131231321;
t = a * b;
}
catch (OverflowException)
{
t = int.MaxValue;
}
}

All combination of a list of tuples

I'm practicing some optimization problems and I'm stuck.
I have a list of tuples and I am doing the following:
private static int CalculateMinimumTotalCost(List<Tuple<int, int>> tuples)
{
int minimumCost = 0;
for(int i=0;i<tuples.Count()-1;i++)
{
minimumCost += Math.Max(Math.Abs(tuples[i].Item1 - tuples[i + 1].Item1), Math.Abs(tuples[i].Item2 - tuples[i + 1].Item2));
}
return minimumCost;
}
The idea is that given a list of tuples and this mathematical equation, I need to find the minimum cost. The catch is that the order of the tuples can be rearranged. My job is to find the LEAST costly arrangement of tuples.
So what I would like to do is loop through all possible combination of Tuples and return the combination with the minimum cost.
For example:
(1,2)(1,1)(1,3) = 3
(1,1)(1,2)(1,3) = 2
So in this case, i would return 2 because that arrangement is less costly.
I understand that when there are N tuples, the number of combinations is N!.
How do I get all the combinations possible for a list of tuples?
Thanks!
As other have suggested you should create the Point class:
public partial class Point
{
public int X { get; set; }
public int Y { get; set; }
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}
}
And, let's encapsulate the functions for computing distance and total cost :
public partial class Point
{
public static int CalculateDistance(Point p0, Point p1)
{
return Math.Max(
Math.Abs(p0.X - p1.X),
Math.Abs(p0.Y - p1.Y)
);
}
}
public static class PointExtensions
{
public static int GetTotalCost(this IEnumerable<Point> source)
{
return source
.Zip(source.Skip(1), Point.CalculateDistance)
.Sum();
}
}
Finally, you will need another extension method to create "all possible combination" :
public static class PermutationExtensions
{
public static IEnumerable<IEnumerable<T>> GetPermutations<T>(this IEnumerable<T> source)
{
if (source == null || !source.Any())
throw new ArgumentNullException("source");
var array = source.ToArray();
return Permute(array, 0, array.Length - 1);
}
private static IEnumerable<IEnumerable<T>> Permute<T>(T[] array, int i, int n)
{
if (i == n)
yield return array.ToArray();
else
{
for (int j = i; j <= n; j++)
{
array.Swap(i, j);
foreach (var permutation in Permute(array, i + 1, n))
yield return permutation.ToArray();
array.Swap(i, j); //backtrack
}
}
}
private static void Swap<T>(this T[] array, int i, int j)
{
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Source from Listing all permutations of a string/integer adapted to be more LINQ-friendly
Usage :
void Main()
{
var list = new List<Point>
{
new Point(1, 2),
new Point(1, 1),
new Point(1, 3),
};
// result: Point[] (3 items) : (1, 1), (1, 2), (1,3)
list.GetPermutations()
.OrderBy(x => x.GetTotalCost())
.First();
}
EDIT : As #EricLippert pointed out, source.OrderBy(selector).First() has some extra cost. This following extension method deals with this issue :
public static class EnumerableExtensions
{
public static T MinBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> keySelector, IComparer<TKey> comparer = null)
{
IEnumerator<T> etor = null;
if (source == null || !(etor = source.GetEnumerator()).MoveNext())
throw new ArgumentNullException("source");
if (keySelector == null)
throw new ArgumentNullException("keySelector");
var min = etor.Current;
var minKey = keySelector(min);
comparer = comparer ?? Comparer<TKey>.Default;
while (etor.MoveNext())
{
var key = keySelector(etor.Current);
if (comparer.Compare(key, minKey) < 0)
{
min = etor.Current;
minKey = key;
}
}
return min;
}
}
And, we can rewrite the above solution as :
list.GetPermutations().MinBy(x => x.GetTotalCost())
You can change the for loop to Foreach to make it more readable and rather than using index to fetch values.
private static int CalculateMinimumTotalCost(List<Tuple<int, int>> tuples)
{
int minimumCost = 0;
Tuple<int, int> currentTuple = tuples.First();
foreach (Tuple<int, int> tuple in tuples)
{
minimumCost += Math.Max(Math.Abs(currentTuple.Item1 - tuple.Item1), Math.Abs(currentTuple.Item2 - tuple.Item2));
currentTuple = tuple;
}
return minimumCost;
}

Sorting an Arraylist of strings on a portion of each string, delimited by a character

I'm trying to sort an ArrayList of strings (not in int).
Given:
f.e.
[0] 23,24
[1] 12,33
[2] 37,11
Arraylist.Sort should give back (sorted by the last number ascending):
[0] 37,11
[1] 23,24
[2] 12,33
Having this so far:
public class Point
{
public int i, j;
public Point(int i, int j)
{this.i = i; this.j = j;}
public string ToString()
{return i + "," + j;}
}
public class SList
{
public static void Main()
{
ArrayList Slist = new ArrayList();
Random Generate = new Random();
for (int i = 0; i < 3; i++)
{
Point p = new Point(Generate.Next(40), Generate.Next(40));
Slist.Add(p.ToString());
}
Slist.Sort();
}
}
I'm not 100% sure if you have an array of strings or if they are split already, but you can create a custom comparer and do something like this perhaps. Make clearer what you want so that people can help you better.
public class MyCustomComparer : IComparer<string>
{
public int Compare(string x, string y)
{
var xIntValues = x.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
var yIntValues = y.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
for(var i = 0; i < Math.Min(xIntValues.Count(), yIntValues.Count()); ++i)
if (xIntValues[i] != yIntValues[i])
return xIntValues[i] - yIntValues[i];
return xIntValues.Count() - yIntValues.Count();
}
}
Then use it like this where your array elements contain strings like "37, 11"
Array.Sort(myArray, MyCustomComparer);
Sort of odd to be using an ArrayList after c# 1.0, but if you have one for legacy reasons, you can create your own non-generic custom comparer, like so:
public class CustomComparer : IComparer<string>, IComparer {
#region IComparer<string> Members
int? ExtractNumber(string str)
{
int index = str.LastIndexOf(',');
if (index < 0)
return null;
var subStr = str.Substring(index+1);
int result;
if (int.TryParse(subStr, out result))
return result;
return null;
}
// Return x - y
public int Compare(string x, string y)
{
#if false
Given: f.e.
[0] 23,24
[1] 12,33
[2] 37,11
Arraylist.Sort should give back (sorted by the last number ascending):
[0] 37,11
[1] 23,24
[2] 12,33
#endif
var xVal = ExtractNumber(x);
var yVal = ExtractNumber(y);
if (!xVal.HasValue && !yVal.HasValue)
return x.CompareTo(y);
else if (!xVal.HasValue)
return 1;
else if (!yVal.HasValue)
return -1;
int cmp = xVal.Value.CompareTo(yVal.Value);
if (cmp != 0)
return cmp;
return x.CompareTo(y);
}
#endregion
#region IComparer Members
public int Compare(object x, object y)
{
if (object.ReferenceEquals(x, y))
return 0;
string xStr = x as string;
string yStr = y as string;
if (xStr == null && yStr == null)
return 0; // NO IDEA
else if (xStr == null)
return 1;
else if (yStr == null)
return -1;
else return Compare(xStr, yStr);
}
#endregion
}
The following code implements IComparable on your class. It sorts on y in ascending order:
public class Point : IComparable<Point>
{
public int x;
public int y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public string ToString()
{
return x + "," + y;
}
public int CompareTo(Point other)
{
return this.y.CompareTo(other.y);
}
}
You can now use ArrayList.Sort() to achieve the order you need.
The easiest way to do this would be by stepping away from your non-generic list:
var sortedList = list.Cast<string>().OrderBy(x => x.Split(',')[1]);
The code is self-explanatory.
Using this as input:
var list = new ArrayList();
list.Add("23,24");
list.Add("12,33");
list.Add("37,11");
Yields this as output:
37,11
23,24
12,33

Why is using a NON-decimal data type bad for money?

tl;dr: What's wrong with my Cur (currency) structure?
tl;dr 2: Read the rest of the question please, before giving an example with float or double. :-)
I'm aware that this question has come up numerous times before all around the internet, but I have not yet seen a convincing answer, so I thought I'd ask again.
I fail to understand why using a non-decimal data type is bad for handling money. (That refers to data types that store binary digits instead of decimal digits.)
True, it's not wise to compare two doubles with a == b. But you can easily say a - b <= EPSILON or something like that.
What is wrong with this approach?
For instance, I just made a struct in C# that I believe handles money correctly, without using any decimal-based data formats:
struct Cur
{
private const double EPS = 0.00005;
private double val;
Cur(double val) { this.val = Math.Round(val, 4); }
static Cur operator +(Cur a, Cur b) { return new Cur(a.val + b.val); }
static Cur operator -(Cur a, Cur b) { return new Cur(a.val - b.val); }
static Cur operator *(Cur a, double factor) { return new Cur(a.val * factor); }
static Cur operator *(double factor, Cur a) { return new Cur(a.val * factor); }
static Cur operator /(Cur a, double factor) { return new Cur(a.val / factor); }
static explicit operator double(Cur c) { return Math.Round(c.val, 4); }
static implicit operator Cur(double d) { return new Cur(d); }
static bool operator <(Cur a, Cur b) { return (a.val - b.val) < -EPS; }
static bool operator >(Cur a, Cur b) { return (a.val - b.val) > +EPS; }
static bool operator <=(Cur a, Cur b) { return (a.val - b.val) <= +EPS; }
static bool operator >=(Cur a, Cur b) { return (a.val - b.val) >= -EPS; }
static bool operator !=(Cur a, Cur b) { return Math.Abs(a.val - b.val) < EPS; }
static bool operator ==(Cur a, Cur b) { return Math.Abs(a.val - b.val) > EPS; }
bool Equals(Cur other) { return this == other; }
override int GetHashCode() { return ((double)this).GetHashCode(); }
override bool Equals(object o) { return o is Cur && this.Equals((Cur)o); }
override string ToString() { return this.val.ToString("C4"); }
}
(Sorry for changing the name Currency to Cur, for the poor variable names, for omitting the public, and for the bad layout; I tried to fit it all onto the screen so that you could read it without scrolling.) :)
You can use it like:
Currency a = 2.50;
Console.WriteLine(a * 2);
Of course, C# has the decimal data type, but that's beside the point here -- the question is about why the above is dangerous, not why we shouldn't use decimal.
So would someone mind providing me with a real-world counterexample of a dangerous statement that would fail for this in C#? I can't think of any.
Thanks!
Note: I am not debating whether decimal is a good choice. I'm asking why a binary-based system is said to be inappropriate.
Floats aren't stable for accumulating and decrementing funds. Here's your actual example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BadFloat
{
class Program
{
static void Main(string[] args)
{
Currency yourMoneyAccumulator = 0.0d;
int count = 200000;
double increment = 20000.01d; //1 cent
for (int i = 0; i < count; i++)
yourMoneyAccumulator += increment;
Console.WriteLine(yourMoneyAccumulator + " accumulated vs. " + increment * count + " expected");
}
}
struct Currency
{
private const double EPSILON = 0.00005;
public Currency(double value) { this.value = value; }
private double value;
public static Currency operator +(Currency a, Currency b) { return new Currency(a.value + b.value); }
public static Currency operator -(Currency a, Currency b) { return new Currency(a.value - b.value); }
public static Currency operator *(Currency a, double factor) { return new Currency(a.value * factor); }
public static Currency operator *(double factor, Currency a) { return new Currency(a.value * factor); }
public static Currency operator /(Currency a, double factor) { return new Currency(a.value / factor); }
public static Currency operator /(double factor, Currency a) { return new Currency(a.value / factor); }
public static explicit operator double(Currency c) { return System.Math.Round(c.value, 4); }
public static implicit operator Currency(double d) { return new Currency(d); }
public static bool operator <(Currency a, Currency b) { return (a.value - b.value) < -EPSILON; }
public static bool operator >(Currency a, Currency b) { return (a.value - b.value) > +EPSILON; }
public static bool operator <=(Currency a, Currency b) { return (a.value - b.value) <= +EPSILON; }
public static bool operator >=(Currency a, Currency b) { return (a.value - b.value) >= -EPSILON; }
public static bool operator !=(Currency a, Currency b) { return Math.Abs(a.value - b.value) <= EPSILON; }
public static bool operator ==(Currency a, Currency b) { return Math.Abs(a.value - b.value) > EPSILON; }
public bool Equals(Currency other) { return this == other; }
public override int GetHashCode() { return ((double)this).GetHashCode(); }
public override bool Equals(object other) { return other is Currency && this.Equals((Currency)other); }
public override string ToString() { return this.value.ToString("C4"); }
}
}
On my box this gives $4,000,002,000.0203 accumulated vs. 4000002000 expected in C#. It's a bad deal if this gets lost over many transactions in a bank - it doesn't have to be large ones, just many. Does that help?
Usually monetary calculations require exact results, not just accurate results. float and double types cannot accurately represent the whole range of base 10 real numbers. For instance, 0.1 cannot be represented by a floating-point variable. What will be stored is the nearest representable value, which may be a number such as 0.0999999999999999996. Try it out for yourself by unit testing your struct - for example, attempt 2.00 - 1.10.
I'm not sure why you're shrugging off J Trana's answer as irrelevant. Why don't you try it yourself? The same example works with your struct too. You just need to add a couple extra iterations because you're using a double instead of a float, which gives you a bit more precision. Just delays the problem, doesn't get rid of it.
Proof:
class Program
{
static void Main(string[] args)
{
Currency currencyAccumulator = new Currency(0.00);
double doubleAccumulator = 0.00f;
float floatAccumulator = 0.01f;
Currency currencyIncrement = new Currency(0.01);
double doubleIncrement = 0.01;
float floatIncrement = 0.01f;
for(int i=0; i<100000000; ++i)
{
currencyAccumulator += currencyIncrement;
doubleAccumulator += doubleIncrement;
floatAccumulator += floatIncrement;
}
Console.WriteLine("Currency: {0}", currencyAccumulator);
Console.WriteLine("Double: {0}", doubleAccumulator);
Console.WriteLine("Float: {0}", floatAccumulator);
Console.ReadLine();
}
}
struct Currency
{
private const double EPSILON = 0.00005;
public Currency(double value) { this.value = value; }
private double value;
public static Currency operator +(Currency a, Currency b) { return new Currency(a.value + b.value); }
public static Currency operator -(Currency a, Currency b) { return new Currency(a.value - b.value); }
public static Currency operator *(Currency a, double factor) { return new Currency(a.value * factor); }
public static Currency operator *(double factor, Currency a) { return new Currency(a.value * factor); }
public static Currency operator /(Currency a, double factor) { return new Currency(a.value / factor); }
public static Currency operator /(double factor, Currency a) { return new Currency(a.value / factor); }
public static explicit operator double(Currency c) { return System.Math.Round(c.value, 4); }
public static implicit operator Currency(double d) { return new Currency(d); }
public static bool operator <(Currency a, Currency b) { return (a.value - b.value) < -EPSILON; }
public static bool operator >(Currency a, Currency b) { return (a.value - b.value) > +EPSILON; }
public static bool operator <=(Currency a, Currency b) { return (a.value - b.value) <= +EPSILON; }
public static bool operator >=(Currency a, Currency b) { return (a.value - b.value) >= -EPSILON; }
public static bool operator !=(Currency a, Currency b) { return Math.Abs(a.value - b.value) <= EPSILON; }
public static bool operator ==(Currency a, Currency b) { return Math.Abs(a.value - b.value) > EPSILON; }
public bool Equals(Currency other) { return this == other; }
public override int GetHashCode() { return ((double)this).GetHashCode(); }
public override bool Equals(object other) { return other is Currency && this.Equals((Currency)other); }
public override string ToString() { return this.value.ToString("C4"); }
}
Result:
Currency: $1,000,000.0008
Double: 1000000.00077928
Float: 262144
We're only up to .08 cents, but eventually that'll add up.
Your edit:
static void Main(string[] args)
{
Currency c = 1.00;
c /= 100000;
c *= 100000;
Console.WriteLine(c);
Console.ReadLine();
}
}
struct Currency
{
private const double EPS = 0.00005;
private double val;
public Currency(double val) { this.val = Math.Round(val, 4); }
public static Currency operator +(Currency a, Currency b) { return new Currency(a.val + b.val); }
public static Currency operator -(Currency a, Currency b) { return new Currency(a.val - b.val); }
public static Currency operator *(Currency a, double factor) { return new Currency(a.val * factor); }
public static Currency operator *(double factor, Currency a) { return new Currency(a.val * factor); }
public static Currency operator /(Currency a, double factor) { return new Currency(a.val / factor); }
public static Currency operator /(double factor, Currency a) { return new Currency(a.val / factor); }
public static explicit operator double(Currency c) { return Math.Round(c.val, 4); }
public static implicit operator Currency(double d) { return new Currency(d); }
public static bool operator <(Currency a, Currency b) { return (a.val - b.val) < -EPS; }
public static bool operator >(Currency a, Currency b) { return (a.val - b.val) > +EPS; }
public static bool operator <=(Currency a, Currency b) { return (a.val - b.val) <= +EPS; }
public static bool operator >=(Currency a, Currency b) { return (a.val - b.val) >= -EPS; }
public static bool operator !=(Currency a, Currency b) { return Math.Abs(a.val - b.val) < EPS; }
public static bool operator ==(Currency a, Currency b) { return Math.Abs(a.val - b.val) > EPS; }
public bool Equals(Currency other) { return this == other; }
public override int GetHashCode() { return ((double)this).GetHashCode(); }
public override bool Equals(object o) { return o is Currency && this.Equals((Currency)o); }
public override string ToString() { return this.val.ToString("C4"); }
}
Prints $0.
Mehrdad, I don't think I could convince you if I brought in the entire SEC. Now, your entire class basically implements BigInteger arithmetic with an implied shift of 2 decimal places. (It should be at least 4 for accounting purposes, but we can change 2 to 4 easily enough.)
What advantage do we have backing this class with double instead of BigDecimal (or longlong if something like that is available)? For the advantage of a primitive type I pay with expensive rounding operations. And I also pay with inaccuracies. [Example from here 1]
import java.text.*;
public class CantAdd {
public static void main(String[] args) {
float a = 8250325.12f;
float b = 4321456.31f;
float c = a + b;
System.out.println(NumberFormat.getCurrencyInstance().format(c));
}
}
OK, here we backed with a float instead of a double, but shouldn't that be a BIG warning flag that the whole concept is wrong and that we may get in trouble if we have to make millions of calculations?
Every professional who works in finance believes that floating-point representation of money are a bad idea. (See, among dozens of hits, http://discuss.joelonsoftware.com/default.asp?design.4.346343.29.) Which is more likely: they are all stupid, or floating-point money is indeed a bad idea?
Cur c = 0.00015;
System.Console.WriteLine(c);
// rounds to 0.0001 instead of the expected 0.0002
The problem is that 0.00015 in binary is really 0.00014999999999999998685946966947568625982967205345630645751953125, which rounds down, but the exact decimal value rounds up.

C# is there a nicer way of writing this?

int uploadsID;
int pageNumber;
int x;
int y;
int w;
int h;
bool isValidUploadID = int.TryParse(context.Request.QueryString["uploadID"], out uploadsID);
bool isValidPage = int.TryParse(context.Request.QueryString["page"], out pageNumber);
bool isValidX = int.TryParse(context.Request.QueryString["x"], out x);
bool isValidY = int.TryParse(context.Request.QueryString["y"], out y);
bool isValidW = int.TryParse(context.Request.QueryString["w"], out w);
bool isValidH = int.TryParse(context.Request.QueryString["h"], out h);
if (isValidUploadID && isValidPage && isValidX && isValidY & isValidW & isValidH)
{
This is an ajax handler, checking all passed params are OK. Is this considered bad, and is there a better way to write this, or is it not that important?
Assuming you're not going to use the individual bool variables elsewhere, you could write that as:
int uploadsID, pageNumber, x, y, w, h;
if (int.TryParse(context.Request.QueryString["uploadID"], out uploadsID) &&
int.TryParse(context.Request.QueryString["page"], out pageNumber) &&
int.TryParse(context.Request.QueryString["x"], out x) &&
int.TryParse(context.Request.QueryString["y"], out y) &&
int.TryParse(context.Request.QueryString["w"], out w) &&
int.TryParse(context.Request.QueryString["h"], out h))
{
}
You may want to extract out int.TryParse(context.Request.QueryString[name], out variable into a separate method, leaving you with something like:
int uploadsID, pageNumber, x, y, w, h;
if (TryParseContextInt32("uploadID", out uploadsID) &&
TryParseContextInt32("page", out pageNumber) &&
TryParseContextInt32("x", out x) &&
TryParseContextInt32("y", out y) &&
TryParseContextInt32("w", out w) &&
TryParseContextInt32("h", out h))
{
}
Alternatively, you could encapsulate all this context data into a new type with a TryParse method, so you'd have something like:
PageDetails details;
if (PageDetails.TryParse(context.Request.QueryString))
{
// Now access details.Page, details.UploadID etc
}
That's obviously more work, but I think it would make the code cleaner.
Yes, start by factoring out your int.TryParse(etc.) into a separate function.
(Possibly over-influenced by F#)
//return a tuple (valid, value) from querystring of context, indexed with key
private Tuple<bool, int> TryGet(HttpContext context, string key)
{
int val = 0;
bool ok = int.TryParse(context.request.QueryString[key], out val);
return Tuple.New(ok, val);
}
Then:
var UploadId = TryGet(context, "uploadID");
//...
if(UploadId.Item1 && etc..)
{
//do something with UploadId.Item2;
To make things slightly clearer, you could
private class ValidValue
{
public bool Valid { get; private set; }
public int Value { get; private set; }
public ValidValue(bool valid, int value)
{
Valid = valid;
Value = value;
}
//etc., but this seems a bit too much like hard work, and you don't get
// equality for free as you would with Tuple, (if you need it)
I would probably go for a formatting like this
int uploadsID, pageNumber, x, y, h;
if (Int32.TryParse(context.Request.QueryString["uploadID"], out uploadsID)
&& Int32.TryParse(context.Request.QueryString["page"], out pageNumber)
&& Int32.TryParse(context.Request.QueryString["x"], out x)
&& Int32.TryParse(context.Request.QueryString["y"], out y)
&& Int32.TryParse(context.Request.QueryString["w"], out w)
&& Int32.TryParse(context.Request.QueryString["h"], out h))
{
...
}
but I don't see anything wrong with your approach.
One thing you can do is to replace this:
int uploadsID;
int pageNumber;
int x;
int y;
int w;
int h;
With this
int uploadsID, pageNumber, x, y, w, h;
try
{
// use Parse instead of TryParse
// all are valid, proceed
}
catch
{
// at least one is not valid
}
You could write a helper that gets rid of the ugly out passing style of TryParse, such as:
public delegate bool TryParser<T>(string text, out T result) where T : struct;
public static T? TryParse<T>(string text, TryParser<T> tryParser)
where T : struct
{
// null checks here.
T result;
return tryParser(text, out result) ? result : new T?();
}
And then (assuming you are only interested in validity):
bool isValid = new [] { "uploadID" , "page", "x", "y", "w", "h" }
.Select(q => context.Request.QueryString[q])
.All(t => TryParse<int>(t, int.TryParse).HasValue);
If you need the individual values:
var numsByKey = new [] { "uploadID" , "page", "x", "y", "w", "h" }
.ToDictionary(q => q,
q => TryParse<int>(context.Request.QueryString[q],
int.TryParse));
bool isValid = numsByKey.Values.All(n => n.HasValue);
This retains pretty much the same information as before, except the fine-grained info needs a lookup rather than a local-variable access.

Categories