none
Need Help :How to write a windows form app that reduces fractions to simpliest form

    Question

  • Hi I'm using Visual Studio 2013 and I was wondering how to write a program to allow the user to enter a fraction and then display that fraction in a list box with the reduced form of the fraction right next to it. An example of this would be if the user entered "2/4" the list box would output "2/4 = 1/2." I've been looking up online how to do this and none of them seem to work. I appreciate any help.

    • Edited by rrrglyn Saturday, April 8, 2017 5:15 PM
    Saturday, April 8, 2017 4:51 PM

All replies

  • Hi

    Here is a very simplified example of my first line of thought.

    ' Form1 with TextBox1, ListBox1 ' and Button1 ' no error checking included ' quick and dirty offering Option Strict On Option Explicit On Option Infer Off Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

            ListBox1.Items.Clear()

    Dim s As String = TextBox1.Text Dim a() As String = Split(s, "/") Dim top As Integer = CInt(a(0)) Dim bott As Integer = CInt(a(1)) Dim res As Double = top / bott For divisor As Integer = 1 To bott If bott Mod divisor = 0 Then If top Mod divisor = 0 Then ListBox1.Items.Add((top \ divisor).ToString & "/" & (bott \ divisor).ToString) End If End If Next End Sub End Class



    Regards Les, Livingston, Scotland


    • Edited by leshay Saturday, April 8, 2017 5:41 PM added ListBox.Items.Clear
    Saturday, April 8, 2017 5:29 PM
  • Thanks so much! it seems to seems to work fine with the one text box. The only thing is how can I get it to output the in the format "2/4 = 1/2". I'm a little new to this software.
    Saturday, April 8, 2017 6:06 PM
  • Thanks so much! it seems to seems to work fine with the one text box. The only thing is how can I get it to output the in the format "2/4 = 1/2". I'm a little new to this software.

    Hi

    You mentioned a Listbox in your original question so that is what I used. The listbox is not actually needed, but here is some code that will display the 'simplest' answer in Label1 in the format you ask for. If you don't want the ListBox, you could set its Visible property to False (or, better still, remove it and just use an array in the code)

    ' Form1 with TextBox1, ListBox1
    ' Button1 and Label1
    ' no error checking included
    ' quick and dirty offering
    Option Strict On
    Option Explicit On
    Option Infer Off
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ' test fraction
            TextBox1.Text = "2970/1710720"
        End Sub
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            ListBox1.Items.Clear()
            Dim s As String = TextBox1.Text
            Dim a() As String = Split(s, "/")
            Dim top As Integer = CInt(a(0))
            Dim bott As Integer = CInt(a(1))
            For divisor As Integer = 1 To bott
                If bott Mod divisor = 0 Then
                    If top Mod divisor = 0 Then
                        ListBox1.Items.Add((top \ divisor).ToString & "/" & (bott \ divisor).ToString)
                    End If
                End If
            Next
            Label1.Text = TextBox1.Text & " = " & ListBox1.Items(ListBox1.Items.Count - 1).ToString
        End Sub
    End Class



    Regards Les, Livingston, Scotland


    Saturday, April 8, 2017 6:11 PM
  • Thank You!
    Saturday, April 8, 2017 6:31 PM
  • Dug this up from some old code.  I think Luc was working with me on this for a Fraction class a long time ago.  Here's an excerpt for dealing with fraction reduction:

        Private Shared ReadOnly Primes As Decimal() = {3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}
    
        Public Shared Sub ReduceByGcd(ByRef fractionNumerator As Integer, ByRef fractionDenominator As Integer)
            Dim gdc As Integer = GetGreatestCommonDivisor(fractionNumerator, fractionDenominator)
            If gdc = 1 Then
                Dim mantissa As Decimal = CDec(System.Math.Abs(fractionNumerator / fractionDenominator))
                For Each prime As Decimal In Primes
                    Dim theta As Decimal = 1D / prime
                    If (mantissa / theta) Mod 1D > 0.99 Then
                        Dim deltaN As Integer = CInt(Decimal.Ceiling(CDec(fractionNumerator / fractionDenominator / theta)))
                        Dim deltaD As Integer = CInt(prime)
                        If deltaN = deltaD Then deltaN = 1 : deltaD = 1
                        fractionNumerator = deltaN
                        fractionDenominator = deltaD
                        Exit Sub
                    End If
                Next
            ElseIf gdc > 1 Then
                fractionNumerator = CInt(Decimal.Ceiling(CDec(fractionNumerator / gdc)))
                fractionDenominator = CInt(Decimal.Ceiling(CDec(fractionDenominator / gdc)))
            End If
        End Sub
    
        Public Shared Function GetGreatestCommonDivisor(number1 As Integer, number2 As Integer) As Integer
            number1 = System.Math.Abs(number1)
            number2 = System.Math.Abs(number2)
            Dim delta As Integer
            If number1 > number2 Then
                delta = number1
                number1 = number2
                number2 = delta
            End If
            While number1 > 0
                delta = number2 Mod number1
                number2 = number1
                number1 = delta
            End While
            Return number2
        End Function
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Dim parts() As String = TextBox2.Text.Split("/"c)
            Dim numer As Integer = Integer.Parse(parts(0))
            Dim denom As Integer = Integer.Parse(parts(1))
            ReduceByGcd(numer, denom)
            TextBox2.Text = $"{numer}/{denom}"
        End Sub

     

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Saturday, April 8, 2017 6:58 PM
    Moderator
  • Hello,

    I've been working on a program to reduce fractions in visual studio 2013. The program works fine except I cant figure out how to get it to output the answer in whole numbers not in fraction form (If its appropriate e.g. "7/7 = 1" or "0/8 =0")

    Any help is appreciated

    here's what I have right now:

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Public Class Form1
    
        Private Sub btncalc_Click(sender As Object, e As EventArgs) Handles btncalc.Click
            'Declareing the varuables as string
            Dim s As String = TextBox1.Text
            'Decareing text as string
            Dim a() As String = Split(s, "/")
            'Declaring the numerator and denominator as integers
            Dim top As Integer = CInt(a(0))
            Dim bott As Integer = CInt(a(1))
            'Declare the result as a Double
            Dim res As Double = top / bott
            For divisor As Integer = 1 To bott
                If bott Mod divisor = 0 Then
                    If top Mod divisor = 0 Then
                lstout.Items.Add((top \ divisor).ToString & "/" & (bott \ divisor).ToString)
                    End If
                End If
    
            Next
            ListBox1.Items.Add(TextBox1.Text & " = " & lstout.Items(lstout.Items.Count - 1).ToString)
        End Sub
    
    End Class

    Thanks



    Sunday, April 9, 2017 2:44 PM
  • Please continue with the existing thread on this topic.  I will merge the threads.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Sunday, April 9, 2017 2:57 PM
    Moderator
  • Hi

    Here is my original code amended for the cases you mention. (also removed the redundant line ' res as Double')

    ' Form1 with TextBox1, ListBox1
    ' Button1 and Label1
    ' no error checking included
    ' quick and dirty offering
    Option Strict On
    Option Explicit On
    Option Infer Off
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ' test fraction
            TextBox1.Text = "2970/1710720"
        End Sub
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            ListBox1.Items.Clear()
            Dim s As String = TextBox1.Text
            Dim a() As String = Split(s, "/")
            Dim top As Integer = CInt(a(0))
            Dim bott As Integer = CInt(a(1))
            If top = 0 Then
                Label1.Text = "0"
                Exit Sub
            End If
            If bott = 0 Then
                Label1.Text = "Infinity and beyond"
                Exit Sub
            End If
            If top = bott Then
                Label1.Text = "1"
                Exit Sub
            End If
            For divisor As Integer = 1 To bott
                If bott Mod divisor = 0 Then
                    If top Mod divisor = 0 Then
                        ListBox1.Items.Add((top \ divisor).ToString & "/" & (bott \ divisor).ToString)
                    End If
                End If
            Next
    
            Label1.Text = TextBox1.Text & " = " & ListBox1.Items(ListBox1.Items.Count - 1).ToString
        End Sub
    End Class


    Regards Les, Livingston, Scotland

    Sunday, April 9, 2017 3:16 PM
  • Note that the primary difference between the two solutions shown is one of execution time.  For a routine which is executed occasionally, on-demand by a user, the execution time difference is probably negligible.  If however you were to perform the reduction many times in succession, then the execution time difference would quickly accumulate to noticeable levels.

    On my machine, the straight-forward solution provided by Leshay takes an average of about 5.6 milliseconds to execute with the example fraction 2970/1710720.  The solution I posted takes an average of 0.028 milliseconds to reduce the same fraction.  This includes a minor refactoring of Leshay's code to remove the ListBox item addition on each iteration and only store the last GDC found (before that change the code averaged 7.8ms).

    As you can see, the difference in execution speed is significant, but would only be a real factor in overall application execution speed if performed repeatedly.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Sunday, April 9, 2017 4:08 PM
    Moderator
  • Great! thanks again!
    Sunday, April 9, 2017 4:31 PM
  • Great! thanks again!

    If your problem is resolved, please close the thread by clicking the Mark as answer link at the bottom of one or more appropriate posts.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Sunday, April 9, 2017 6:08 PM
    Moderator
  • Hi rrrglyn,

    Please remember to close your threads by marking helpful posts as answer, it will be beneficial to other communities who have the same issue.

    Thanks for your understanding.

    Best Regards,

    Cherry Bu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, April 10, 2017 2:25 AM
    Moderator