Что нового

Решение квадратных уравнений: обыкновенные дроби.

trizorka

Новичок
Сообщения
53
Репутация
4
Доброго времени суток.
Написал скрипт, которые решает квадратное уравнение вида a*x^2+b*x+c=0. Autoit работает с десятичными дробями, а вот с обыкновенными вроде нет, а я хочу, что бы ответы были представлены обыкновенными дробями или выражениями. Но возникла проблема с уравнением 12*x^2-7*x+1=0. как я не крутил - число под корнем десятичная дробь. Подскажите, что я не учел?
Код:
Local $R = ""
$win = GUICreate("",200 , 100)
$a = GUICtrlCreateInput("12", 10, 10, 150, 17)
$b = GUICtrlCreateInput("-7", 10, 30, 150, 17)
$c = GUICtrlCreateInput("1", 10, 50, 150, 17)
$button = GUICtrlCreateButton("GO", 100, 70, 50)

GUISetState()
While True
Global  $msg = GUIGetMsg()
If $msg =-3 Then Exit 
If $msg = $button Then
go()
EndIf
WEnd

func go()
Local $An = Number(GUICtrlRead($a))
Local $Bn = Number(GUICtrlRead($b))
Local $Cn = Number(GUICtrlRead($c))

Global $A1 = - $Bn/$An/2
Global $A2 = - $Bn/$An/2
Global $e = $A1^2 - $Cn/$An
				If $e > 0 Then
							_q()
							If StringIsInt(Sqrt($e)) = 1 Then
								If StringIsInt(Abs($A1)) = 1 And StringIsInt(Abs($A2)) = 1 Then
											$A1 = $A1 + Sqrt($e)
											$A2 = $A2 - Sqrt($e)		
											Else							
											$A1 &= " + " & Sqrt($e)
											$A2 &= " - " & Sqrt($e)
								EndIf
							ElseIf StringIsInt(Sqrt($e)) = 0 Then
								If StringIsInt($e) = 0 Then
											For $tr = 1 To 100000 Step +1
											$jr = $e*$tr
											If StringIsInt($jr) = 1 Then
											$e = $jr & "/" & $tr
												ExitLoop
											EndIf
											Next			
								EndIf
								$A1 &= " + " & "Sqrt" & "(" & $e & ")"
								$A2 &= " - " & "Sqrt" & "(" & $e & ")"
							EndIf
				ElseIf $e < 0 Then
							_q()
							If StringIsInt(Sqrt(Abs($e))) = 1 Then
							$A1 &= " + "  & Sqrt(Abs($e)) & "*i"
							$A2 &= " - "  & Sqrt(Abs($e)) & "*i"
							Else
								If StringIsInt(Abs($e)) = 0 Then
											For $t = 1 To 100000
											$j = $e*$t
											If StringIsInt($j) = 1 Then
											$e = $j & "/" & $t
												ExitLoop
											EndIf
											Next	
								EndIf
							EndIf			
							$A1 &= " + " & "Sqrt" & "(" & -$e & ")*i"
							$A2 &= " - " & "Sqrt" & "(" & -$e & ")*i"
				ElseIf Abs($e) = 1	Then
							_q()
							$A1 &= " + i"
							$A2 &= " - i" 
				EndIf
							$R = ConsoleWrite("X1 = " & $A1 & @CR & "X2 = " & $A2 & @CR)
							Return $R
EndFunc

Func _q()
If StringIsInt(Abs($A1)) = 0 Then
			For $m = 1 To 100000
			$o = $A1*$m
			If StringIsInt($o) = 1 Then
				$A1 = $o & "/" & $m
				ExitLoop
			EndIf
			Next
ElseIf StringIsInt(Abs($A1)) = 1 Then	
			Return $A1			
EndIf
If StringIsInt(Abs($A2)) = 0 Then
			For $v = 1 To 100000
			$y = $A2*$v
			If StringIsInt($y) = 1 Then
				$A2 = $y & "/" & $v
				ExitLoop
			EndIf
			Next
ElseIf StringIsInt(Abs($A2)) = 1 Then	
			Return $A2								
