Determine if decimal can be saved as int32

I do some custom serialization, and in order to save some space, I want to serialize decimal numbers as int, if possible, the value is wise. Performance is a concern because I am dealing with a large amount of data. The current method I'm using is:

if ((value > Int32.MinValue) && (value < Int32.MaxValue) && ((valueAsInt = Decimal.ToInt32(value)) == value)) { return true; } 

Can this be improved?

+4
source share
6 answers

Do you have negative values? I suppose yes, since you have a MinValue check, otherwise you can skip it. You can even use unsigned int, which will allow you to convert more of your double values ​​to ints.

Edit: Also, if you have more positive numbers, you can change the first two conditions. Thus, the first of these is likely to fail, reducing the total number of comparisons.

+1
source

Your invalidity criteria:

1) Is it more MaxValue?

2) Is it smaller than MinValue?

3) Does it contain a fractional component?

Looks like you covered them. My implementation will 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; } 
+1
source

How about this one. I think this should take less operations (at least fewer comparisons):

  return (value == (Int32)value); 

Also remember that if the if just returns a boolean, you can simply return the comparison. Only this can make it faster (if the compiler no longer optimizes for this). If you need to use the if statement, you can also do this:

  if (value == (Int32)value) { //Do stuff... return true; } else { //Do stuff... return false; } 

EDIT: I understand that this actually doesn't work. I thought that throwing Int32 would simply copy into the first 32 bits of the decimal, leaving all the remaining bits (and not throwing an exception), but alas, it did not work (not to mention that it would be wrong for all negative values).

+1
source

It depends on how many decimal places you have or really cares about. If you could say that I only have up to 3 decimal places, then the largest number you can save in int32 is int.MaxValue / 1000. If you only work with positive numbers, you can get a larger number using uint. In any case, the way to do this is to sequentially reserve space for the decimal fraction and use * 1000 to encode them and / 1000 to decode them to / from the decimal number.

+1
source

Could you just do something like:

 if(Decimal.ToInt32(value) == value) { return true; } 

Not a .net specialist, but I think that should be all that is required. In addition, your two comparison operators must be β€œor equal,” since the min / max values ​​are also valid.

Edit: as noted in the comment, this will throw an exception. You can try to catch the exception and return false, but at this point, it will most likely be much faster to perform min / max testing.

0
source

No need for "valueAsInt =". I believe (Decimal.ToInt32 (value) == value)) gets the same result with one lesser purpose. Are you using valueAsInt as some output parameter?

0
source

Source: https://habr.com/ru/post/1308372/


All Articles