문제

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top