EndIf
;~ If StringIsInt(Abs($e)) = 0 Then
;~ 			For $t = 1 To 100000
;~ 			$j = $e*$t
;~ 			If StringIsInt($j) = 1 Then
;~ 			$e = $j & "/" & $t
;~ 				ExitLoop
;~ 			EndIf
;~ 			Next	
;~ EndIf
EndFunc
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Re: Квадратное уравнение

Предупреждение За нарушение правил форума (пункт Б.5):
Имя темы должно нести смысловую нагрузку (отражать суть вопроса/проблемы)
Правильно сформулированное название темы привлекает больше внимания, и шансы получить конкретный ответ увеличиваются.


Данные правила могут пополняться локальными правилами раздела.
Как правильно называть темы

"Квадратное уравнение" - это неприемлемое название темы, переименуйте тему иначе она будет закрыта, а вам возможно будет выдан бан на несколько дней.

С уважением, ваш Глобальный модератор.
 
Автор
T

trizorka

Новичок
Сообщения
53
Репутация
4
переписал скрипт сначала, внес поправки, но проблема осталась...
Код:
$win = GUICreate("",200 , 110)
$aq = GUICtrlCreateInput(12, 10, 10, 150, 17)
$bq = GUICtrlCreateInput(-7, 10, 30, 150, 17)
$cq = GUICtrlCreateInput(1, 10, 50, 150, 17)
$button = GUICtrlCreateButton("GO", 100, 90, 50)
GUISetState()
While True
	Sleep(100)
Global  $msg = GUIGetMsg()
If $msg = -3 Then Exit 
If $msg = $button Then
	go()
EndIf
WEnd
Func go()
Local $a = Number(GUICtrlRead($aq))
Local $b = Number(GUICtrlRead($bq))
Local $c = Number(GUICtrlRead($cq))
Local $e = 0.25*$b^2/$a^2 - $c/$a
	If $e > 0 And IsInt(Sqrt($e)) = 1 And IsInt(Abs(0.5*$b/$a)) = 1 Then
	$x1 = -0.5*$b/$a + Sqrt($e)
	$x2 = -0.5*$b/$a - Sqrt($e)
	ElseIf $e > 0 And IsInt(Sqrt($e)) = 0 And IsInt(Abs(0.5*$b/$a)) = 1 Then
		For $p = 1 To 10^5
			$p1 = $e*$p
			If IsInt($p1) = 1 Then
				$e1 = $p1 & "/" & $p
					If 	$p = 1 Then
						$e1 = $p1
						ExitLoop
					EndIf			
				ExitLoop
			EndIf
		Next
	$x1 = -0.5*$b/$a
	$x1 &= " + Sqrt(" & $e1 & ")" 
	$x2 = -0.5*$b/$a
	$x2 &= " - Sqrt(" & $e1 & ")" 
	ElseIf $e > 0 And IsInt(Sqrt($e)) = 1 And IsInt(Abs(0.5*$b/$a)) = 0 Then	
		For $o = 1 To 10^5
			$o1 = 0.5*$b/$a * $o
			If IsInt(Abs($o1)) = 1 Then
				$AA = $o1 & "/" & $o
				ExitLoop
			EndIf
		Next
	$x1 = - $o1 & "/" & $o
	$x1 &= " + " & Sqrt($e)
	$x2 = - $o1 & "/" & $o
	$x2 &= " - " & Sqrt($e)
	ElseIf $e > 0 And IsInt(Sqrt($e)) = 0 And IsInt(Abs(0.5*$b/$a)) = 0 Then
		For $u = 1 To 10^5 Step +1
			$u1 = $e*$u
			If IsInt($u1) = 1 Then
			 $e = $u1 &  "/" & $u
					If 	$u = 1 Then
						$e = $u1
					EndIf			
				ExitLoop
			EndIf
		Next	
		For $y = 1 To 100000
			$y1 = 0.5*$b/$a * $y
			If IsInt(Abs($y1)) = 1 Then
				$x1 = - $y1 & "/" & $y
				$x2 = - $y1 & "/" & $y
				ExitLoop
			EndIf
		Next
	$x1 &= " + Sqrt(" & $e & ")" 
	$x2 &= " - Sqrt(" & $u1 & "/" & $u & ")" 	
	ElseIf $e < 0 And IsInt(Sqrt(Abs($e))) = 1 And IsInt(Abs(0.5*$b/$a)) = 1 Then	
	$x1 = -0.5*$b/$a
	$x1 &= " + " & Sqrt($e) & "*i"
	$x2 = -0.5*$b/$a
	$x2 &= " - " & Sqrt($e) & "*i"
	ElseIf $e < 0 And IsInt(Sqrt(Abs($e))) = 0 And IsInt(Abs(0.5*$b/$a)) = 1 Then	
		For $t = 1 To 10^5
			$t1 = $e*$t
			If IsInt(Abs($t1)) = 1 Then
				$e3 = $t1 & "/" & $t
						If 	$t = 1 Then
						$e3 = $t1
						ExitLoop
					EndIf			
				ExitLoop
			EndIf
		Next
	$x1 = -0.5*$b/$a
	$x1 &= " + Sqrt(" & $e3 & ")*i" 
	$x2 = -0.5*$b/$a
	$x2 &= " - Sqrt(" & $e3 & ")*i" 
	ElseIf $e < 0 And IsInt(Sqrt(Abs($e))) = 1 And IsInt(Abs(0.5*$b/$a)) = 0 Then
		For $r = 1 To 10^5
			$r1 = 0.5*$b/$a * $r
			If IsInt(Abs($r1)) = 1 Then
				$AAAA = $r1 & "/" & $r
				ExitLoop
			EndIf
		Next
	$x1 = - $r1 & "/" & $r
	$x1 &= " + " & Sqrt($e) & "*i"
	$x2 = - $r1 & "/" & $r
	$x2 &= " - " & Sqrt($e) & "*i"
	ElseIf $e < 0 And IsInt(Sqrt(Abs($e))) = 0 And IsInt(Abs(0.5*$b/$a)) = 0 Then
		For $w = 1 To 10^5
			$w1 = $e*$w
			If IsInt(Abs($w1)) = 1 Then
				$e4 = $w1 & "/" & $w
						If 	$w = 1 Then
						$e4 = $w1
						ExitLoop
					EndIf			
				ExitLoop
			EndIf
		Next	
		For $q = 1 To 10^5
			$q1 = 0.5*$b/$a * $q
			If IsInt(Abs($q1)) = 1 Then
				$AAAAA = $q1 & "/" & $q
				ExitLoop
			EndIf
		Next	
	$x1 = - $q1 & "/" & $q
	$x1 &= " + Sqrt(" & Abs($e4) & ")*i" 
	$x2 = - $q1 & "/" & $q
	$x2 &= " - Sqrt(" & Abs($e4) & ")*i"
	ElseIf $e = 0 And IsInt(Abs(0.5*$b/$a)) = 0 Then
		For $l = 1 To 10^5
			$l1 = 0.5*$b/$a * $l
			If IsInt(Abs($l1)) = 1 Then
				$AAAAAA = $y1 & "/" & $l
				ExitLoop
			EndIf
		Next	
	$x1 = - $y1 & "/" & $l
	$x2 = - $y1 & "/" & $l
	ElseIf $e = 0 And IsInt(Abs(0.5*$b/$a)) = 1 Then
	$x1 = -0.5*$b/$a
	$x2 = -0.5*$b/$a
	EndIf
ConsoleWrite("x1  = " & $x1 & @CRLF & "x2  = " & $x2 & @CRLF)
EndFunc
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Читаем тут "Преобразование между разными форматами записи"
http://ru.wikipedia.org/wiki/%C4%F0%EE%E1%FC_(%EC%E0%F2%E5%EC%E0%F2%E8%EA%E0)

Потом читаем тут
http://younglinux.info/algorithm/euclidean

И переходим к весьма интересной для школьного возраста задачи - написанию скрипта алгоритма Евклида.
:IL_AutoIt_1:
 
Автор
T

trizorka

Новичок
Сообщения
53
Репутация
4
первая ссылка для меня вообще неочем...а вот про Евклида интересно, в автоите есть фунции которые с остатком работают... щас буду експерементировать...
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
первая ссылка для меня вообще неочем...

Как ни о чем ?! :shok:
А ты догадался кликнуть на
http://ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D0%B8%D0%BE%D0%B4%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%B4%D1%80%D0%BE%D0%B1%D1%8C#.D0.9F.D0.B5.D1.80.D0.B8.D0.BE.D0.B4.D0.B8.D1.87.D0.B5.D1.81.D0.BA.D0.B8.D0.B5_.D0.B4.D0.B5.D1.81.D1.8F.D1.82.D0.B8.D1.87.D0.BD.D1.8B.D0.B5_.D0.B4.D1.80.D0.BE.D0.B1.D0.B8

и прочитать раздел "Перевод из десятичной дроби в обыкновенную" ?

А ну решай уравнение
77*x*x - x - 6 = 0
 
Автор
T

trizorka

Новичок
Сообщения
53
Репутация
4
мне не надо переводит с десятичной в обычную дробь, а надо что бы программа сама записала, если надо, в обыкновенную дробь. и зачем уравнение мне решать?
Переписал еще раз скрипт, ошибок в вычисление вроде не увидел
Код:
$win = GUICreate("",200 , 110)
$aq = GUICtrlCreateInput(77, 10, 10, 150, 17)
$bq = GUICtrlCreateInput(16, 10, 30, 150, 17)
$cq = GUICtrlCreateInput(60, 10, 50, 150, 17)
$button = GUICtrlCreateButton("GO", 100, 90, 50)
GUISetState()
While True
    Sleep(100)
Global  $msg = GUIGetMsg()
If $msg = -3 Then Exit
If $msg = $button Then
    go()
EndIf
WEnd

Func go()
$a = Number(GUICtrlRead($aq))
$b = Number(GUICtrlRead($bq))
$c = Number(GUICtrlRead($cq))
	$s = $b^2 - 4*$a*$c
	$e = 0.5*Sqrt(Abs($s))/$a
	$f = - 0.5*$b/$a
If $s > 0 And IsInt($e) = 1 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 1 And IsInt($f) = 1 Then
	$x1 = $f + $e
	$x2 = $f - $e
ElseIf $s > 0 And IsInt($e) = 1 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 1 And IsInt($f) = 0 Then
	For $i = 1 To 10^5
		$u = $f*$i
		If IsInt($u) = 1 Then
		$f = $u&"/"&$i
			ExitLoop
		EndIf
	Next
	$x1 = $f & " + " & $e
	$x2 = $f & " - " & $e
ElseIf $s > 0 And IsInt($e) = 1 And IsInt($s)*IsInt(Sqrt($s)) = 0 And IsInt($f) = 1 Then
	$e = "Sqrt(" & $b^2 - 4*$a*$c & ")" & "/" & 2*$a
	$x1 = $f & " + " & $e
	$x2 = $f & " - " & $e
ElseIf $s > 0 And IsInt($e) = 0 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 1 And IsInt($f) = 1 Then
	$e = Sqrt($s) & "/" & 2*$a
	$x1 = $f & " + " & $e
	$x2 = $f & " - " & $e
ElseIf $s > 0 And IsInt($e) = 1 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 0 And IsInt($f) = 0 Then
	For $i = 1 To 10^5
		$u = $f*$i
		If IsInt($u) = 1 Then
		$f = $u&"/"&$i
			ExitLoop
		EndIf
	Next
	$e = "Sqrt(" & $b^2 - 4*$a*$c & ")" & "/" & 2*$a
	$x1 = $f & " + " & $e
	$x2 = $f & " - " & $e
ElseIf $s > 0 And IsInt($e) = 0 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 1 And IsInt($f) = 0 Then
	For $i = 1 To 10^5
		$u = $f*$i
		If IsInt($u) = 1 Then
		$f = $u&"/"&$i
			ExitLoop
		EndIf
	Next
	$e = Sqrt($s) & "/" & 2*$a
	$x1 = $f & " + " & $e
	$x2 = $f & " - " & $e
ElseIf $s > 0 And IsInt($e) = 0 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 0 And IsInt($f) = 1 Then
	$e = "Sqrt(" & $b^2 - 4*$a*$c & ")" & "/" & 2*$a
	$x1 = $f & " + " & $e
	$x2 = $f & " - " & $e
