Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Funkcja zmieniająca char na int
- let parseIntC(c: char) = (int c) - 48;
- //Funkcja zwracająca większą z podanych wartości
- let maximum(a: int, b:int) = if a>b then a else b;
- //Funkcja zamieniająca listy miejscami.
- let swap (left : 'a byref) (right : 'a byref) =
- let temp = left
- left <- right
- right <- temp
- //Metoda zamieniająca liczbę w postaci tablicy na łańcuch znaków
- let asString(listI: list<int>, listF: list<int>) =
- let rec convRec(lista: list<int>, str: string, count:int) =
- if count=lista.Length then str else convRec(lista, str+(string lista.[count]), count+1)
- if listI.IsEmpty&&listF.IsEmpty then "0"
- elif listI.IsEmpty then "0." + convRec(listF, "", 0)
- elif listF.IsEmpty then convRec(listI, "", 0)
- else convRec(listI, "", 0) + "." + convRec(listF, "", 0)
- //Funkcja zwracająca tablicę stworzoną z podanej listy o długości max
- let cut(listA:list<int>, max:int)=
- let rec cuts(listA:list<int>, listB:list<int>,iter:int)=
- if iter = max then [|listA;listB|]
- else cuts(listA.Tail,listA.Head::listB,iter+1)
- let rett = cuts(listA,[],0)
- rett
- //Funkcja zamieniająca string na int
- let parseInt(s: string) =
- let rec parse(position: int, value: int, multiply: int) =
- if position<0 then value else parse(position-1, value+(multiply*parseIntC(s.[position])), multiply*10)
- parse(s.Length-1, 0, 1);
- //Funkcja zamieniająca liczbe całkowitą w postaci stringa na przedstawiającą go listę cyfr
- let toBigNumberArray(str: string) =
- let rec converse(lista: list<int>, pos: int, sign: int) =
- if pos=str.Length then lista else converse((sign*parseIntC(str.[pos]))::lista, pos+1, sign);
- if (int str.[0])=45 then
- List.rev(converse([], 1, -1))
- else
- List.rev(converse([], 0, 1));
- //Funkcja zmieniająca część całkowitą liczby w postaci string na listę cyfr
- let parserInteger(str: string) =
- let splitted = str.Split([|'.'; 'e'|]);
- toBigNumberArray(splitted.[0])
- //Funkcja zmieniająca część dziesiętną liczby w postaci string na listę cyfr
- let parserFloat(str: string) =
- let splitted = str.Split([|'.'|]);
- if splitted.Length<=1 then []
- else
- let ndsplitted = splitted.[1].Split([|'e'|]);
- if (int str.[0])=45 then toBigNumberArray("-"+ndsplitted.[0]) else toBigNumberArray(ndsplitted.[0])
- //Funkcja zamieniająca liczbę zmiennoprzecinkową w postaci string z obsługą notacji wykładniczej na reprezentujące ją listy cyfr
- let parserE(str: string) =
- let integerList = parserInteger(str);
- let floatList = parserFloat(str);
- let splitted = str.Split([|'e'|]);
- let rec backwards(listI: list<int>, listF: list<int>, count: int) =
- if count=parseInt(splitted.[1].[1..(splitted.[1].Length-1)]) then [|listI; listF|]
- elif listI.IsEmpty then backwards([], 0::listF, count+1)
- else backwards(List.rev(List.rev(listI).Tail), List.rev(listI).Head::listF, count+1)
- let rec forwards(listI: list<int>, listF: list<int>, count: int) =
- if count=parseInt(splitted.[1]) then [|listI; listF|]
- elif listF.IsEmpty then forwards(List.rev(0::List.rev(listI)), [], count+1)
- else forwards(List.rev(listF.Head::List.rev(listI)), listF.Tail, count+1)
- if splitted.Length>1 then
- if splitted.[1].Contains("-") then
- backwards(integerList, floatList, 0);
- else
- forwards(integerList, floatList, 0);
- else [|integerList; floatList|]
- //Funkcja uzupełniająca tablicę o nieznaczące zera
- let addZero(listA:list<int>, max:int)=
- let rec recZero(listA:list<int>,listB:list<int>,iter:int,too:int)=
- if iter = too then listB
- else
- if not(listA.IsEmpty) then recZero(listA.Tail,listA.Head::listB,iter+1,too)
- else recZero(listA,0::listB,iter+1,too)
- let ret = recZero(listA,[],0,max)
- List.rev(ret)
- //Funkcja potrzeban w odejmowaniu. Jeżeli nie można odjąć danej cyfry, to pobiera potrzebne jej wartości z bardziej znaczących miejsc
- let tak(listka:list<int>)=
- let rets = List.toArray(listka)
- let rec take(iter:int)=
- if iter<rets.Length then
- if rets.[iter] > 0 then
- rets.[iter] <- listka.[iter]-1
- 9
- else
- let tmp = take(iter+1)
- if tmp > 0 then
- rets.[iter]<-9
- 9
- else 0
- else 0
- if take(1) > 0 then
- rets.[0]<- listka.[0]+10
- List.ofArray(rets)
- //Funkcja wykonująca odejmowanie. Przyjmuje 2 listy reprezentujące liczby oraz ilość miejsc dziesiętnych, a zwraca listę z wynikiem.
- let less(listA:list<int>,listB:list<int>,flo:int)=
- let rec lessFloat(listF1:list<int>,listF2:list<int>,listR:list<int>,pos:int,too:int)=
- if pos = too then listR
- elif listF2.IsEmpty then lessFloat(listF1.Tail,listF2,listF1.Head::listR,pos+1,too)
- elif listF1.Head < listF2.Head then lessFloat(tak(listF1),listF2,listR,pos,too)
- else lessFloat(listF1.Tail,listF2.Tail,listF1.Head-listF2.Head::listR,pos+1,too)
- let tst = lessFloat(List.rev(listA),List.rev(listB),[],0,listA.Length)
- let wynik = cut(List.rev(tst),flo)
- [|List.rev(wynik.[0]);wynik.[1]|]
- //Funkcja zwracająca prawdę jeżeli pierwsza liczba jest większa od 2giej i fałsz, gdy jest odwrotnie
- let getBigger(listA1:list<int>,listA2:list<int>,listB1:list<int>,listB2:list<int>) =
- let rec check(listA:list<int>, listB:list<int>, iter:int)=
- if iter<listA.Length then
- if listA.Head > listB.Head then false
- elif listA.Head < listB.Head then true
- else check(listA.Tail,listB.Tail,iter+1)
- else false
- if listA1.Length>listB1.Length then false
- elif listA1.Length<listB1.Length then true
- else check(listA1@listA2,listB1@listB2,0)
- //Funkcja przyjmujące 2 liczby w postaci string i zwracająca wynik odejmowania 1szej od 2giej w postaci string
- let minus(numFirst:string, numSecond:string) =
- let mutable _first = parserE(numFirst);
- let mutable _second = parserE(numSecond);
- if _first.[1].Length < _second.[1].Length then
- _first.[1] <- addZero(_first.[1],_second.[1].Length)
- elif _second.[1].Length < _first.[1].Length then
- _second.[1]<-addZero(_second.[1],_first.[1].Length)
- let _big = getBigger(_first.[0],_first.[1],_second.[0],_second.[1])
- if _big then
- swap(&_first)(&_second)
- let wyn = less(_first.[0]@_first.[1],_second.[0]@_second.[1],_first.[1].Length)
- if _big then "-" + asString(wyn.[0],wyn.[1]) else asString(wyn.[0],wyn.[1])
- //Funkcja dodająca 2 liczby przyjęte w postaci string i zwracająca wynik ich dodawania w postaci string
- let plus(numFirst: string, numSecond: string) =
- let first = parserE(numFirst);
- let second = parserE(numSecond);
- let rec addiR(listF: list<int>, listS: list<int>, pos: int, result: list<int>, too: int) =
- if pos=too then result
- elif listF.IsEmpty&¬(listS.IsEmpty) then addiR([], List.rev(List.rev(listS).Tail), pos+1, List.rev(listS).Head::result, too)
- elif listS.IsEmpty&¬(listF.IsEmpty) then addiR(List.rev(List.rev(listF).Tail), [], pos+1, List.rev(listF).Head::result, too)
- else addiR(List.rev(List.rev(listF).Tail), List.rev(List.rev(listS).Tail), pos+1, (List.rev(listF).Head+List.rev(listS).Head)::result, too)
- let rec addfR(listF: list<int>, listS: list<int>, pos: int, result: list<int>, too: int) =
- if pos=too then List.rev(result)
- elif listF.IsEmpty&¬(listS.IsEmpty) then addfR([], listS.Tail, pos+1, listS.Head::result, too)
- elif listS.IsEmpty&¬(listF.IsEmpty) then addfR(listF.Tail, [], pos+1, listF.Head::result, too)
- else addfR(listF.Tail, listS.Tail, pos+1, (listF.Head+listS.Head)::result, too)
- let rec checkI (lista: list<int>, count: int, result: list<int>, next: bool) =
- if count<0 then result
- else
- let mutable elem = if lista.IsEmpty then 0 else lista.[count]
- if next then elem <- elem+1
- if lista.[count] >9 then checkI(lista, count-1, (elem-10)::result,true) else checkI(lista, count-1, elem::result,false)
- let mutable integerPart = addiR(first.[0], second.[0],0,[], maximum(first.[0].Length,second.[0].Length));
- let mutable floatPart = addfR(first.[1], second.[1],0,[], maximum(first.[1].Length,second.[1].Length));
- integerPart <- checkI(integerPart, integerPart.Length-1, [], false);
- floatPart <- checkI(floatPart, floatPart.Length-1, [], false);
- if not(floatPart.IsEmpty)&&floatPart.[0]>10
- then
- floatPart <- floatPart.Head-10::floatPart.Tail
- integerPart <- checkI(List.rev(List.rev(integerPart).Head+1::List.rev(integerPart).Tail), integerPart.Length-1, [], false)
- asString(integerPart, floatPart)
- //Funkcja obsługująca odejmowanie wielkich liczb, przyjmuje 2 liczby w postaci string i zwraca wynik odejmowania również w tej postaci
- let sub(numFirst:string, numSecond:string)=
- if numFirst.[0] = '-' && numSecond.[0] = '-' then
- minus(numSecond.[1..numFirst.Length-1],numFirst.[1..numSecond.Length-1])
- elif numFirst.[0] = '-' && not(numSecond.[0] = '-') then
- "-"+plus(numSecond,numFirst.[1..numFirst.Length-1])
- elif not(numFirst.[0] = '-') && numSecond.[0] ='-' then
- plus(numFirst,numSecond.[1..numSecond.Length-1])
- else minus(numFirst,numSecond)
- //Funkcja obsługująca dodawanie wielkich liczb, przyjmuje 2 liczby w postaci string i zwraca wynik odejmowania również w tej postaci
- let add(numFirst:string, numSecond:string)=
- if numFirst.[0] = '-' && numSecond.[0] = '-' then
- "-"+plus(numFirst.[1..numFirst.Length-1],numSecond.[1..numSecond.Length-1])
- elif numFirst.[0] = '-' && not(numSecond.[0] = '-') then
- minus(numSecond,numFirst.[1..numFirst.Length-1])
- elif not(numFirst.[0] = '-') && numSecond.[0] ='-' then
- minus(numFirst,numSecond.[1..numSecond.Length-1])
- else plus(numFirst,numSecond)
- //Funckja testująca odejmowanie wielkich liczb
- let test = sub("26666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666677777777777777777777777777777777777777777777777777777777777777777777777777777777777778888888888888888888888888888888888888888888888888888888888888888888888888888444444444444444444444444444444444444444444444444444444444444444444444444222222222222222222222222222222222123.213e4200","-3666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666.1238888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888e1880")
- printf "%s" test;
- System.Console.ReadKey(true);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement