Home > Software design >  IEnumerable method return squared int
IEnumerable method return squared int

Time:07-27

I am new to C# and found a method I can't quite finish making work. The method is supposed to take an array and return it with all integers squared.

What I don't understand is the <long> return type or why it would be needed and the fact that if an item that is more than int's MaxValue is passed, then the method doesn't change it in any way when it's supposed to return it as 0.

What I want is if an array like new long[] {4294967296, 4295098369, 4611686014132420609} is passed to it, it would return {0, 0, 0}

using System;
using System.Collections.Generic;
using System.Linq;

namespace EnumerableTask
{
    public class EnumerableManipulation
    {
        public IEnumerable<long> GetSquareSequence(IEnumerable<int> data)
        {
        /// <summary>Transforms integer sequence to its square sequence
        /// <param name="data">Source int sequence.</param>
        ///   Returns sequence of squared items.
            foreach (int item in data)
            {
                if (item == null)
                {
                    yield return 0;
                }                
                else if (item > int.MaxValue)
                {
                    yield return 0;
                }
                yield return item * item;
///For some reason just returns an item's value if it's more than int.MaxValue. Why?
            }
        }
    }
}

CodePudding user response:

if (item == null)

primitive types like int cannot be null, so this is redundant.

 else if (item > int.MaxValue)

An int cannot be larger than int.MaxValue. Perhaps you intended to tale a list of long? i.e. GetSquareSequence(IEnumerable<long> data) ? Otherwise you should not need that check.

When using any arithmetic operation on values you may run the risk of overflow, i.e. that the result is larger than the number of bits used to represent the value. This is especially an issue when multiplying large numbers. But since a long is twice as many bits, you should not need any overflow checking. So your whole code should be possible to replace with

foreach (long item in data)
{
    yield return item * item;
}

or just

var squared list = myList.Select(i => (long)i * i);

If you want to use the same return type as input type with overflow checking, you might want to use checked expressions to find such cases and handle them somehow.

CodePudding user response:

You have integer overflow on item * item, to prevent it cast item before multiplication:

// static : we don't want "this" here, so we can declare it as static 
public static IEnumerable<long> GetSquareSequence(IEnumerable<int> data)
{
    // the method is public we should validate user input
    if (data == null)
        throw new ArgumentNullException(nameof(data)); // or yield break;

    // long item  - we should multiply longs, not ints:
    // item is long; int.MaxValue * int.MaxValue < long.MaxValue   
    foreach (long item in data)
        yield return item * item; 
}

Please note, that both of your conditions are of no use: if (item == null) {...} will never be true (since int is struct and thus can't be null); if (item > int.MaxValue) will never be true since int value can't be beyond its own maximum value

CodePudding user response:

The item can not be larger than int.MaxValue because data type of item is int and the maximum value of int is exactly int.MaxValue.

If you want pass larger value than int you must use larger data type. Don't know your case in detail, but using IEnumerable<long> instead of IEnumerable<int> may be to solution for you.

  • Related