ElseIf $s > 0 And IsInt($e) = 0 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 0 And IsInt($f) = 0 Then
	For $i = 1 To 10^5
		$u = $f*$i
		If IsInt($u) = 1 Then
		$f = $u&"/"&$i
			ExitLoop
		EndIf
	Next
	$e = "Sqrt(" & $b^2 - 4*$a*$c & ")" & "/" & 2*$a
	$x1 = $f & " + " & $e
	$x2 = $f & " - " & $e
ElseIf $s < 0 And IsInt($e) = 1 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 1 And IsInt($f) = 1 Then
	$x1 = $f & " + " & $e & "*i"
	$x2 = $f & " - " & $e & "*i"
ElseIf $s < 0 And IsInt($e) = 1 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 1 And IsInt($f) = 0 Then
	For $i = 1 To 10^5
		$u = $f*$i
		If IsInt($u) = 1 Then
		$f = $u&"/"&$i
			ExitLoop
		EndIf
	Next
	$x1 = $f & " + " & $e & "*i"
	$x2 = $f & " - " & $e & "*i"
ElseIf $s < 0 And IsInt($e) = 1 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 0 And IsInt($f) = 1 Then
	$e = "Sqrt(" & Abs($s) & ")" & "/" & 2*$a
	$x1 = $f & " + " & $e & "*i"
	$x2 = $f & " - " & $e & "*i"
ElseIf $s < 0 And IsInt($e) = 0 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 1 And IsInt($f) = 1 Then
	$e = Sqrt(Abs($s)) & "/" & 2*$a
	$x1 = $f & " + " & $e & "*i"
	$x2 = $f & " - " & $e & "*i"
ElseIf $s < 0 And IsInt($e) = 1 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 0 And IsInt($f) = 0 Then
	For $i = 1 To 10^5
		$u = $f*$i
		If IsInt($u) = 1 Then
		$f = $u&"/"&$i
			ExitLoop
		EndIf
	Next
	$e = "Sqrt(" & Abs($s) & ")" & "/" & 2*$a
	$x1 = $f & " + " & $e & "*i"
	$x2 = $f & " - " & $e & "*i"
ElseIf $s < 0 And IsInt($e) = 0 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 0 And IsInt($f) = 1 Then
	$e = "Sqrt(" & Abs($s) & ")" & "/" & 2*$a
	$x1 = $f & " + " & $e & "*i"
	$x2 = $f & " - " & $e & "*i"
ElseIf $s < 0 And IsInt($e) = 1 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 0 And IsInt($f) = 0 Then
	For $i = 1 To 10^5
		$u = $f*$i
		If IsInt($u) = 1 Then
		$f = $u&"/"&$i
			ExitLoop
		EndIf
	Next
	$e = Sqrt(Abs($s)) & "/" & 2*$a
	$x1 = $f & " + " & $e & "*i"
	$x2 = $f & " - " & $e & "*i"
ElseIf $s < 0 And IsInt($e) = 0 And IsInt($s)*IsInt(Sqrt(Abs($s))) = 0 And IsInt($f) = 0 Then
	For $i = 1 To 10^5
		$u = $f*$i
		If IsInt($u) = 1 Then
		$f = $u&"/"&$i
			ExitLoop
		EndIf
	Next
	$e = "Sqrt(" & Abs($s) & ")" & "/" & 2*$a
	$x1 = $f & " + " & $e & "*i"
	$x2 = $f & " - " & $e & "*i"
ElseIf $s = 0 And IsInt($f) = 1 Then
	$x1 = $f
	$x2 = $f
ElseIf $s = 0 And IsInt($f) = 0 Then
	For $i = 1 To 10^5
		$u = $f*$i
		If IsInt($u) = 1 Then
		$f = $u&"/"&$i
			ExitLoop
		EndIf
	Next
	$x1 = $f
	$x2 = $f
EndIf
ConsoleWrite("x1 = " & $x1 & @CRLF & "x2 = " & $x2 & @CRLF)
EndFunc
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Фух, времени немного появилось. :Typing:
На самом деле задача меня довольно таки повеселила.
Может быть столо бы даже запустить её как конкурс... ;D

Код:
$N = 20 / 11

ConsoleWrite("десятичная дробь = " & $N & @CRLF)

$R = Ratio($N)

ConsoleWrite("целая часть = " & $R[0] & "  дробь = " & $R[1] & " / " & $R[2] & @CRLF)

;-------------------------------------------------------------------------------
; Функция преобразования десятичной дроби в рациональную
; 	Ratio( число )
; возвращает массив из трёх элементов
; $Res[0] = целая часть числа
; $Res[1] = числитель дробной части
; $Res[2] = знаменатель дробной части
; Если дробную часть не удалось преобразовать в рациональную дробь, то $Res[2] = 0
;-------------------------------------------------------------------------------

Func Ratio($X)

	Dim $Res[3]
	Local $y1, $y2, $s = String($X)
	Local $chislo = StringSplit($s, ".",2)
	$Res[0] = $chislo[0]
	Local $s_drob = $chislo[UBound($chislo)-1]
	Local $L = Floor(StringLen($s_drob)/2)

	For $i = $L To 0 Step -1
		$s1 = StringLeft($s_drob,$i)
		$s2 = $s1 & $s1
		If StringInStr($s_drob, $s2) = 1 Then ExitLoop
	Next

	If $s1 = "" Then
		$Res[1] = 0
		If UBound($chislo) > 1 Then $Res[1] = $chislo[1]
		$Res[2] = 0
		Return $Res
	EndIf

	$L = StringLen($s1)
	$s2 = ""
	For $i=1 To $L
		$s2 = $s2 & "9"
	Next

	$y1 = int($s1)
	$y2 = int($s2)
	$L = NOD($y1,$y2)
	$Res[1] = $y1 / $L
	$Res[2] = $y2 / $L
	Return $Res
EndFunc

Func NOD($x1, $x2)
	while $x1 > 0 and $x2 > 0
		If $x1 > $x2 Then
			$x1 = mod($x1,$x2)
		Else
			$x2 = mod($x2,$x1)
		EndIf
	WEnd
	Return $x1+$x2
EndFunc
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,590
Репутация
341
А ведь это обычная функция калькулятьров CASIO :smile: Они умеют преобразовывать дроби :smile:
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Да, помню писал такую функцию для калькулятора, не CASIO :smile: Очень помогала на тестировании по математике.

Вот, перевел на autoit.

Код:
#NoTrayIcon
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
$Form1 = GUICreate("Перевод десятичной дроби в обыкновенную", 419, 135, 350, 232)
$Label1 = GUICtrlCreateLabel("Label1", 32, 72, 136, 4, $SS_BLACKRECT)
$Input1 = GUICtrlCreateInput("0.624", 32, 48, 137, 21)
$Input2 = GUICtrlCreateInput("1", 32, 80, 137, 21)
$Label3 = GUICtrlCreateLabel("Label3", 248, 72, 136, 4, $SS_BLACKRECT)
$Input3 = GUICtrlCreateInput("", 248, 48, 137, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY))
$Input4 = GUICtrlCreateInput("", 248, 80, 137, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY))
$Button1 = GUICtrlCreateButton("=", 176, 64, 64, 25, $BS_DEFPUSHBUTTON)
$Label2 = GUICtrlCreateLabel("перевести", 176, 48, 66, 17)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Label4 = GUICtrlCreateLabel("Переводит и сокращает дроби вида 0.25 в 1/4", 32, 6, 356, 17)
$Label5 = GUICtrlCreateLabel("Впишите 1 в знаминатель если нужно просто перевести.", 32, 26, 294, 17)
$Label6 = GUICtrlCreateLabel("Десятичная:", 32, 104, 68, 17)
$Label7 = GUICtrlCreateLabel("", 104, 104, 284, 17)
GUISetState(@SW_SHOW)


