Recent

Author Topic: Fractions  (Read 2224 times)

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Fractions
« Reply #15 on: November 07, 2020, 08:50:33 am »
I need something to translate back and forth between inches fraction (as string) to real.
For example 1 3/4 = 1.75
                   1 1/8 = 1.125  etc.
You can use fractions unit for this direction:
1 3/4 => 1.75
Also use fractions unit for reverse direction:
1.75 => 7/4
You simply assign 175 to numerator and 100 to denominator and call Normalize() method. If you want 1 3/4 instead of 7/4 then strip integer part from 1.75 to 0.75 to get 3/4 and prefix that output with integer part.

This method would not work on numbers like 0.3333333, but for standard imperial sizes it will work.

EDIT: FloatToFractionDef() that Bart mentioned seams to do better job.
« Last Edit: November 07, 2020, 08:55:03 am by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

AL

  • Sr. Member
  • ****
  • Posts: 264
Re: Fractions
« Reply #16 on: November 07, 2020, 09:13:46 pm »
Thanks to all for suggestions.
Fractions unit was overkill for my needs, since I do not need to do any fraction arithmetic.
Could Have used it but since I need only a display function ( as in Excell) I made my own.

This is the last part of it.
A little redondant code, could be made cleaner using subroutines.

Code: Pascal  [Select][+][-]
  1. Procedure ErrorInvalid ;
  2. Begin
  3.   ShowMessage ( 'Invalid number') ;
  4. end;
  5.  
  6. Function FractionToReal ( var Fraction: String ) : real ;
  7. var
  8.   SpaceNdx,
  9.   E , ValErr,
  10.   Numerator,
  11.   Denominator: word ;
  12.   F ,N       : double;
  13.   S          : string   ;
  14.  
  15. Begin
  16.  N := 0 ;
  17.  f := 0 ;
  18.  ValErr := 0 ;
  19.  S := '' ;
  20.  Fraction := trim(Fraction) ; // remove leading/trailing spaces
  21.  
  22.  // extract integer part if there is one
  23.  SpaceNdx := Pos(' ',Fraction) ;
  24.  If SpaceNdx > 1 then    // we have a space so X y/z
  25.    begin
  26.      S := (copy(Fraction,1,SpaceNdx-1)) ;
  27.      Val(S ,N,ValErr) ;
  28.      If ValErr > 0 then begin
  29.        ErrorInvalid ;
  30.        result := -1;
  31.        exit ;
  32.        end;
  33.      Delete(Fraction,1,SpaceNdx) ;
  34.      // remove any other extra space car
  35.      while (Pos(' ' , Fraction) > 0) and (Length (fraction) > 0) do delete(Fraction,Pos(' ',Fraction),1);
  36.      if Length(Fraction) > 0 then begin
  37.      // check for dividor sign
  38.        IF Pos('/',Fraction) = 0 then
  39.        begin // no / sign = error
  40.           ErrorInvalid;
  41.           result := -1 ;
  42.           exit;
  43.         end
  44.         Else
  45.         begin // there is a / sign
  46.         Val( Copy(Fraction,1,Pos('/', Fraction)-1),Numerator,ValErr) ;
  47.         E := ValErr ;
  48.         val(Copy(Fraction,Pos('/',Fraction)+1,Length(Fraction)),Denominator,ValErr) ;
  49.         If E + ValErr > 0 then
  50.          begin
  51.           ErrorInvalid;
  52.           result := -1 ;
  53.           exit;
  54.          end;
  55.          F := Numerator/Denominator ;
  56.        // reformat string for the display in case of too many spaces
  57.          if  S <> '0' then Fraction := S + ' ' + Fraction ; // remove non significant 0
  58.          Result := N + F  ;
  59.          exit ;
  60.         end ;
  61.      end;
  62.      end else   // no space so it is either just a fraction or just a whole number
  63.      begin
  64.         // remove any other extra space car
  65.        while (Pos(' ' , Fraction) > 0) and (Length (fraction) > 0) do delete(Fraction,Pos(' ',Fraction),1);
  66.        ValErr := 0 ;
  67.  
  68.         if Length(Fraction) > 0 then
  69.          begin
  70.          IF Pos('/',Fraction) = 0 then     // check for dividor sign
  71.           begin // this is a whole number
  72.           Val( Fraction, F,ValErr) ;
  73.           If ValErr > 0 then
  74.           begin
  75.            ErrorInvalid;
  76.            result := -1 ;
  77.            exit;
  78.           end
  79.           Else
  80.           begin
  81.              result := N+F;
  82.              exit ;
  83.            end;
  84.          end
  85.          Else begin // there is a '/' sign
  86.             Val( Copy(Fraction,1,Pos('/', Fraction)-1),Numerator,ValErr) ;
  87.             E := ValErr ;
  88.            val(Copy(Fraction,Pos('/',Fraction)+1,Length(Fraction)),Denominator,ValErr) ;
  89.            If E + ValErr > 0 then
  90.            begin
  91.              ErrorInvalid;
  92.              result := -1 ;
  93.              exit;
  94.            end;
  95.          F := Numerator/Denominator ;
  96.        // reformat string for the display in case of too many spaces
  97.          if  S <> '0' then Fraction := S + ' ' + Fraction ;
  98.       // could also use:  Fraction := Nearest64(N+F) ;
  99.          end;
  100.      end;    // length > 0
  101.  end; // no space
  102.    Result := N + F  ;
  103. end;                              
  104.  
Laz 3.1, fpc 3.2.2, Win10
Laz 3.1  fpc 3.2.2, MacOS Monterey running on VMWare/Win 10
Laz 3.1  fpc 3.2.2 Ubuntu 20.04

 

TinyPortal © 2005-2018