Difference between revisions of "Fractions"
From Lazarus wiki
Jump to navigationJump to search(6 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{Fractions}} | ||
+ | |||
==What is Fractions?== | ==What is Fractions?== | ||
− | Fractions is a unit for doing calculations with fractions.<br> | + | Fractions is a [[Unit|unit]] for doing calculations with fractions.<br> |
The unit was inspired by a [http://forum.lazarus.freepascal.org/index.php/topic,27805.0.html discussion on the Lazarus forum]. | The unit was inspired by a [http://forum.lazarus.freepascal.org/index.php/topic,27805.0.html discussion on the Lazarus forum]. | ||
Line 16: | Line 18: | ||
===The TFraction type=== | ===The TFraction type=== | ||
− | TFraction is an "advanced record": a record with methods and properties. | + | TFraction is an "advanced record": a [[Record|record]] with [[Method|methods]] and [[Property|properties]]. |
====Porperties of TFraction==== | ====Porperties of TFraction==== | ||
− | *property Numerator: Int64; | + | *property Numerator: [[Int64|Int64]]; |
**Gets and sets the Numerator part of the fraction | **Gets and sets the Numerator part of the fraction | ||
*property Denominator: Int64; | *property Denominator: Int64; | ||
**Gets and sets the Denominator part of the fraction. | **Gets and sets the Denominator part of the fraction. | ||
− | **Trying to assign 0 (zero) to TFraction.Denomiator will raise an EZeroDivide exception | + | **Trying to assign 0 (zero) to TFraction.Denomiator will raise an EZeroDivide [[Exceptions|exception]] |
====Methods of TFraction==== | ====Methods of TFraction==== | ||
− | *procedure Normalize; | + | *[[Procedure|procedure]] Normalize; |
− | **Normalizes the fraction by dividing the Numerator and Dominatr by their greatest common divisor, e.g. 10/5 becomes 2/1 | + | **Normalizes the fraction by dividing the Numerator and Dominatr by their [[Greatest common divisor|greatest common divisor]], e.g. 10/5 becomes 2/1 |
− | *function ToString: String; | + | *[[Function|function]] ToString: [[String|String]]; |
− | **returns the string representation of the fraction (no normalizaltion is done), e.g. when Numerator = 10 and Denominator = 5, the function | + | **returns the string representation of the fraction (no normalizaltion is done), e.g. when Numerator = 10 and Denominator = 5, the function returns '10/5' |
*function Resolve: String; | *function Resolve: String; | ||
**retruns the string representation of the fraction <b>after normalization</b>, e.g. when Numerator = 4 and Denominator = 3, the function returns '1 1/3' | **retruns the string representation of the fraction <b>after normalization</b>, e.g. when Numerator = 4 and Denominator = 3, the function returns '1 1/3' | ||
− | *function ToFloat: Double; | + | *function ToFloat: [[Double|Double]]; |
**returns the floating point representation of the fraction, e.g. when Numerator = 1 and Denominator = 3, the function returns 0.3333333333333 | **returns the floating point representation of the fraction, e.g. when Numerator = 1 and Denominator = 3, the function returns 0.3333333333333 | ||
− | |||
− | |||
===Assigning and creating Fractions=== | ===Assigning and creating Fractions=== | ||
Line 45: | Line 45: | ||
===Supported calculations=== | ===Supported calculations=== | ||
− | ====Overloaded operators==== | + | ====[[Operator_overloading|Overloaded]] [[Operator|operators]]==== |
* = (equals) | * = (equals) | ||
− | * < (less than) | + | * [[Less than|<syntaxhighlight lang="pascal" inline><</syntaxhighlight>]] (less than) |
− | * > (greater than) | + | * [[Greater than|<syntaxhighlight lang="pascal" inline>></syntaxhighlight>]] (greater than) |
* <= (less than or equal) | * <= (less than or equal) | ||
* >= (greater than or equal) | * >= (greater than or equal) | ||
− | * := (assign): this operator allows an Int64 or a String on the right hand side | + | * [[Becomes|<syntaxhighlight lang="pascal" inline>:=</syntaxhighlight>]] (assign): this operator allows an Int64 or a String on the right hand side |
− | * + (add) | + | * [[Plus|<syntaxhighlight lang="pascal" inline>+</syntaxhighlight>]] (add) |
− | * - (subtract) | + | * [[Minus|<syntaxhighlight lang="pascal" inline>-</syntaxhighlight>]] (subtract) |
− | * * (multiply): overloaded for fractions and Int64 | + | * [[Asterisk|<syntaxhighlight lang="pascal" inline>*</syntaxhighlight>]] (multiply): overloaded for fractions and Int64 |
− | * / (divide): overloaded for fractions and Int64 | + | * [[Slash|<syntaxhighlight lang="pascal" inline>/</syntaxhighlight>]] (divide): overloaded for fractions and Int64 |
* ** (power): only allowed for Integers (on right hand side) | * ** (power): only allowed for Integers (on right hand side) | ||
+ | |||
+ | |||
====Mathematical functions==== | ====Mathematical functions==== | ||
− | *function Min(a, b: TFraction): TFraction; inline; overload; | + | *function Min(a, b: TFraction): TFraction; [[Inline|inline]]; [[Overload|overload]]; |
**returns a if (a <= b), otherwise retruns b | **returns a if (a <= b), otherwise retruns b | ||
*function Max(a, b: TFraction): TFraction; inline; overload; | *function Max(a, b: TFraction): TFraction; inline; overload; | ||
**returns a if (a >= b), otherwise returns b | **returns a if (a >= b), otherwise returns b | ||
− | *function InRange(const AValue, AMin, AMax: TFraction): Boolean; inline; overload; | + | *function InRange(const AValue, AMin, AMax: TFraction): [[Boolean|Boolean]]; inline; overload; |
− | **returns True if (AValue >= AMin) and (AValue <= AMax), otherwise returns False | + | **returns [[True|True]] if (AValue >= AMin) and (AValue <= AMax), otherwise returns [[False|False]] |
*function EnsureRange(const AValue, AMin, AMax: TFraction): TFraction; inline; overload; | *function EnsureRange(const AValue, AMin, AMax: TFraction): TFraction; inline; overload; | ||
** returns AMin if (AValue < AMin), otherwise returns AMax if (AValue > AMax), otherwise returns AValue | ** returns AMin if (AValue < AMin), otherwise returns AMax if (AValue > AMax), otherwise returns AValue | ||
Line 101: | Line 103: | ||
*function StrToFractionDef(const S: String; Def: TFraction): TFraction; | *function StrToFractionDef(const S: String; Def: TFraction): TFraction; | ||
**returns the fraction represented in S if conversion succeeds, otherwise returns Def | **returns the fraction represented in S if conversion succeeds, otherwise returns Def | ||
+ | |||
+ | ==Example program== | ||
+ | <syntaxhighlight lang=pascal> | ||
+ | program example; | ||
+ | |||
+ | {$mode objfpc}{$H+} | ||
+ | {$apptype console} | ||
+ | |||
+ | uses | ||
+ | Classes, sysutils, fractions, math; | ||
+ | |||
+ | var | ||
+ | F1, F2: TFraction; | ||
+ | D, Prec: Double; | ||
+ | i: Integer; | ||
+ | begin | ||
+ | F1 := Fraction(1,1,3); // 1 1/3 | ||
+ | F2 := Fraction(4,3); // 4/3 | ||
+ | writeln('F1.ToString = ',F1.ToString); // '4/3' | ||
+ | writeln('F1.Resolve = ',F1.Resolve); // '1 1/3' | ||
+ | writeln('F1.ToFloat = ',F1.ToFloat:16:16); // 1.3333333333333333 | ||
+ | writeln('F2.ToString = ',F2.ToString); // '4/3' | ||
+ | writeln('(F1 = F2) = ',F1=F2); //True | ||
+ | |||
+ | F1 := Fraction(1,2); | ||
+ | F2 := Fraction(1,3); | ||
+ | writeln(F1.ToString,' * ',F2.ToString,' = ',(F1*F2).Resolve); // '1/6' | ||
+ | writeln(F1.ToString,' / ',F2.ToString,' = ',(F1/F2).Resolve); // '1 1/2' | ||
+ | writeln(F1.ToString,' + ',F2.ToString,' = ',(F1+F2).Resolve); // '5/6' | ||
+ | writeln(F1.ToString,' - ',F2.ToString,' = ',(F1-F2).Resolve); // '1/6' | ||
+ | writeln(F1.ToString,' ** 2 = ',(F1**2).Resolve); // '1/6' | ||
+ | |||
+ | D := 0.25; | ||
+ | F1 := FloatToFraction(D, 0.000001); | ||
+ | writeln('FloatTofraction(0.25) -> ',F1.ToString); // '1/4' | ||
+ | writeln; | ||
+ | writeln('Approximations of Pi:'); | ||
+ | writeln(' [Pi = ',Pi:16:16,']'); | ||
+ | Prec := 1.0; | ||
+ | for i := 1 to 10 do | ||
+ | begin | ||
+ | Prec := Prec / 10; | ||
+ | F2 := FloatTofraction(Pi, Prec); | ||
+ | writeln('FloatTofraction(Pi,',Prec:10:10,') = ',Format('%-13s',[F2.Resolve]),' [',F2.ToFloat:16:16,']'); | ||
+ | end; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | This outputs: | ||
+ | <pre> | ||
+ | F1.ToString = 4/3 | ||
+ | F1.Resolve = 1 1/3 | ||
+ | F1.ToFloat = 1.3333333333333333 | ||
+ | F2.ToString = 4/3 | ||
+ | (F1 = F2) = TRUE | ||
+ | 1/2 * 1/3 = 1/6 | ||
+ | 1/2 / 1/3 = 1 1/2 | ||
+ | 1/2 + 1/3 = 5/6 | ||
+ | 1/2 - 1/3 = 1/6 | ||
+ | 1/2 ** 2 = 1/4 | ||
+ | FloatTofraction(0.25) -> 1/4 | ||
+ | |||
+ | Approximations of Pi: | ||
+ | [Pi = 3.1415926535897932] | ||
+ | FloatTofraction(Pi,0.1000000000) = 3 1/7 [3.1428571428571428] | ||
+ | FloatTofraction(Pi,0.0100000000) = 3 1/7 [3.1428571428571428] | ||
+ | FloatTofraction(Pi,0.0010000000) = 3 16/113 [3.1415929203539825] | ||
+ | FloatTofraction(Pi,0.0001000000) = 3 16/113 [3.1415929203539825] | ||
+ | FloatTofraction(Pi,0.0000100000) = 3 16/113 [3.1415929203539825] | ||
+ | FloatTofraction(Pi,0.0000010000) = 3 16/113 [3.1415929203539825] | ||
+ | FloatTofraction(Pi,0.0000001000) = 3 4703/33215 [3.1415926539214212] | ||
+ | FloatTofraction(Pi,0.0000000100) = 3 4703/33215 [3.1415926539214212] | ||
+ | FloatTofraction(Pi,0.0000000010) = 3 4703/33215 [3.1415926539214212] | ||
+ | FloatTofraction(Pi,0.0000000001) = 3 14093/99532 [3.1415926536189365] | ||
+ | </pre> |
Latest revision as of 17:20, 6 August 2022
│
English (en) │
suomi (fi) │
What is Fractions?
Fractions is a unit for doing calculations with fractions.
The unit was inspired by a discussion on the Lazarus forum.
Subversion
You can get a copy of fractions on
svn https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/components/fractions
Or you can use viewcv to preview the files:
http://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/fractions/
Features
The TFraction type
TFraction is an "advanced record": a record with methods and properties.
Porperties of TFraction
- property Numerator: Int64;
- Gets and sets the Numerator part of the fraction
- property Denominator: Int64;
- Gets and sets the Denominator part of the fraction.
- Trying to assign 0 (zero) to TFraction.Denomiator will raise an EZeroDivide exception
Methods of TFraction
- procedure Normalize;
- Normalizes the fraction by dividing the Numerator and Dominatr by their greatest common divisor, e.g. 10/5 becomes 2/1
- function ToString: String;
- returns the string representation of the fraction (no normalizaltion is done), e.g. when Numerator = 10 and Denominator = 5, the function returns '10/5'
- function Resolve: String;
- retruns the string representation of the fraction after normalization, e.g. when Numerator = 4 and Denominator = 3, the function returns '1 1/3'
- function ToFloat: Double;
- returns the floating point representation of the fraction, e.g. when Numerator = 1 and Denominator = 3, the function returns 0.3333333333333
Assigning and creating Fractions
- function Fraction(ANumerator, ADenominator: Int64): TFraction;
- creates the fraction ANumerator/ADenominator, e.g. Fraction(1,2) gives 1/2 (one half).
- function Fraction(AIntPart, ANumerator, ADenominator: Int64): TFraction;
- creates the fraction ANumerator/ADenominator, e.g. Fraction(1,1,2) gives 1 1/2 (one and one half).
Supported calculations
Overloaded operators
- = (equals)
<
(less than)>
(greater than)- <= (less than or equal)
- >= (greater than or equal)
:=
(assign): this operator allows an Int64 or a String on the right hand side+
(add)-
(subtract)*
(multiply): overloaded for fractions and Int64/
(divide): overloaded for fractions and Int64- ** (power): only allowed for Integers (on right hand side)
Mathematical functions
- function Min(a, b: TFraction): TFraction; inline; overload;
- returns a if (a <= b), otherwise retruns b
- function Max(a, b: TFraction): TFraction; inline; overload;
- returns a if (a >= b), otherwise returns b
- function InRange(const AValue, AMin, AMax: TFraction): Boolean; inline; overload;
- function EnsureRange(const AValue, AMin, AMax: TFraction): TFraction; inline; overload;
- returns AMin if (AValue < AMin), otherwise returns AMax if (AValue > AMax), otherwise returns AValue
- function Sign(const AValue: TFraction): TValueSign; inline; overload;
- retruns NegativeValue if (AValue < 0), otherwise returns PositiveValue if (AValue >0), otherwise returns ZeroValue
- function IsZero(const AValue: TFraction): Boolean; overload;
- returns True if (AValue = 0), otherwise returns False
- function Abs(const AValue: TFraction): TFraction; overload;
- return AValue if (AValue >= 0), otherwise returns -AValue;
General purpose functions
- function GreatestCommonDivisor(a, b: Int64): Int64;
- returns the greates common divisor of a and b
- function Floor(D: Double): Int64; overload;
- returns the integer part of D (subtracted with 1, if (D < 0))
Conversion routines
- function FloatToFraction(Value, Precision: Double): TFraction;
- returns an approximation of Value in the form of a fraction, e.g. FloatTofraction(0.5,0.01) returns 1/2 (one half)
- Precision defines the acceptable value for which (Abs(Result) - Abs(Value) <= Precision.
- Precision is bound to Value by a magnitude of 15 at most
- FloatToFraction in fact is a function varable which is initialized to the MF_FloatTofraction() function. You can assign your own function to it if wanted.
- function TryFloatToFraction(Value, Precision: Double; out F: TFraction; AcceptPrecisionError: Boolean): Boolean;
- return value depends on AcceptPrecisionError value:
- if (AcceptPrecisionError = True) then the function retruns True if an approxiamtion can be found
- if (AcceptPrecisionError = False) the functions returns True if an approximation can be found AND Abs(Abs(Result)-Abs(Value)) <= Precision
- the value of F only makes sense if the function returns True
- return value depends on AcceptPrecisionError value:
- function FloatToFractionDef(Value, Precision: Double; Def: TFraction; AcceptPrecisionError: Boolean): TFraction;
- returns the found approximation (F) if TryFloatToFraction(Value, Precision, F, AcceptPrecisionError: Boolean) succeeds, otherwise returns Def
- function StrToFraction(const S: String): TFraction;
- returns fraction that is represented in S, raises an EConvertError upon failure
- function TryStrToFraction(const S: String; out F: TFraction): Boolean;
- retruns True if S can be converted to a fraction, otherwise returns False
- the value of F only makes sense f the function returns True
- function StrToFractionDef(const S: String; Def: TFraction): TFraction;
- returns the fraction represented in S if conversion succeeds, otherwise returns Def
Example program
program example;
{$mode objfpc}{$H+}
{$apptype console}
uses
Classes, sysutils, fractions, math;
var
F1, F2: TFraction;
D, Prec: Double;
i: Integer;
begin
F1 := Fraction(1,1,3); // 1 1/3
F2 := Fraction(4,3); // 4/3
writeln('F1.ToString = ',F1.ToString); // '4/3'
writeln('F1.Resolve = ',F1.Resolve); // '1 1/3'
writeln('F1.ToFloat = ',F1.ToFloat:16:16); // 1.3333333333333333
writeln('F2.ToString = ',F2.ToString); // '4/3'
writeln('(F1 = F2) = ',F1=F2); //True
F1 := Fraction(1,2);
F2 := Fraction(1,3);
writeln(F1.ToString,' * ',F2.ToString,' = ',(F1*F2).Resolve); // '1/6'
writeln(F1.ToString,' / ',F2.ToString,' = ',(F1/F2).Resolve); // '1 1/2'
writeln(F1.ToString,' + ',F2.ToString,' = ',(F1+F2).Resolve); // '5/6'
writeln(F1.ToString,' - ',F2.ToString,' = ',(F1-F2).Resolve); // '1/6'
writeln(F1.ToString,' ** 2 = ',(F1**2).Resolve); // '1/6'
D := 0.25;
F1 := FloatToFraction(D, 0.000001);
writeln('FloatTofraction(0.25) -> ',F1.ToString); // '1/4'
writeln;
writeln('Approximations of Pi:');
writeln(' [Pi = ',Pi:16:16,']');
Prec := 1.0;
for i := 1 to 10 do
begin
Prec := Prec / 10;
F2 := FloatTofraction(Pi, Prec);
writeln('FloatTofraction(Pi,',Prec:10:10,') = ',Format('%-13s',[F2.Resolve]),' [',F2.ToFloat:16:16,']');
end;
end.
This outputs:
F1.ToString = 4/3 F1.Resolve = 1 1/3 F1.ToFloat = 1.3333333333333333 F2.ToString = 4/3 (F1 = F2) = TRUE 1/2 * 1/3 = 1/6 1/2 / 1/3 = 1 1/2 1/2 + 1/3 = 5/6 1/2 - 1/3 = 1/6 1/2 ** 2 = 1/4 FloatTofraction(0.25) -> 1/4 Approximations of Pi: [Pi = 3.1415926535897932] FloatTofraction(Pi,0.1000000000) = 3 1/7 [3.1428571428571428] FloatTofraction(Pi,0.0100000000) = 3 1/7 [3.1428571428571428] FloatTofraction(Pi,0.0010000000) = 3 16/113 [3.1415929203539825] FloatTofraction(Pi,0.0001000000) = 3 16/113 [3.1415929203539825] FloatTofraction(Pi,0.0000100000) = 3 16/113 [3.1415929203539825] FloatTofraction(Pi,0.0000010000) = 3 16/113 [3.1415929203539825] FloatTofraction(Pi,0.0000001000) = 3 4703/33215 [3.1415926539214212] FloatTofraction(Pi,0.0000000100) = 3 4703/33215 [3.1415926539214212] FloatTofraction(Pi,0.0000000010) = 3 4703/33215 [3.1415926539214212] FloatTofraction(Pi,0.0000000001) = 3 14093/99532 [3.1415926536189365]