While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $Label5
			GUICtrlSetData($Input2,1)
		Case $Button1
			$RCL5=GUICtrlRead($Input1)
			$RCL6=GUICtrlRead($Input2)
			If Not StringRegExp($RCL5,"(?m)^[\d-.]+$",0) Then
				GUICtrlSetState($Input1,$GUI_FOCUS)
				ContinueLoop
			EndIf
			If Not StringRegExp($RCL6,"(?m)^[\d-.]+$",0) Then
				GUICtrlSetState($Input2,$GUI_FOCUS)
				ContinueLoop
			EndIf
			$RCL9 = $RCL6
			$RCL8 = $RCL5
			GUICtrlSetData($Label7,$RCL5/$RCL6)
			While 1
				$b = Abs(Round(Int($RCL5 / $RCL6) * $RCL6 - $RCL5, 14))
				If $b = 0 Then ExitLoop
				$RCL5 = $RCL6
				$RCL6 = $b
			WEnd
			GUICtrlSetData($Input3,$RCL8 / $RCL6)
			GUICtrlSetData($Input4,$RCL9 / $RCL6)
	EndSwitch
WEnd
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
inververs,
как бы тест не пройден...
7d772e2d89b3.jpg



У меня получается
[box title=Console]десятичная дробь = 0.333333333333333
целая часть = 0 дробь = 1 / 3[/box]
;D
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Я в твоем попробывал
Код:
$N = 0.25 / 1
Получил: [box title=console]десятичная дробь = 0.25
целая часть = 0 дробь = 25 / 0[/box] :whistle:

Ну мой вариант с периодическими дробями не справляется
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
OffTopic:
Haskell'a на вас нет, с его Ratio типом данных ;D
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Получил:
consoleдесятичная дробь = 0.25
целая часть = 0 дробь = 25 / 0

Та не вопрос. Могу и сам проанализировать $Res[2] = 0 и обработать данные
Код:
$N = 0.25

ConsoleWrite("десятичная дробь = " & $N & @CRLF)

$R = Ratio($N)

ConsoleWrite("целая часть = " & $R[0] & "  дробь = " & $R[1] & " / " & $R[2] & @CRLF)

;-------------------------------------------------------------------------------
; Функция преобразования десятичной дроби в рациональную
; Ratio( число )
; возвращает массив из трёх элементов
; $Res[0] = целая часть числа
; $Res[1] = числитель дробной части
; $Res[2] = знаменатель дробной части
;-------------------------------------------------------------------------------

Func Ratio($X)

	Dim $Res[3] = [0,0,10]
	Local $y1, $y2, $s = String($X)
	Local $chislo = StringSplit($s, ".",2)
	$Res[0] = $chislo[0]
	If UBound($chislo) = 1 Then Return $Res
	Local $s_drob = $chislo[1]
	Local $L = Floor(StringLen($s_drob)/2)

	For $i = $L To 0 Step -1
		$s1 = StringLeft($s_drob,$i)
		$s2 = $s1 & $s1
		If StringInStr($s_drob, $s2) = 1 Then ExitLoop
	Next

	If $s1 = "" Then
		$y1 = int($s_drob)
		$L = StringLen($s_drob)
		$y2 = 10 ^ $L
	Else
		$L = StringLen($s1)
		$s2 = ""
		For $i=1 To $L
			$s2 = $s2 & "9"
		Next
		$y1 = int($s1)
		$y2 = int($s2)
	EndIf

	$L = NOD($y1,$y2)
	$Res[1] = $y1 / $L
	$Res[2] = $y2 / $L
	Return $Res
EndFunc

Func NOD($x1, $x2)
	while $x1 > 0 and $x2 > 0
		If $x1 > $x2 Then
			$x1 = mod($x1,$x2)
		Else
			$x2 = mod($x2,$x1)
		EndIf
	WEnd
	Return $x1+$x2
EndFunc
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
C2H5OH
Твой способ каждую дробь будет считать периодической, и ответ выдавать соответствующий. Например: Дробь 0.222 твой пример посчитает как 2/9, хотя на самом деле это 111/500.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Хороший вопрос!
Как отличить периодическую дробь от обрезанной?
В AutoIt нет такого формата числа 0.(2) или 0.(142857)
Можешь сформулировать критерий отбора?
А ещё лучше сразу регулярное выражение написать, а то я ж с регулярными выражениями не того...
:-[
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Я не знаю. Я бы сделал checkbox которой указывал какой алгоритм использовать: для переодических дробей или нет. И пусть человек сам выбирает лучший результат.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Вряд ли checkbox подойдёт.
Изначально планировалось использовать конвертацию для корней квадратного уравнения.
Тут зараннее не угадаешь.
Может быть и 0.222 , и 0.(2)
 
Верх