I need to limit the value on overflow.
I implemented this as follows:
public static sbyte LimitValueToSByte(this int val)
{
if (val > sbyte.MaxValue) return sbyte.MaxValue;
if (val < sbyte.MinValue) return sbyte.MinValue;
return (sbyte)val;
}
Is there a more elegant way?
This is the code in a time critical system, therefore performance is important.
That seems like a perfectly readable and valid code that doesn't need any improvement whatsoever. It's just the name of the method. Maybe use ToSbyte rather than LimitValueToSByte.
Can't think of a better way to write that function.
I'd call it ClampToSByte, since this kind of limiting operation is usually called Clamp. Limit is a bit less specific, and allows for other boundary conditions, such as wrapping around.
You should be careful if you implement similar code for floating point numbers. In particular you need to decide what behavior you want for NaNs and signed zeros. But luckily that are no issues with integral values.
Looks pretty good to me. If you want something more elegant, how about a generic clamp function?
public static T Clamp<T>(this T value, T min, T max)
where T : IComparable<T>
{
if (value.CompareTo(min) <= 0) return min;
if (value.CompareTo(max) >= 0) return max;
return value;
}
(Warning: I didn't test this.) You could use it like this:
int a = 42;
sbyte b = (sbyte)a.Clamp(sbyte.MinValue, sbyte.MaxValue);
My new solution of this problem:
public static sbyte Clamp(this int val)
{
return (sbyte)Math.Max(Math.Min(value, sbyte.MaxValue), sbyte.MinValue);
}
Related
I am not sure if "clamping" is the correct terminology for this, however I really don't know what else to call it. Suppose we wanted to limit an integer to stay within some arbitrary range, like 0-50. This can be easily achieved by testing the current value with an if statement and assigning the maximum or minimum value accordingly. However, what is the fastest way to keep the Integer at its maximum value or minimum value?
As easy as
var normalized = Math.Min(50, Math.Max(0, value));
As of performance:
public static int Max(int val1, int val2) {
return (val1>=val2)?val1:val2;
}
That's how it's implemented in .NET, so it's unlikely you can implement it even better.
If you want speed, you should keep the CPU's branch predictor happy. So make the "happy path" return 'n' (the most probable outcome of calling 'Clamp'):
public static int Clamp( int n, int min, int max ) {
if( value < min ) return min;
if( value > max ) return max;
return n;
}
Math.Clamp was introduced since .NET Core 2.0 so you can use it directly. It should be the current fastest method
Math.Clamp(12, 0, 50)
I'm familiar with the System.Numerics.BigInteger class, but in my app, I'm only ever dealing with positive integers. Negative integers are an error case, and it'd be nice if there was an unsigned equivalent of the BigInteger type so I could remove all of these checks. Does one exist?
There's nothing in the framework, no. I would try to centralize the checks in as small a public API as possible, and then treat the data as valid for the rest of the time - just as you would for something like null checking. Of course, you still need to be careful if you perform any operations which could create a negative value (e.g. subtracting one from another).
You may be able to make the code slightly neater by creating an extension method, e.g.
public static void ThrowIfNegative(this BigInteger value, string name)
{
if (value.Sign < 0)
{
throw new ArgumentOutOfRangeException(name);
}
}
... and use it like this:
input.ThrowIfNegative("input");
You could potentially create your own UBigInteger struct which contained a BigInteger, and perform operations between different values by using the BigInteger implementation and checks, but I suspect that would be quite a lot of work for relatively little benefit, and may have performance implications if you're using it for a lot of calculations.
Well, let's have a look at a simple example
uint a=1;
uint b=2;
uint c=a-b;
Console.WriteLine(c);
gives you the output 4294967295 (=2^32-1).
But what if you had an unsigned BigInteger with similar behaviour?
UBigInteger a(1);
UBigInteger b(2);
UBigInteger c=a-b;
Console.WriteLine(c.ToString());
What should that be? Of course, from what you wrote one can assume you might expect to get some kind of exception in this case, but such behaviour would not be consistent to int. Better introduce the checks for < 0 where you need them, for example, like the way Jon Skeet suggested.
If you only use a reasonably small subset of the the BigInteger API, writing your own wrapper class is easy if laborious. Here is some sample code to demonstrate that it needn't be that big an operation:
public struct UnsignedBigInteger
{
private BigInteger value;
private UnsignedBigInteger(BigInteger n) { value = n; }
public UnsignedBigInteger(uint n) { value = new BigInteger(n); }
// ... other constructors ...
public static UnsignedBigInteger operator+(UnsignedBigInteger lhs, UnsignedBigInteger rhs)
{
return new UnsignedBigInteger(lhs.value + rhs.value);
}
public static UnsignedBigInteger operator-(UnsignedBigInteger lhs, UnsignedBigInteger rhs)
{
var result = lhs.value - rhs.value;
if (result < BigInteger.Zero) throw new InvalidOperationException("value out of range");
return new UnsignedBigInteger(result);
}
// ... other operators ...
}
If negative values present such a problem, is possible to eliminate them somehow so that bad data(the negative values) doesn't even reach your logic ? This will eliminate the check all together. Could you post a short snippet of what you are doing ?
There isn't any support in the framework to declare BigInteger as unsigned. However, you could create a static method to check if the number is negative or not.
public static void ValidateBigIntForUnsigned(BigInteger bigInteger)
{
if(bigInteger.Sign < 0)
throw new Exception("Only unsigned numbers are allowed!");
}
Often I find myself having a expression where a division by int is a part of a large formula. I will give you a simple example that illustrate this problem:
int a = 2;
int b = 4;
int c = 5;
int d = a * (b / c);
In this case, d equals 0 as expected, but I would like this to be 1 since 4/5 multiplied by 2 is 1 3/5 and when converted to int get's "rounded" to 1. So I find myself having to cast c to double, and then since that makes the expression a double also, casting the entire expression to int. This code looks like this:
int a = 2;
int b = 4;
int c = 5;
int d = (int)(a * (b / (double)c));
In this small example it's not that bad, but in a big formula this get's quite messy.
Also, I guess that casting will take a (small) hit on performance.
So my question is basically if there is any better approach to this than casting both divisor and result.
I know that in this example, changing a*(b/c) to (a*b)/c would solve the problem, but in larger real-life scenarios, making this change will not be possible.
EDIT (added a case from an existing program):
In this case I'm caclulating the position of a scrollbar according to the size of the scrollbar, and the size of it's container. So if there is double the elements to fit on the page, the scrollbar will be half the height of the container, and if we have scrolled through half of the elements possible, that means that the scroller position should be moved 1/4 down so it will reside in the middle of the container. The calculations work as they should, and it displays fine. I just don't like how the expression looks in my code.
The important parts of the code is put and appended here:
int scrollerheight = (menusize.Height * menusize.Height) / originalheight;
int maxofset = originalheight - menusize.Height;
int scrollerposition = (int)((menusize.Height - scrollerheight) * (_overlayofset / (double)maxofset));
originalheight here is the height of all elements, so in the case described above, this will be the double of menusize.Height.
Disclaimer: I typed all this out, and then I thought, Should I even post this? I mean, it's a pretty bad idea and therefore doesn't really help the OP... In the end I figured, hey, I already typed it all out; I might as well go ahead and click "Post Your Answer." Even though it's a "bad" idea, it's kind of interesting (to me, anyway). So maybe you'll benefit in some strange way by reading it.
For some reason I have a suspicion the above disclaimer's not going to protect me from downvotes, though...
Here's a totally crazy idea.
I would actually not recommend putting this into any sort of production environment, at all, because I literally thought of it just now, which means I haven't really thought it through completely, and I'm sure there are about a billion problems with it. It's just an idea.
But the basic concept is to create a type that can be used for arithmetic expressions, internally using a double for every term in the expression, only to be evaluated as the desired type (in this case: int) at the end.
You'd start with a type like this:
// Probably you'd make this implement IEquatable<Term>, IEquatable<double>, etc.
// Probably you'd also give it a more descriptive, less ambiguous name.
// Probably you also just flat-out wouldn't use it at all.
struct Term
{
readonly double _value;
internal Term(double value)
{
_value = value;
}
public override bool Equals(object obj)
{
// You would want to override this, of course...
}
public override int GetHashCode()
{
// ...as well as this...
return _value.GetHashCode();
}
public override string ToString()
{
// ...as well as this.
return _value.ToString();
}
}
Then you'd define implicit conversions to/from double and the type(s) you want to support (again: int). Like this:
public static implicit operator Term(int x)
{
return new Term((double)x);
}
public static implicit operator int(Term x)
{
return (int)x._value;
}
// ...and so on.
Next, define the operations themselves: Plus, Minus, etc. In the case of your example code, we'd need Times (for *) and DividedBy (for /):
public Term Times(Term multiplier)
{
// This would work because you would've defined an implicit conversion
// from double to Term.
return _value * multiplier._value;
}
public Term DividedBy(Term divisor)
{
// Same as above.
return _value / divisor._value;
}
Lastly, write a static helper class to enable you to perform Term-based operations on whatever types you want to work with (probably just int for starters):
public static class TermHelper
{
public static Term Times(this int number, Term multiplier)
{
return ((Term)number).Times(multiplier);
}
public static Term DividedBy(this int number, Term divisor)
{
return ((Term)number).DividedBy(divisor);
}
}
What would all of this buy you? Practically nothing! But it would clean up your expressions, hiding away all those unsightly explicit casts, making your code significantly more attractive and considerably more impossible to debug. (Once again, this is not an endorsement, just a crazy-ass idea.)
So instead of this:
int d = (int)(a * (b / (double)c)); // Output: 2
You'd have this:
int d = a.Times(b.DividedBy(c)); // Output: 2
Is it worth it?
Well, if having to write casting operations were the worst thing in the world, like, even worse than relying on code that's too clever for its own good, then maybe a solution like this would be worth pursuing.
Since the above is clearly not true... the answer is a pretty emphatic NO. But I just thought I'd share this idea anyway, to show that such a thing is (maybe) possible.
First of all, C# truncates the result of int division, and when casting to int. There's no rounding.
There's no way to do b / c first without any conversions.
Multiply b times 100. Then divide by 100 at the end.
In this case, I would suggest Using double instead, because you don't need 'exact' precision.
However, if you really feel you want to do it all without floating-point operation, I would suggest creating some kind of fraction class, which is far more complex and less efficient but you can keep track of all dividend and divisor and then calculate it all at once.
This question already has answers here:
Where can I find the "clamp" function in .NET?
(11 answers)
Closed 6 years ago.
In C#, I often have to limit an integer value to a range of values. For example, if an application expects a percentage, an integer from a user input must not be less than zero or more than one hundred. Another example: if there are five web pages which are accessed through Request.Params["p"], I expect a value from 1 to 5, not 0 or 256 or 99999.
I often end by writing a quite ugly code like:
page = Math.Max(0, Math.Min(2, page));
or even uglier:
percentage =
(inputPercentage < 0 || inputPercentage > 100) ?
0 :
inputPercentage;
Isn't there a smarter way to do such things within .NET Framework?
I know I can write a general method int LimitToRange(int value, int inclusiveMinimum, int inlusiveMaximum) and use it in every project, but maybe there is already a magic method in the framework?
If I need to do it manually, what would be the "best" (ie. less uglier and more fast) way to do what I'm doing in the first example? Something like this?
public int LimitToRange(int value, int inclusiveMinimum, int inlusiveMaximum)
{
if (value >= inclusiveMinimum)
{
if (value <= inlusiveMaximum)
{
return value;
}
return inlusiveMaximum;
}
return inclusiveMinimum;
}
This operation is called 'Clamp' and it's usually written like this:
public static int Clamp( int value, int min, int max )
{
return (value < min) ? min : (value > max) ? max : value;
}
A much cleaner method that will work with more than just integers (taken from my own library of shared code):
public static T Clamp<T>(T value, T min, T max) where T : IComparable<T>
{
if (value.CompareTo(min) < 0)
return min;
if (value.CompareTo(max) > 0)
return max;
return value;
}
I see Mark's answer and raise it by a this:
public static class InputExtensions
{
public static int LimitToRange(
this int value, int inclusiveMinimum, int inclusiveMaximum)
{
if (value < inclusiveMinimum) { return inclusiveMinimum; }
if (value > inclusiveMaximum) { return inclusiveMaximum; }
return value;
}
}
Usage:
int userInput = ...;
int result = userInput.LimitToRange(1, 5)
See: Extension Methods
I like Guffa's answer, but I am surprised that no one has yet posted a solution using Min/Max.
public int LimitInclusive(int value, int min, int max)
{
return Math.Min(max, Math.Max(value, min));
}
An alternative way to write your LimitToRange function is as follows.
public int LimitToRange(int value, int inclusiveMinimum, int inclusiveMaximum)
{
if (value < inclusiveMinimum) { return inclusiveMinimum; }
if (value > inclusiveMaximum) { return inclusiveMaximum; }
return value;
}
I think this is a little easier to understand while still being efficient.
No, there isn't any method for that built in the framework. I suppose that it was left out because you already have Min and Max, so you can accomplish it using them.
If you write your own method for it, it doesn't matter much how you write it. If you use if statements or the conditional operator ?, it will still compile to pretty much the same code anyway.
To clamp values without giving users any feedback that the value entered by them is wrong, in general, might not be a great idea (IMHO). This might lead to subtle bugs later, which are difficult to debug, especially when min/max values are determined at run time.
Think of this. You have $100 in your bank account, and you want to transfer $150 to your friend. Would you like your banking system to throw an InsufficientFundsException or get into a discussion with your friend that you transferred $150 but he received only $100 (assuming the bank clamped the transfer amount to 100 since your did not have sufficient funds)
That being said, you should also look at code contracts.
public void MyFunction (Type input)
{
Contract.Requires(input > SomeReferenceValue);
Contract.Requires (input < SomeOtherReferencValue);
}
This will force the user input to be within the range.
I like the Clamp name. I would suggest the following class
public class MathHelper
{
public static int Clamp (int value,int min,int max)
{
// todo - implementation
}
public static float Clamp (float value,float min,float max)
{
// todo - implementation
}
)
or if you want to use generics, then
public class MathHelper
{
public static T Clamp<T> (T value, T min, T max) where T : IComparable
{
// todo - implementation
T output = value;
if (value.CompareTo(max) > 0)
{
return max;
}
if (value.CompareTo(min) < 0)
{
return min;
}
return output;
}
}
I am doing some custom serializing, and in order to save some space, i want to serialize the decimals as int, if possible value wise. Performance is a concern, since i am dealing with a high volume of data. The current method i use is:
if ((value > Int32.MinValue) && (value < Int32.MaxValue) && ((valueAsInt = Decimal.ToInt32(value)) == value))
{
return true;
}
Can this be improved?
Do you have any negative values? I'm guessing yes since you have the MinValue check, otherwise you can skip it. You could even use unsigned int which will allow you to convert more of your double values into ints.
Edit: Also, if you have more positive numbers, you can swap the first two conditions. That way the first one is the most likely to fail, decreasing the total number of comparisons.
Your invalidation criteria are:
1) Is it greater than MaxValue?
2) Is it smaller than MinValue?
3) Does it contain a fractional component?
It sounds like you have them covered. My implementation would be:
public bool IsConvertibleToInt(decimal value)
{
if(value > int.MaxValue)
return false;
if(value < int.MinValue)
return false;
if(Math.Floor(value) < value && Math.Ceiling(value) > value)
return false;
return true;
}
How about this. I think it should take fewer operations (at least a fewer number of comparisons):
return (value == (Int32)value);
Also remember, if an if statement simply returns a boolean, you can just return the comparison. That alone might make it faster (unless the compiler already optimizes for this). If you have to use the if statement, you can similarly do this:
if (value == (Int32)value)
{
//Do stuff...
return true;
}
else
{
//Do stuff...
return false;
}
EDIT: I realize this doesn't actually work. I was thinking the Int32 cast would just copy in the first 32 bits from the decimal, leaving behind any remaining bits (and not throw an exception), but alas, it didn't work that way (not to mention it would be wrong for all negative values).
It depends on how many decimal places you have or really care about. If you could say that I only care about up to 3 decimal places then the largest number you can store in int32 is int.MaxValue / 1000. If you are only working with positive numbers then you can get a higher number by using uint. In any case the way to do it is to consistently reserve space for the decimal and use * 1000 to encode them and / 1000 to decode them to / from decimal.
No need for "valueAsInt =". I believe (Decimal.ToInt32(value) == value)) gets you the same result with one less assignment. Are you using valueAsInt as some sort of output parameter?
Wouldn't you be able to just do something like:
if(Decimal.ToInt32(value) == value)
{
return true;
}
Not an expert on .net, but I think that should be all it'd require. Also, your two comparisons operators should be 'or equal' since the min/max values are also valid.
Edit: As pointed out in the comment, this would throw an exception. You could try catching the exception and returning false, but at that point it likely would be much faster to do the min/max testing yourself.