Thursday, September 26, 2013

C#: ForEach with an IEnumerable range of UInt64 (ulong) values


        /// <summary>
        ///     Example: foreach (var i in 10240.To(20448)) { Console.WriteLine(i); }
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="step"></param>
        /// <returns></returns>
        public static IEnumerable<UInt64> To( this int from, UInt64 to, UInt64 step = 1 ) {
            if ( from < 0 ) {
                throw new ArgumentOutOfRangeException( "from", "From must be equal to or greater than zero." );
            }
 
            if ( step == 0UL ) {
                step = 1UL;
            }
 
            var reFrom = ( UInt64 )from;        //bug here is the bug if from is less than zero
 
            if ( from <= ( decimal )to ) {
                for ( var ul = reFrom; ul <= to; ul += step ) {
                    yield return ul;
                    if ( ul == UInt64.MaxValue ) { yield break; }   //special case to deal with overflow
                }
            }
            else {
                for ( var ul = reFrom; ul >= to; ul -= step ) {
                    yield return ul;
                    if ( ul == UInt64.MinValue ) { yield break; }   //special case to deal with overflow
                }
            }
        }
 
        /// <summary>
        ///     Example: foreach (var i in 10240.To(20448)) { Console.WriteLine(i); }
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="step"></param>
        /// <returns></returns>
        public static IEnumerable<UInt64> To( this UInt64 from, UInt64 to, UInt64 step = 1 ) {
            if ( step == 0UL ) {
                step = 1UL;
            }
 
            if ( from <= to ) {
                for ( var ul = from; ul <= to; ul += step ) {
                    yield return ul;
                    if ( ul == UInt64.MaxValue ) { yield break; }   //special case to deal with overflow
                }
            }
            else {
                for ( var ul = from; ul >= to; ul -= step ) {
                    yield return ul;
                    if ( ul == UInt64.MinValue ) { yield break; }   //special case to deal with overflow
                }
            }
        }

No comments: