Asked by:
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
- Edited by leshay Sunday, April 9, 2017 2:58 PM Removed redundant and added default start fraction
- Proposed as answer by Cherry BuMicrosoft contingent staff Wednesday, April 19, 2017 9:10 AM
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 -
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
- Edited by rrrglyn Sunday, April 9, 2017 2:46 PM
- Merged by Reed KimbleMVP Sunday, April 9, 2017 2:59 PM duplicate
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 -
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
- Proposed as answer by Reed KimbleMVP Sunday, April 9, 2017 6:08 PM
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 -
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 -
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