C# trying to fill up a binary number to 4 digit blocks

I have a base-n-converter and I wanted it to output all values in 4 digit blocks (1111 -> 1111, 101 -> 0101, 110101 -> 00110101). For this, I made this piece in vscode to try and make it work.

using System;

namespace Test
{
    using static intUtilities;
    class Program
    {
        static void Main(string[] args)
        {
            string number = "";
            int[] wholenumbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
            for(;;)
            {
                Console.WriteLine("enter binary number");
                number = Console.ReadLine();
                Console.WriteLine("is number length divisible by 4? " + Contains(wholenumbers, number.Length/4f)); 
                Console.WriteLine(number.Length/4f);
                while(!Contains(wholenumbers, number.Length/4f))
                {
                    number = "0" + number;
                }
                Console.WriteLine(number);
                Console.ReadLine();
            }
        
        }
    }
    public class intUtilities
    {
        public static bool Contains(int[] array, float number)
        {
            foreach(int i in array)
            {
                if(i == number)
                {
                return true;
                }
                else {return false;}
            }
            return false;
        }
    }
}

For inputting 111, I am expecting an output of 0111, which does happen, but if I input 111111, I am expecting 00111111, but there is no output. When executing the while loop, it should catch the moment when numbers.Length / 4 is "2" (which is when therre would be 8 digits) and break the loop, but for some reason, it doesnt and keeps on adding zeros to the string. It even reads out numbers.Length / 4 as "2" at some point but doesnt break the loop. The code only seems to work for a target size of 4 digits, where numbers.Length / 4 would be "1". Is there a way to correct that? Or even an easier workaround?

4 answers

  • answered 2022-01-23 02:54 Phillip Ngan

    There are a number of "interesting" issues with this code, but to answer your immediate question, you need to remove the else {return false;} line. This prevents you from searching over every element in the wholeNumbers array - or more specifically, you only query the first element in the wholeNumbers array (which is the value 1) which is why the code only works correctly for the first 4-bit block of binary digits.

    In the spirit of your approach, a possible implementation is:

    void Main()
    {
        string number = "";
        Console.WriteLine("enter binary number");
        number = Console.ReadLine();
        while (number.Length % 4 != 0)
        {
            number = "0" + number;
        }       
        Console.WriteLine(number);
    }
    

  • answered 2022-01-23 02:59 John Glenn

    You can use the modulus function to determine the remainder of one number (the string length) divided by another number (4). The entire effect can be shortened to this:

    // find how many characters don't fit into a block of four
    int leftovers = numbers.Length % 4;
    
    // determine how many numbers to pad
    int padding =
        (4 - leftovers) // this is the number of characters we have to add to get an even group of 4
        % 4; // this will ensure that if leftovers is 0, then instead of padding 4 characters we don't pad any
    
    // pad the string
    string displayMe = numbers.PadLeft(numbers.Length + padding, '0');
    

  • answered 2022-01-23 06:43 Johan Donne

    The original question ('why doesn't this work') is answered by Phillip Ngan. Just fyi the correct result can be gotten in a simple calculation without a loop:

    void Main
    {
       Console.WriteLine("enter binary number"); 
       string number = Console.ReadLine();
    
       int padLength = (4 - (number.Length % 4)) % 4;
       number = "000".Substring(0, padLength)+number;
    
       Console.WriteLine(number);
    }
    

    edit: Just noticed this is simply a variant for the solution proposed by John Glenn.

  • answered 2022-01-23 07:41 Caius Jard

    Or even an easier workaround?

    Relying on the usual "round an integer up to the nearest N" of "integer, divide by N, add one and times by N" we can use this to pad the left of the binary string out to the next "multiple of 4" up from the current length

    var x= "01111";
    
    var y = x.PadLeft(((x.Length/4)+1)*4, '0');
    

    y is "00001111";

    If you don't like all the parentheses you can use precedence to the same effect

    .PadLeft(x.Length/4*4+4, '0');
    

    Hopefully most future readers of the code will remember their high school maths lessons 😀

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum