[BACK]Return to multprec_floating_numbers.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Math_Lib / Numbers

Annotation of OpenXM_contrib/PHC/Ada/Math_Lib/Numbers/multprec_floating_numbers.adb, Revision 1.1

1.1     ! maekawa     1: with Standard_Mathematical_Functions;    use Standard_Mathematical_Functions;
        !             2:
        !             3: package body Multprec_Floating_Numbers is
        !             4:
        !             5: -- NOTES ON THE IMPLEMENTATION :
        !             6: --   0) See the notes in the bodies of Multprec_{Natural,Integer}_Numbers.
        !             7: --   1) 0.0 must have zero fraction and zero exponent.
        !             8: --   2) The truncate and round operations all depend on the decimal radix.
        !             9: --   3) The function "Decimal_Places" occupies a central place.
        !            10: --   4) The normalized representation has a nonzero least significant digit.
        !            11:
        !            12:   tol : constant double_float := 10.0**(-8);
        !            13:
        !            14: -- AUXILIARIES :
        !            15:
        !            16:   function Truncate ( f : double_float ) return integer is
        !            17:
        !            18:     i : integer := integer(f);
        !            19:
        !            20:   begin
        !            21:     if i >= 0
        !            22:      then if double_float(i) > f + tol
        !            23:            then i := i-1;
        !            24:           end if;
        !            25:      else if double_float(i) < f - tol
        !            26:            then i := i+1;
        !            27:           end if;
        !            28:     end if;
        !            29:     return i;
        !            30:   end Truncate;
        !            31:
        !            32:   function Max_Size ( i1,i2 : Integer_Number ) return natural is
        !            33:
        !            34:   -- DESCRIPTION :
        !            35:   --   Return the maximal size of i1 and i2.
        !            36:
        !            37:     sz1 : constant natural := Size(i1);
        !            38:     sz2 : constant natural := Size(i2);
        !            39:
        !            40:   begin
        !            41:     if sz1 > sz2
        !            42:      then return sz1;
        !            43:      else return sz2;
        !            44:     end if;
        !            45:   end Max_Size;
        !            46:
        !            47:   procedure Shift_Left ( n : in out Natural_Number; ns : out natural ) is
        !            48:
        !            49:   -- DESCRIPTION :
        !            50:   --   Shifts n until the leading coefficient is larger than Base/10.
        !            51:   --   The number ns on return equals the number of shifts.
        !            52:
        !            53:   begin
        !            54:     if (Empty(n) or else Equal(n,0))
        !            55:      then ns := 0;
        !            56:      else ns := 0;
        !            57:           while (Coefficient(n,Size(n)) < Base/10) loop
        !            58:             Mul(n,10);
        !            59:             ns := ns+1;
        !            60:           end loop;
        !            61:     end if;
        !            62:   end Shift_Left;
        !            63:
        !            64:   procedure Shift_Right ( n : in out Natural_Number; ns : out natural ) is
        !            65:
        !            66:   -- DESCRIPTION :
        !            67:   --   Shifts n until the last digit in the least significant coefficient
        !            68:   --   of n is different from zero.
        !            69:   --   The number ns on return equals the number of shifts.
        !            70:
        !            71:     cff : natural;
        !            72:
        !            73:   begin
        !            74:     if (Empty(n) or else Equal(n,0))
        !            75:      then ns := 0;
        !            76:      else ns := 0;
        !            77:           cff := Coefficient(n,0) mod 10;
        !            78:           while (cff = 0) loop
        !            79:             Div(n,10);
        !            80:             ns := ns+1;
        !            81:             cff := Coefficient(n,0) mod 10;
        !            82:           end loop;
        !            83:     end if;
        !            84:   end Shift_Right;
        !            85:
        !            86:   procedure Shift_Right ( i : in out Integer_Number; ns : out natural ) is
        !            87:
        !            88:   -- DESCRIPTION :
        !            89:   --   Applies the Shift_Right to the number representation of i.
        !            90:
        !            91:     ni : Natural_Number;
        !            92:
        !            93:   begin
        !            94:     if Empty(i)
        !            95:      then ns := 0;
        !            96:      else --ni := Unsigned(i);
        !            97:           Copy(Unsigned(i),ni);  -- avoid sharing
        !            98:           Shift_Right(ni,ns);
        !            99:           if Sign(i) < 0
        !           100:            then Clear(i); i := Create(ni); Min(i);
        !           101:            else Clear(i); i := Create(ni);
        !           102:           end if;
        !           103:           Clear(ni);
        !           104:     end if;
        !           105:   end Shift_Right;
        !           106:
        !           107:   procedure Normalize ( f : in out Floating_Number ) is
        !           108:
        !           109:   -- DESCRIPTION :
        !           110:   --   Normalizes the representation of f so that its fraction has as
        !           111:   --   rightmost digit a nonzero number.
        !           112:
        !           113:     ns : natural;
        !           114:
        !           115:   begin
        !           116:     Shift_Right(f.fraction,ns);
        !           117:     Add(f.exponent,ns);
        !           118:   end Normalize;
        !           119:
        !           120:   procedure Adjust_Expo ( f : in out double_float;
        !           121:                           expo : in Integer_Number ) is
        !           122:
        !           123:   -- DESCRIPTION :
        !           124:   --   Multiplies f with 10**expo.
        !           125:
        !           126:     cnt : Integer_Number;
        !           127:
        !           128:   begin
        !           129:     Copy(expo,cnt);
        !           130:     while cnt > 0 loop
        !           131:       f := f*10.0;
        !           132:       Sub(cnt,1);
        !           133:     end loop;
        !           134:     while cnt < 0 loop
        !           135:       f := f/10.0;
        !           136:       Add(cnt,1);
        !           137:     end loop;
        !           138:     Clear(cnt);
        !           139:   end Adjust_Expo;
        !           140:
        !           141: -- CONSTRUCTORS :
        !           142:
        !           143:   function Create ( i : integer ) return Floating_Number is
        !           144:
        !           145:     res : Floating_Number;
        !           146:
        !           147:   begin
        !           148:     res.fraction := Create(i);
        !           149:     res.exponent := Create(0);
        !           150:     Normalize(res);
        !           151:     return res;
        !           152:   end Create;
        !           153:
        !           154:   function Create ( i : Integer_Number ) return Floating_Number is
        !           155:
        !           156:     res : Floating_Number;
        !           157:
        !           158:   begin
        !           159:     res.fraction := +i;
        !           160:     res.exponent := Create(0);
        !           161:     Normalize(res);
        !           162:     return res;
        !           163:   end Create;
        !           164:
        !           165:   function Create ( fraction,exponent : integer ) return Floating_Number is
        !           166:
        !           167:     res : Floating_Number;
        !           168:
        !           169:   begin
        !           170:     res.fraction := Create(fraction);
        !           171:     res.exponent := Create(exponent);
        !           172:     Normalize(res);
        !           173:     return res;
        !           174:   end Create;
        !           175:
        !           176:   function Create ( fraction : Integer_Number;
        !           177:                     exponent : integer ) return Floating_Number is
        !           178:
        !           179:     res : Floating_Number;
        !           180:
        !           181:   begin
        !           182:     res.fraction := +fraction;
        !           183:     res.exponent := Create(exponent);
        !           184:     Normalize(res);
        !           185:     return res;
        !           186:   end Create;
        !           187:
        !           188:   function Create ( fraction : integer;
        !           189:                     exponent : Integer_Number ) return Floating_Number is
        !           190:
        !           191:     res : Floating_Number;
        !           192:
        !           193:   begin
        !           194:     res.fraction := Create(fraction);
        !           195:     res.exponent := +exponent;
        !           196:     Normalize(res);
        !           197:     return res;
        !           198:   end Create;
        !           199:
        !           200:   function Create ( fraction,exponent : Integer_Number )
        !           201:                   return Floating_Number is
        !           202:
        !           203:     res : Floating_Number;
        !           204:
        !           205:   begin
        !           206:     res.fraction := +fraction;
        !           207:     res.exponent := +exponent;
        !           208:     Normalize(res);
        !           209:     return res;
        !           210:   end Create;
        !           211:
        !           212:   function Create ( f : double_float ) return Floating_Number is
        !           213:
        !           214:   -- NOTE :
        !           215:   --   To avoid rounding errors, comparison operations are prefered
        !           216:   --   above relying on intermediate results of calculations, although
        !           217:   --   rounding errors still occur!
        !           218:
        !           219:     res : Floating_Number;
        !           220:     ten : Integer_Number;
        !           221:     wrkflt,fltexp,lowflt,uppflt,incflt : double_float;
        !           222:     intexp : integer;
        !           223:     fraction,exponent,intinc : Integer_Number;
        !           224:
        !           225:   begin
        !           226:     if f = 0.0
        !           227:      then res := Create(0);
        !           228:           return res;
        !           229:     end if;
        !           230:     if f > 0.0
        !           231:      then wrkflt := f;
        !           232:      else wrkflt := -f;
        !           233:     end if;
        !           234:     fltexp := LOG10(wrkflt);
        !           235:     intexp := Truncate(fltexp);
        !           236:     if intexp < 15
        !           237:      then wrkflt := wrkflt*(10.0**(15-intexp));
        !           238:           exponent := Create(intexp-15);
        !           239:           intexp := 15;
        !           240:      else exponent := Create(0);
        !           241:     end if;
        !           242:     lowflt := 10.0**intexp;
        !           243:     uppflt := 10.0**(intexp+1);
        !           244:     while lowflt > wrkflt loop
        !           245:       intexp := intexp-1;
        !           246:       lowflt := 10.0**intexp;
        !           247:       uppflt := 10.0**(intexp+1);
        !           248:     end loop;
        !           249:     ten := Create(10);
        !           250:     fraction := ten**intexp;
        !           251:     for k in 1..16 loop
        !           252:       incflt := 10.0**intexp;
        !           253:       intinc := ten**intexp;
        !           254:       uppflt := lowflt;
        !           255:       for i in 1..10 loop
        !           256:         uppflt := uppflt + incflt;
        !           257:         exit when (uppflt > wrkflt);
        !           258:         lowflt := uppflt;
        !           259:         Add(fraction,intinc);
        !           260:       end loop;
        !           261:       intexp := intexp - 1;
        !           262:       Clear(intinc);
        !           263:     end loop;
        !           264:     Clear(ten);
        !           265:     if f < 0.0
        !           266:      then Min(fraction);
        !           267:     end if;
        !           268:     res := Create(fraction,exponent);
        !           269:     Normalize(res);
        !           270:     return res;
        !           271:   end Create;
        !           272:
        !           273: -- SELECTORS :
        !           274:
        !           275:   function Fraction ( f : Floating_Number ) return Integer_Number is
        !           276:   begin
        !           277:     return f.fraction;
        !           278:   end Fraction;
        !           279:
        !           280:   function Exponent ( f : Floating_Number ) return Integer_Number is
        !           281:   begin
        !           282:     return f.exponent;
        !           283:   end Exponent;
        !           284:
        !           285:   function Size_Fraction ( f : Floating_Number ) return natural is
        !           286:   begin
        !           287:     return Size(Fraction(f));
        !           288:   end Size_Fraction;
        !           289:
        !           290:   function Size_Exponent ( f : Floating_Number ) return natural is
        !           291:   begin
        !           292:     return Size(Exponent(f));
        !           293:   end Size_Exponent;
        !           294:
        !           295:   function Decimal_Places_Fraction ( f : Floating_Number ) return natural is
        !           296:   begin
        !           297:     return Decimal_Places(Fraction(f));
        !           298:   end Decimal_Places_Fraction;
        !           299:
        !           300:   function Decimal_Places_Exponent ( f : Floating_Number ) return natural is
        !           301:   begin
        !           302:     return Decimal_Places(Exponent(f));
        !           303:   end Decimal_Places_Exponent;
        !           304:
        !           305:   function Decimal_to_Size ( deci : natural ) return natural is
        !           306:
        !           307:     res : natural;
        !           308:     exp : constant natural := Multprec_Natural_Numbers.Exponent;
        !           309:
        !           310:   begin
        !           311:     res := deci/exp;
        !           312:     if res*exp < deci
        !           313:      then res := res+1;
        !           314:     end if;
        !           315:     return res;
        !           316:   end Decimal_to_Size;
        !           317:
        !           318:   function AbsVal ( f : Floating_Number ) return Floating_Number is
        !           319:
        !           320:     res : Floating_Number;
        !           321:
        !           322:   begin
        !           323:     if Negative(f.fraction)
        !           324:      then res.fraction := -f.fraction;
        !           325:      else res.fraction := +f.fraction;
        !           326:     end if;
        !           327:     res.exponent := +f.exponent;
        !           328:     return res;
        !           329:   end AbsVal;
        !           330:
        !           331: -- COMPARISON AND COPYING :
        !           332:
        !           333:   function Equal ( f1 : Floating_Number; f2 : double_float ) return boolean is
        !           334:
        !           335:     ff2 : Floating_Number := Create(f2);
        !           336:     res : boolean := Equal(f1,ff2);
        !           337:
        !           338:   begin
        !           339:     Clear(ff2);
        !           340:     return res;
        !           341:   end Equal;
        !           342:
        !           343:   function Equal ( f1,f2 : Floating_Number ) return boolean is
        !           344:
        !           345:     res : boolean;
        !           346:     f1deci : constant natural := Decimal_Places(f1.fraction);
        !           347:     f2deci : constant natural := Decimal_Places(f2.fraction);
        !           348:     f1expo : Integer_Number := f1.exponent + f1deci;
        !           349:     f2expo : Integer_Number := f2.exponent + f2deci;
        !           350:     mulfra : Integer_Number;
        !           351:
        !           352:   begin
        !           353:     if Equal(f1expo,f2expo)
        !           354:      then if f1deci = f2deci
        !           355:            then res := Equal(f1.fraction,f2.fraction);
        !           356:            else if f1deci < f2deci
        !           357:                  then mulfra := f1.fraction*10;
        !           358:                       for i in 1..(f2deci-f1deci-1) loop
        !           359:                         Mul(mulfra,10);
        !           360:                       end loop;
        !           361:                       res := Equal(mulfra,f2.fraction);
        !           362:                  else mulfra := f2.fraction*10;
        !           363:                       for i in 1..(f1deci-f2deci-1) loop
        !           364:                         Mul(mulfra,10);
        !           365:                       end loop;
        !           366:                       res := Equal(f1.fraction,mulfra);
        !           367:                 end if;
        !           368:                 Clear(mulfra);
        !           369:           end if;
        !           370:      else res := false;
        !           371:     end if;
        !           372:     Clear(f1expo); Clear(f2expo);
        !           373:     return res;
        !           374:   end Equal;
        !           375:
        !           376:   function "<" ( f1 : double_float; f2 : Floating_Number ) return boolean is
        !           377:
        !           378:     ff1 : Floating_Number := Create(f1);
        !           379:     res : boolean := (ff1 < f2);
        !           380:
        !           381:   begin
        !           382:     Clear(ff1);
        !           383:     return res;
        !           384:   end "<";
        !           385:
        !           386:   function "<" ( f1 : Floating_Number; f2 : double_float ) return boolean is
        !           387:
        !           388:     ff2 : Floating_Number := Create(f2);
        !           389:     res : boolean := (f1 < ff2);
        !           390:
        !           391:   begin
        !           392:     Clear(ff2);
        !           393:     return res;
        !           394:   end "<";
        !           395:
        !           396:   function "<" ( f1,f2 : Floating_Number ) return boolean is
        !           397:
        !           398:     res : boolean;
        !           399:     f1deci : constant natural := Decimal_Places(f1.fraction);
        !           400:     f2deci : constant natural := Decimal_Places(f2.fraction);
        !           401:     f1expo : Integer_Number := f1.exponent + f1deci;
        !           402:     f2expo : Integer_Number := f2.exponent + f2deci;
        !           403:     mulfra : Integer_Number;
        !           404:
        !           405:   begin
        !           406:     if (f1expo < f2expo)
        !           407:      then if Sign(f2.fraction) > 0
        !           408:            then res := true;
        !           409:            elsif Sign(f2.fraction) < 0
        !           410:                then res := false;
        !           411:                else res := (Sign(f1.fraction) < 0);
        !           412:           end if;
        !           413:      elsif (f1expo > f2expo)
        !           414:          then if Sign(f1.fraction) > 0
        !           415:                then res := false;
        !           416:                elsif Sign(f1.fraction) < 0
        !           417:                    then res := true;
        !           418:                    else res := (Sign(f2.fraction) > 0);
        !           419:               end if;
        !           420:          else if f1deci = f2deci
        !           421:                then res := (f1.fraction < f2.fraction);
        !           422:                else if f1deci < f2deci
        !           423:                      then mulfra := f1.fraction*10;
        !           424:                           for i in 1..(f2deci-f1deci-1) loop
        !           425:                             Mul(mulfra,10);
        !           426:                           end loop;
        !           427:                           res := (mulfra < f2.fraction);
        !           428:                      else mulfra := f2.fraction*10;
        !           429:                           for i in 1..(f1deci-f2deci-1) loop
        !           430:                             Mul(mulfra,10);
        !           431:                           end loop;
        !           432:                           res := (f1.fraction < mulfra);
        !           433:                     end if;
        !           434:                     Clear(mulfra);
        !           435:               end if;
        !           436:     end if;
        !           437:     Clear(f1expo); Clear(f2expo);
        !           438:     return res;
        !           439:   end "<";
        !           440:
        !           441:   function ">" ( f1 : double_float; f2 : Floating_Number ) return boolean is
        !           442:
        !           443:     ff1 : Floating_Number := Create(f1);
        !           444:     res : boolean := (ff1 > f2);
        !           445:
        !           446:   begin
        !           447:     Clear(ff1);
        !           448:     return res;
        !           449:   end ">";
        !           450:
        !           451:   function ">" ( f1 : Floating_Number; f2 : double_float ) return boolean is
        !           452:
        !           453:     ff2 : Floating_Number := Create(f2);
        !           454:     res : boolean := (f1 > ff2);
        !           455:
        !           456:   begin
        !           457:     Clear(ff2);
        !           458:     return res;
        !           459:   end ">";
        !           460:
        !           461:   function ">" ( f1,f2 : Floating_Number ) return boolean is
        !           462:
        !           463:     res : boolean;
        !           464:     f1deci : constant natural := Decimal_Places(f1.fraction);
        !           465:     f2deci : constant natural := Decimal_Places(f2.fraction);
        !           466:     f1expo : Integer_Number := f1.exponent + f1deci;
        !           467:     f2expo : Integer_Number := f2.exponent + f2deci;
        !           468:     mulfra : Integer_Number;
        !           469:
        !           470:   begin
        !           471:     if (f1expo > f2expo)
        !           472:      then if Sign(f1.fraction) > 0
        !           473:            then res := true;
        !           474:            elsif Sign(f1.fraction) < 0
        !           475:                then res := false;
        !           476:                else res := (Sign(f2.fraction) < 0);
        !           477:           end if;
        !           478:      elsif (f1expo < f2expo)
        !           479:          then if Sign(f2.fraction) > 0
        !           480:                then res := false;
        !           481:                elsif Sign(f2.fraction) < 0
        !           482:                    then res := true;
        !           483:                    else res := (Sign(f1.fraction) > 0);
        !           484:               end if;
        !           485:          else if f1deci = f2deci
        !           486:                then res := (f1.fraction > f2.fraction);
        !           487:                else if f1deci < f2deci
        !           488:                      then mulfra := f1.fraction*10;
        !           489:                           for i in 1..(f2deci-f1deci-1) loop
        !           490:                             Mul(mulfra,10);
        !           491:                           end loop;
        !           492:                           res := (mulfra > f2.fraction);
        !           493:                      else mulfra := f2.fraction*10;
        !           494:                           for i in 1..(f1deci-f2deci-1) loop
        !           495:                             Mul(mulfra,10);
        !           496:                           end loop;
        !           497:                           res := (f1.fraction > mulfra);
        !           498:                     end if;
        !           499:                     Clear(mulfra);
        !           500:               end if;
        !           501:     end if;
        !           502:     Clear(f1expo); Clear(f2expo);
        !           503:     return res;
        !           504:   end ">";
        !           505:
        !           506:   procedure Copy ( f1 : in Floating_Number; f2 : in out Floating_Number ) is
        !           507:   begin
        !           508:     Clear(f2);
        !           509:     Copy(f1.fraction,f2.fraction);
        !           510:     Copy(f1.exponent,f2.exponent);
        !           511:   end Copy;
        !           512:
        !           513: -- EXPANDING AND SHORTENING THE MANTISSA :
        !           514:
        !           515:   function Expand ( i : Integer_Number; k : natural )
        !           516:                   return Array_of_Naturals is
        !           517:
        !           518:   -- DESCRIPTION :
        !           519:   --   Returns the expanded coefficient vector of i.
        !           520:
        !           521:     cff : constant Array_of_Naturals := Coefficients(Unsigned(i));
        !           522:     res : Array_of_Naturals(cff'first..cff'last+k);
        !           523:
        !           524:   begin
        !           525:     res(cff'range) := cff(cff'range);
        !           526:     res(cff'last+1..res'last) := (cff'last+1..res'last => 0);
        !           527:     return res;
        !           528:   end Expand;
        !           529:
        !           530:   procedure Truncate ( i : in Integer_Number; k : in natural;
        !           531:                        trc : out Array_of_Naturals; exp : out integer ) is
        !           532:
        !           533:   -- DESCRIPTION :
        !           534:   --   On return is the truncated coefficient vector of i and the number
        !           535:   --   of decimal places that are lost, or gained when exp is positive.
        !           536:
        !           537:     n : Natural_Number;
        !           538:     ns : natural;          -- #shifts = #decimal places gained
        !           539:
        !           540:   begin
        !           541:     Copy(Unsigned(i),n);
        !           542:     Shift_Left(n,ns);
        !           543:     exp := k*Multprec_Natural_Numbers.Exponent - ns;
        !           544:     declare
        !           545:       cff : constant Array_of_Naturals := Coefficients(n);
        !           546:     begin
        !           547:       for i in trc'range loop
        !           548:         trc(i) := cff(i+k);
        !           549:       end loop;
        !           550:       Clear(n);
        !           551:     end;
        !           552:   end Truncate;
        !           553:
        !           554:   procedure Truncate ( i : in out Integer_Number; k : in natural;
        !           555:                        exp : out integer ) is
        !           556:
        !           557:     n : Natural_Number := Unsigned(i);
        !           558:     neg : constant boolean := Negative(i);
        !           559:     ns : natural;
        !           560:     newint : Integer_Number;
        !           561:
        !           562:   begin
        !           563:     Shift_Left(n,ns);
        !           564:     exp := k*Multprec_Natural_Numbers.Exponent - ns;
        !           565:     declare
        !           566:       cff : constant Array_of_Naturals := Coefficients(n);
        !           567:       trc : Array_of_Naturals(cff'first..cff'last-k);
        !           568:     begin
        !           569:       for i in trc'range loop
        !           570:         trc(i) := cff(i+k);
        !           571:       end loop;
        !           572:       newint := Create(trc);
        !           573:       i := newint; --Copy(newint,i); --Clear(newint);
        !           574:       if neg
        !           575:        then Min(i);
        !           576:       end if;
        !           577:     end;
        !           578:     Clear(n);
        !           579:   end Truncate;
        !           580:
        !           581:   procedure Round ( i : in Integer_Number; k : in natural;
        !           582:                     trc : out Array_of_Naturals; exp : out integer ) is
        !           583:
        !           584:   -- DESCRIPTION :
        !           585:   --   On return is the rounded coefficient vector of i and the number
        !           586:   --   of decimal places that are lost, or gained when exp is positive.
        !           587:
        !           588:     n : Natural_Number := Unsigned(i);
        !           589:     ns : natural;          -- #shifts = #decimal places gained
        !           590:
        !           591:   begin
        !           592:     Shift_Left(n,ns);
        !           593:     exp := k*Multprec_Natural_Numbers.Exponent - ns;
        !           594:     declare
        !           595:       cff : constant Array_of_Naturals := Coefficients(n);
        !           596:     begin
        !           597:       for i in trc'range loop
        !           598:         trc(i) := cff(i+k);
        !           599:       end loop;
        !           600:       if k > 0
        !           601:        then if cff(k-1) >= Multprec_Natural_Numbers.Base/2
        !           602:              then trc(0) := trc(0)+1;
        !           603:             end if;
        !           604:       end if;
        !           605:     end;
        !           606:     Clear(n);
        !           607:   end Round;
        !           608:
        !           609:   function Expand ( f : Floating_Number; k : natural ) return Floating_Number is
        !           610:
        !           611:     res : Floating_Number;
        !           612:     cff : constant Array_of_Naturals := Expand(f.fraction,k);
        !           613:
        !           614:   begin
        !           615:     res.fraction := Create(Create(cff));
        !           616:     if Negative(f.fraction)
        !           617:      then Min(res.fraction);
        !           618:     end if;
        !           619:     Copy(f.exponent,res.exponent);
        !           620:     Normalize(res);
        !           621:     return res;
        !           622:   end Expand;
        !           623:
        !           624:   procedure Expand ( f : in out Floating_Number; k : in natural ) is
        !           625:
        !           626:     cff : constant Array_of_Naturals := Expand(f.fraction,k);
        !           627:     neg : constant boolean := Negative(f.fraction);
        !           628:
        !           629:   begin
        !           630:     Clear(f.fraction);
        !           631:     f.fraction := Create(Create(cff));
        !           632:     if neg
        !           633:      then Min(f.fraction);
        !           634:     end if;
        !           635:     Normalize(f);
        !           636:   end Expand;
        !           637:
        !           638:   function Round ( f : Floating_Number ) return double_float is
        !           639:
        !           640:     res : double_float;
        !           641:     szf,ns : natural;
        !           642:     n : Natural_Number;
        !           643:     expo : Integer_Number;
        !           644:
        !           645:   begin
        !           646:     if (Empty(f.fraction) or else Equal(f.fraction,0))
        !           647:      then res := 0.0;
        !           648:      else Copy(Unsigned(f.fraction),n);
        !           649:           Shift_Left(n,ns);
        !           650:           expo := f.exponent - ns;
        !           651:           szf := Size(n);
        !           652:           while Coefficient(n,szf) = 0 and szf > 0 loop
        !           653:             szf := szf - 1;
        !           654:           end loop;
        !           655:           res := double_float(Coefficient(n,szf));
        !           656:           if szf >= 1
        !           657:            then res := res*double_float(Multprec_Natural_Numbers.Base)
        !           658:                      + double_float(Coefficient(n,szf-1));
        !           659:                 if szf >= 2
        !           660:                  then if Coefficient(n,szf-2) > Multprec_Natural_Numbers.Base/2
        !           661:                        then res := res+1.0;
        !           662:                       end if;
        !           663:                       ns := (szf - 1)*Multprec_Natural_Numbers.Exponent;
        !           664:                       Add(expo,ns);
        !           665:                 end if;
        !           666:           end if;
        !           667:           Adjust_Expo(res,expo);
        !           668:           Clear(n); Clear(expo);
        !           669:     end if;
        !           670:     return res;
        !           671:   end Round;
        !           672:
        !           673:   function Round ( f : Floating_Number; k : natural ) return Floating_Number is
        !           674:
        !           675:     res : Floating_Number;
        !           676:     cff : Array_of_Naturals(0..(Size(f.fraction)-k));
        !           677:     exp : integer;
        !           678:
        !           679:   begin
        !           680:     Round(f.fraction,k,cff,exp);
        !           681:     res.fraction := Create(Create(cff));
        !           682:     if Negative(f.fraction)
        !           683:      then Min(res.fraction);
        !           684:     end if;
        !           685:     Copy(f.exponent,res.exponent);
        !           686:     Add(res.exponent,exp);
        !           687:     Normalize(res);
        !           688:     return res;
        !           689:   end Round;
        !           690:
        !           691:   procedure Round ( f : in out Floating_Number; k : in natural ) is
        !           692:
        !           693:     exp : integer;
        !           694:     n : Natural_Number;
        !           695:     neg : constant boolean := Negative(f.fraction);
        !           696:     ns : natural;
        !           697:
        !           698:   begin
        !           699:     Copy(Unsigned(f.fraction),n);
        !           700:     Shift_Left(n,ns);
        !           701:     exp := k*Multprec_Natural_Numbers.Exponent - ns;
        !           702:     declare
        !           703:       cff : constant Array_of_Naturals := Coefficients(n);
        !           704:       trc : Array_of_Naturals(cff'first..cff'last-k);
        !           705:     begin
        !           706:       for i in trc'range loop
        !           707:         trc(i) := cff(i+k);
        !           708:       end loop;
        !           709:       if k > 0
        !           710:        then if cff(k-1) >= Multprec_Natural_Numbers.Base/2
        !           711:              then trc(0) := trc(0)+1;
        !           712:             end if;
        !           713:       end if;
        !           714:       Clear(f.fraction);
        !           715:       f.fraction := Create(trc);
        !           716:       if neg
        !           717:        then Min(f.fraction);
        !           718:       end if;
        !           719:     end;
        !           720:     Clear(n);
        !           721:     Add(f.exponent,exp);
        !           722:     Normalize(f);
        !           723:   end Round;
        !           724:
        !           725:   function Trunc ( f : Floating_Number ) return double_float is
        !           726:
        !           727:     res : double_float;
        !           728:     szf,ns : natural;
        !           729:     n : Natural_Number;
        !           730:     expo : Integer_Number;
        !           731:
        !           732:   begin
        !           733:     if (Empty(f.fraction) or else Equal(f.fraction,0))
        !           734:      then res := 0.0;
        !           735:      else n := Unsigned(f.fraction);
        !           736:           Shift_Left(n,ns);
        !           737:           expo := f.exponent - ns;
        !           738:           szf := Size(n);
        !           739:           while Coefficient(n,szf) = 0 and szf > 0 loop
        !           740:             szf := szf - 1;
        !           741:           end loop;
        !           742:           res := double_float(Coefficient(f.fraction,szf));
        !           743:           if szf >= 1
        !           744:            then res := res*double_float(Multprec_Natural_Numbers.Base)
        !           745:                      + double_float(Coefficient(f.fraction,szf-1));
        !           746:                 if szf >= 2
        !           747:                  then ns := (szf - 1)*Multprec_Natural_Numbers.Exponent;
        !           748:                       Add(expo,ns);
        !           749:                 end if;
        !           750:           end if;
        !           751:           Adjust_Expo(res,expo);
        !           752:           Clear(n); Clear(expo);
        !           753:     end if;
        !           754:     return res;
        !           755:   end Trunc;
        !           756:
        !           757:   function Trunc ( f : Floating_Number; k : natural ) return Floating_Number is
        !           758:
        !           759:     res : Floating_Number;
        !           760:     cff : Array_of_Naturals(0..(Size(f.fraction)-k));
        !           761:     exp : integer;
        !           762:
        !           763:   begin
        !           764:     Truncate(f.fraction,k,cff,exp);
        !           765:     res.fraction := Create(Create(cff));
        !           766:     if Negative(f.fraction)
        !           767:      then Min(res.fraction);
        !           768:     end if;
        !           769:     Copy(f.exponent,res.exponent);
        !           770:     Add(res.exponent,exp);
        !           771:     return res;
        !           772:   end Trunc;
        !           773:
        !           774:   procedure Trunc ( f : in out Floating_Number; k : in natural ) is
        !           775:
        !           776:     exp : integer;
        !           777:     n : Natural_Number;
        !           778:     neg : constant boolean := Negative(f.fraction);
        !           779:     ns : natural;
        !           780:
        !           781:   begin
        !           782:     Copy(Unsigned(f.fraction),n);
        !           783:     Shift_Left(n,ns);
        !           784:     exp := k*Multprec_Natural_Numbers.Exponent - ns;
        !           785:     declare
        !           786:       cff : constant Array_of_Naturals := Coefficients(n);
        !           787:       trc : Array_of_Naturals(cff'first..cff'last-k);
        !           788:     begin
        !           789:       for i in trc'range loop
        !           790:         trc(i) := cff(i+k);
        !           791:       end loop;
        !           792:       Clear(f.fraction);
        !           793:       f.fraction := Create(trc);
        !           794:       if neg
        !           795:        then Min(f.fraction);
        !           796:       end if;
        !           797:     end;
        !           798:     Clear(n);
        !           799:     Add(f.exponent,exp);
        !           800:   end Trunc;
        !           801:
        !           802:   procedure Set_Size ( f : in out Floating_Number; k : in natural ) is
        !           803:
        !           804:     sz : constant natural := Size_Fraction(f);
        !           805:
        !           806:   begin
        !           807:     if sz > k
        !           808:      then Round(f,sz-k);
        !           809:      elsif sz < k
        !           810:          then Expand(f,k-sz);
        !           811:     end if;
        !           812:   end Set_Size;
        !           813:
        !           814: -- ARITHMETIC OPERATIONS as functions (no data sharing) :
        !           815:
        !           816:   function "+" ( f1 : Floating_Number; f2 : double_float )
        !           817:                return Floating_Number is
        !           818:
        !           819:     ff2 : Floating_Number := Create(f2);
        !           820:     res : Floating_Number := f1+ff2;
        !           821:
        !           822:   begin
        !           823:     Clear(ff2);
        !           824:     return res;
        !           825:   end "+";
        !           826:
        !           827:   function "+" ( f1 : double_float; f2 : Floating_Number )
        !           828:                return Floating_Number is
        !           829:   begin
        !           830:     return f2+f1;
        !           831:   end "+";
        !           832:
        !           833:   function "+" ( f1,f2 : Floating_Number ) return Floating_Number is
        !           834:
        !           835:     res : Floating_Number;
        !           836:     maxsz,diff_size,max_diff : integer;
        !           837:     diff_expo : Integer_Number;
        !           838:     cnt : natural;
        !           839:
        !           840:   begin
        !           841:     if (Empty(f1.fraction) or else Equal(f1.fraction,0))
        !           842:      then Copy(f2,res);
        !           843:      elsif (Empty(f2.fraction) or else Equal(f2.fraction,0))
        !           844:          then Copy(f1,res);
        !           845:          else maxsz := Max_Size(f1.fraction,f2.fraction) + 1;
        !           846:               if Equal(f1.exponent,f2.exponent)
        !           847:                then res.fraction := f1.fraction + f2.fraction;
        !           848:                     Copy(f1.exponent,res.exponent);
        !           849:                else diff_expo := f1.exponent - f2.exponent;
        !           850:                     max_diff := maxsz*Multprec_Natural_Numbers.Exponent;
        !           851:                     if diff_expo > 0
        !           852:                      then Copy(f1.fraction,res.fraction);
        !           853:                           if diff_expo < 2*max_diff
        !           854:                            then cnt := Create(diff_expo);
        !           855:                                 for i in 1..cnt loop
        !           856:                                   Mul(res.fraction,10);
        !           857:                                 end loop;
        !           858:                                 Add(res.fraction,f2.fraction);
        !           859:                                 Copy(f2.exponent,res.exponent);
        !           860:                            else Copy(f1.exponent,res.exponent);
        !           861:                           end if;
        !           862:                      else Copy(f2.fraction,res.fraction);
        !           863:                           Min(diff_expo);
        !           864:                           if diff_expo < 2*max_diff
        !           865:                            then cnt := Create(diff_expo);
        !           866:                                 for i in 1..cnt loop
        !           867:                                   Mul(res.fraction,10);
        !           868:                                 end loop;
        !           869:                                 Add(res.fraction,f1.fraction);
        !           870:                                 Copy(f1.exponent,res.exponent);
        !           871:                            else Copy(f2.exponent,res.exponent);
        !           872:                           end if;
        !           873:                     end if;
        !           874:                     Clear(diff_expo);
        !           875:               end if;
        !           876:               diff_size := Size(res.fraction) + 1 - maxsz;
        !           877:               if diff_size > 0
        !           878:                then Round(res,diff_size);
        !           879:                else Normalize(res);
        !           880:               end if;
        !           881:     end if;
        !           882:     return res;
        !           883:   end "+";
        !           884:
        !           885:   function "+" ( f : Floating_Number ) return Floating_Number is
        !           886:
        !           887:     res : Floating_Number;
        !           888:
        !           889:   begin
        !           890:     Copy(f,res);
        !           891:     return res;
        !           892:   end "+";
        !           893:
        !           894:   function "-" ( f : Floating_Number ) return Floating_Number is
        !           895:
        !           896:     res : Floating_Number;
        !           897:
        !           898:   begin
        !           899:     Copy(f,res);
        !           900:     Min(res.fraction);
        !           901:     return res;
        !           902:   end "-";
        !           903:
        !           904:   function "-" ( f1 : Floating_Number; f2 : double_float )
        !           905:                return Floating_Number is
        !           906:
        !           907:     minf2 : double_float := -f2;
        !           908:     res : Floating_Number := f1+minf2;
        !           909:
        !           910:   begin
        !           911:     return res;
        !           912:   end "-";
        !           913:
        !           914:   function "-" ( f1 : double_float; f2 : Floating_Number )
        !           915:                return Floating_Number is
        !           916:
        !           917:     ff1 : Floating_Number := Create(f1);
        !           918:     res : Floating_Number := ff1 - f2;
        !           919:
        !           920:   begin
        !           921:     Clear(ff1);
        !           922:     return res;
        !           923:   end "-";
        !           924:
        !           925:   function "-" ( f1,f2 : Floating_Number ) return Floating_Number is
        !           926:
        !           927:     res,minf2 : Floating_Number;
        !           928:
        !           929:   begin
        !           930:     minf2.exponent := f2.exponent;
        !           931:     minf2.fraction := -f2.fraction;
        !           932:     res := f1 + minf2;
        !           933:     Clear(minf2.fraction);
        !           934:     return res;
        !           935:   end "-";
        !           936:
        !           937:   function "*" ( f1 : Floating_Number; f2 : double_float )
        !           938:                return Floating_Number is
        !           939:
        !           940:     ff2 : Floating_Number := Create(f2);
        !           941:     res : Floating_Number := f1*ff2;
        !           942:
        !           943:   begin
        !           944:     Clear(ff2);
        !           945:     return res;
        !           946:   end "*";
        !           947:
        !           948:   function "*" ( f1 : double_float; f2 : Floating_Number )
        !           949:                return Floating_Number is
        !           950:
        !           951:     ff1 : Floating_Number := Create(f1);
        !           952:     res : Floating_Number := ff1*f2;
        !           953:
        !           954:   begin
        !           955:     Clear(ff1);
        !           956:     return res;
        !           957:   end "*";
        !           958:
        !           959:   function "*" ( f1,f2 : Floating_Number ) return Floating_Number is
        !           960:
        !           961:     res : Floating_Number;
        !           962:     diffsize : integer;
        !           963:
        !           964:   begin
        !           965:     if not (Empty(f1.fraction) or else Equal(f1.fraction,0))
        !           966:      then if not (Empty(f2.fraction) or else Equal(f2.fraction,0))
        !           967:            then res.fraction := f1.fraction*f2.fraction;
        !           968:                 res.exponent := f1.exponent+f2.exponent;
        !           969:                 diffsize := Size(res.fraction)
        !           970:                           - Max_Size(f1.fraction,f2.fraction);
        !           971:                 if diffsize > 0
        !           972:                  then Round(res,diffsize);
        !           973:                 end if;
        !           974:                 Normalize(res);
        !           975:           end if;
        !           976:     end if;
        !           977:     return res;
        !           978:   end "*";
        !           979:
        !           980:   function "**" ( f : double_float; n : Natural_Number )
        !           981:                 return Floating_Number is
        !           982:
        !           983:     ff : Floating_Number := Create(f);
        !           984:     res : Floating_Number := ff**n;
        !           985:
        !           986:   begin
        !           987:     Clear(ff);
        !           988:     return res;
        !           989:   end "**";
        !           990:
        !           991:   function "**" ( f : Floating_Number; n : Natural_Number )
        !           992:                 return Floating_Number is
        !           993:
        !           994:     res : Floating_Number;
        !           995:     cnt : Natural_Number;
        !           996:
        !           997:   begin
        !           998:     if (Empty(n) or else Equal(n,0))
        !           999:      then res := Create(1);
        !          1000:      else Copy(f,res);
        !          1001:           cnt := Create(1);
        !          1002:           while cnt < n loop
        !          1003:             Mul(res,f);
        !          1004:             Add(cnt,1);
        !          1005:           end loop;
        !          1006:           Clear(cnt);
        !          1007:           Normalize(res);
        !          1008:     end if;
        !          1009:     return res;
        !          1010:   end "**";
        !          1011:
        !          1012:   function "**" ( f : Floating_Number; i : integer ) return Floating_Number is
        !          1013:
        !          1014:     res : Floating_Number;
        !          1015:
        !          1016:   begin
        !          1017:     if i = 0
        !          1018:      then res := Create(1.0);
        !          1019:      else if i > 0
        !          1020:            then Copy(f,res);
        !          1021:                 for j in 1..(i-1) loop
        !          1022:                   Mul(res,f);
        !          1023:                 end loop;
        !          1024:            else res := Create(1);
        !          1025:                 for j in 1..(-i) loop
        !          1026:                   Div(res,f);
        !          1027:                 end loop;
        !          1028:           end if;
        !          1029:           Normalize(res);
        !          1030:     end if;
        !          1031:     return res;
        !          1032:   end "**";
        !          1033:
        !          1034:   function "**" ( f : double_float; i : Integer_Number )
        !          1035:                 return Floating_Number is
        !          1036:
        !          1037:     ff : Floating_Number := Create(f);
        !          1038:     res : Floating_Number := ff**i;
        !          1039:
        !          1040:   begin
        !          1041:     Clear(ff);
        !          1042:     return res;
        !          1043:   end "**";
        !          1044:
        !          1045:   function "**" ( f : Floating_Number; i : Integer_Number )
        !          1046:                 return Floating_Number is
        !          1047:
        !          1048:     res : Floating_Number;
        !          1049:     cnt,n : Natural_Number;
        !          1050:
        !          1051:   begin
        !          1052:     if (Empty(i) or else Equal(i,0))
        !          1053:      then res := Create(1);
        !          1054:      else n := Unsigned(i);
        !          1055:           if i > 0
        !          1056:            then Copy(f,res);
        !          1057:                 cnt := Create(1);
        !          1058:                 while cnt < n loop
        !          1059:                   Mul(res,f);
        !          1060:                   Add(cnt,1);
        !          1061:                 end loop;
        !          1062:            else res := Create(1);
        !          1063:                 cnt := Create(0);
        !          1064:                 while cnt < n loop
        !          1065:                   Div(res,f);
        !          1066:                   Add(cnt,1);
        !          1067:                 end loop;
        !          1068:           end if;
        !          1069:           Clear(cnt);
        !          1070:           Normalize(res);
        !          1071:     end if;
        !          1072:     return res;
        !          1073:   end "**";
        !          1074:
        !          1075:   function "/" ( f1 : Floating_Number; f2 : double_float )
        !          1076:                return Floating_Number is
        !          1077:
        !          1078:     ff2 : Floating_Number := Create(f2);
        !          1079:     res : Floating_Number := f1/ff2;
        !          1080:
        !          1081:   begin
        !          1082:     Clear(ff2);
        !          1083:     return res;
        !          1084:   end "/";
        !          1085:
        !          1086:   function "/" ( f1 : double_float; f2 : Floating_Number )
        !          1087:                return Floating_Number is
        !          1088:
        !          1089:     ff1 : Floating_Number := Create(f1);
        !          1090:     res : Floating_Number := ff1/f2;
        !          1091:
        !          1092:   begin
        !          1093:     Clear(ff1);
        !          1094:     return res;
        !          1095:   end "/";
        !          1096:
        !          1097:   function Pos_Div ( f1,f2 : Floating_Number ) return Floating_Number is
        !          1098:
        !          1099:   -- DESCRIPTION :
        !          1100:   --   This division only applies when f1 and f2 are both positive.
        !          1101:
        !          1102:     res : Floating_Number;
        !          1103:     rmd_frac,new_rmd_frac : Integer_Number;
        !          1104:     diffsize : integer;
        !          1105:     maxsz : natural := Max_Size(f1.fraction,f2.fraction);
        !          1106:
        !          1107:   begin
        !          1108:     Div(f1.fraction,f2.fraction,res.fraction,rmd_frac);
        !          1109:     res.exponent := f1.exponent - f2.exponent;
        !          1110:     diffsize := Size(res.fraction) - maxsz;
        !          1111:     if not Equal(rmd_frac,0)
        !          1112:      then while diffsize <= 0 loop
        !          1113:             while rmd_frac < f2.fraction loop
        !          1114:               Mul(rmd_frac,10);
        !          1115:               Mul(res.fraction,10);
        !          1116:               Sub(res.exponent,1);
        !          1117:             end loop;
        !          1118:             Div(rmd_frac,f2.fraction,new_rmd_frac);
        !          1119:             Add(res.fraction,rmd_frac);
        !          1120:             Clear(rmd_frac); rmd_frac := new_rmd_frac;
        !          1121:             diffsize := Size(res.fraction) - maxsz;
        !          1122:             exit when Equal(rmd_frac,0);
        !          1123:           end loop;
        !          1124:     end if;
        !          1125:     Clear(rmd_frac);
        !          1126:     if diffsize > 0
        !          1127:      then Round(res,diffsize);
        !          1128:     end if;
        !          1129:     Normalize(res);
        !          1130:     return res;
        !          1131:   end Pos_Div;
        !          1132:
        !          1133:   function "/" ( f1,f2 : Floating_Number ) return Floating_Number is
        !          1134:
        !          1135:     res,minf1,minf2 : Floating_Number;
        !          1136:
        !          1137:   begin
        !          1138:     if not (Empty(f1.fraction) or else Equal(f1.fraction,0))
        !          1139:      then if not (Empty(f2.fraction) or else Equal(f2.fraction,0))
        !          1140:            then if Multprec_Integer_Numbers.Positive(f1.fraction)
        !          1141:                  then if Multprec_Integer_Numbers.Positive(f2.fraction)
        !          1142:                        then res := Pos_Div(f1,f2);
        !          1143:                        else minf2.fraction := -f2.fraction;
        !          1144:                             minf2.exponent := f2.exponent;
        !          1145:                             res := Pos_Div(f1,minf2);
        !          1146:                             Clear(minf2.fraction);
        !          1147:                             Min(res);
        !          1148:                       end if;
        !          1149:                  else minf1.fraction := -f1.fraction;
        !          1150:                       minf1.exponent := f1.exponent;
        !          1151:                       if Multprec_Integer_Numbers.Positive(f2.fraction)
        !          1152:                        then res := Pos_Div(minf1,f2);
        !          1153:                             Min(res);
        !          1154:                        else minf2.fraction := -f2.fraction;
        !          1155:                             minf2.exponent := f2.exponent;
        !          1156:                             res := Pos_Div(minf1,minf2);
        !          1157:                             Clear(minf2.fraction);
        !          1158:                       end if;
        !          1159:                       Clear(minf1.fraction);
        !          1160:                 end if;
        !          1161:            else raise NUMERIC_ERROR;
        !          1162:           end if;
        !          1163:     end if;
        !          1164:     return res;
        !          1165:   end "/";
        !          1166:
        !          1167: -- ARITHMETIC OPERATIONS as procedures for memory management :
        !          1168:
        !          1169:   procedure Add ( f1 : in out Floating_Number; f2 : in double_float ) is
        !          1170:
        !          1171:     ff2 : Floating_Number := Create(f2);
        !          1172:
        !          1173:   begin
        !          1174:     Add(f1,ff2);
        !          1175:     Clear(ff2);
        !          1176:   end Add;
        !          1177:
        !          1178:   procedure Add ( f1 : in out Floating_Number; f2 : in Floating_Number ) is
        !          1179:
        !          1180:     res : Floating_Number;
        !          1181:     maxsz,diff_size,max_diff : integer;
        !          1182:     diff_expo : Integer_Number;
        !          1183:     cnt : natural;
        !          1184:
        !          1185:   begin
        !          1186:     if (Empty(f1.fraction) or else Equal(f1.fraction,0))
        !          1187:      then Copy(f2,f1);
        !          1188:      elsif (Empty(f2.fraction) or else Equal(f2.fraction,0))
        !          1189:          then null;
        !          1190:          else maxsz := Max_Size(f1.fraction,f2.fraction) + 1;
        !          1191:               if Equal(f1.exponent,f2.exponent)
        !          1192:                then Add(f1.fraction,f2.fraction);
        !          1193:                else diff_expo := f1.exponent - f2.exponent;
        !          1194:                     max_diff := maxsz*Multprec_Natural_Numbers.Exponent;
        !          1195:                     if diff_expo > 0
        !          1196:                      then if diff_expo < 2*max_diff
        !          1197:                            then cnt := Create(diff_expo);
        !          1198:                                 for i in 1..cnt loop
        !          1199:                                   Mul(f1.fraction,10);
        !          1200:                                 end loop;
        !          1201:                                 Add(f1.fraction,f2.fraction);
        !          1202:                                 Copy(f2.exponent,f1.exponent);
        !          1203:                            else null;
        !          1204:                           end if;
        !          1205:                      else Copy(f2.fraction,res.fraction);
        !          1206:                           Min(diff_expo);
        !          1207:                           if diff_expo < 2*max_diff
        !          1208:                            then cnt := Create(diff_expo);
        !          1209:                                 for i in 1..cnt loop
        !          1210:                                   Mul(res.fraction,10);
        !          1211:                                 end loop;
        !          1212:                                 Add(f1.fraction,res.fraction);
        !          1213:                                 Clear(res.fraction);
        !          1214:                            else Copy(f2.exponent,f1.exponent);
        !          1215:                                 Clear(f1.fraction);
        !          1216:                                 f1.fraction := res.fraction;
        !          1217:                           end if;
        !          1218:                     end if;
        !          1219:                     Clear(diff_expo);
        !          1220:               end if;
        !          1221:               diff_size := Size(f1.fraction) + 1 - maxsz;
        !          1222:               if diff_size > 0
        !          1223:                then Round(f1,diff_size);
        !          1224:                else Normalize(f1);
        !          1225:               end if;
        !          1226:     end if;
        !          1227:   end Add;
        !          1228:
        !          1229:   procedure Sub ( f1 : in out Floating_Number; f2 : in double_float ) is
        !          1230:
        !          1231:     minf2 : double_float := -f2;
        !          1232:
        !          1233:   begin
        !          1234:     Add(f1,minf2);
        !          1235:   end Sub;
        !          1236:
        !          1237:   procedure Sub ( f1 : in out Floating_Number; f2 : in Floating_Number ) is
        !          1238:
        !          1239:     minf2 : Floating_Number;
        !          1240:
        !          1241:   begin
        !          1242:     minf2.exponent := f2.exponent;
        !          1243:     minf2.fraction := -f2.fraction;
        !          1244:     Add(f1,minf2);
        !          1245:     Clear(minf2.fraction);
        !          1246:   end Sub;
        !          1247:
        !          1248:   procedure Min ( f : in out Floating_Number ) is
        !          1249:   begin
        !          1250:     Min(f.fraction);
        !          1251:   end Min;
        !          1252:
        !          1253:   procedure Mul ( f1 : in out Floating_Number; f2 : in double_float ) is
        !          1254:
        !          1255:     ff2 : Floating_Number := Create(f2);
        !          1256:
        !          1257:   begin
        !          1258:     Mul(f1,ff2);
        !          1259:     Clear(ff2);
        !          1260:   end Mul;
        !          1261:
        !          1262:   procedure Mul ( f1 : in out Floating_Number; f2 : in Floating_Number ) is
        !          1263:
        !          1264:     diffsize,maxsize : integer;
        !          1265:
        !          1266:   begin
        !          1267:     if Empty(f2.fraction)
        !          1268:      then Clear(f1);
        !          1269:      elsif Equal(f2.fraction,0)
        !          1270:          then Clear(f1);
        !          1271:          elsif Empty(f1.fraction)
        !          1272:              then null;
        !          1273:              elsif Equal(f1.fraction,0)
        !          1274:                  then null;
        !          1275:                  else maxsize := Max_Size(f1.fraction,f2.fraction);
        !          1276:                       Mul(f1.fraction,f2.fraction);
        !          1277:                       Add(f1.exponent,f2.exponent);
        !          1278:                       diffsize := Size(f1.fraction) - maxsize;
        !          1279:                       if diffsize > 0
        !          1280:                        then Round(f1,diffsize);
        !          1281:                       end if;
        !          1282:                       Normalize(f1);
        !          1283:     end if;
        !          1284:   end Mul;
        !          1285:
        !          1286:   procedure Div ( f1 : in out Floating_Number; f2 : in double_float ) is
        !          1287:
        !          1288:     ff2 : Floating_Number := Create(f2);
        !          1289:
        !          1290:   begin
        !          1291:     Div(f1,ff2);
        !          1292:     Clear(ff2);
        !          1293:   end Div;
        !          1294:
        !          1295:   procedure Pos_Div ( f1 : in out Floating_Number; f2 : in Floating_Number ) is
        !          1296:
        !          1297:   -- DESCRIPTION :
        !          1298:   --   Does the division in case f1 and f2 are both positive.
        !          1299:
        !          1300:     rmd_frac,new_rmd_frac : Integer_Number;
        !          1301:     diffsize : integer;
        !          1302:     maxsz : natural := Max_Size(f1.fraction,f2.fraction);
        !          1303:
        !          1304:   begin
        !          1305:     Div(f1.fraction,f2.fraction,rmd_frac);
        !          1306:     Sub(f1.exponent,f2.exponent);
        !          1307:     diffsize := Size(f1.fraction) - maxsz;
        !          1308:     if not Equal(rmd_frac,0)
        !          1309:      then while diffsize <= 0 loop
        !          1310:             while rmd_frac < f2.fraction loop
        !          1311:               Mul(rmd_frac,10);
        !          1312:               Mul(f1.fraction,10);
        !          1313:               Sub(f1.exponent,1);
        !          1314:             end loop;
        !          1315:             Div(rmd_frac,f2.fraction,new_rmd_frac);
        !          1316:             Add(f1.fraction,rmd_frac);
        !          1317:             Clear(rmd_frac); rmd_frac := new_rmd_frac;
        !          1318:             diffsize := Size(f1.fraction) - maxsz;
        !          1319:             exit when Equal(rmd_frac,0);
        !          1320:           end loop;
        !          1321:     end if;
        !          1322:     Clear(rmd_frac);
        !          1323:     if diffsize > 0
        !          1324:      then Round(f1,diffsize);
        !          1325:     end if;
        !          1326:     Normalize(f1);
        !          1327:   end Pos_Div;
        !          1328:
        !          1329:   procedure Div ( f1 : in out Floating_Number; f2 : in Floating_Number ) is
        !          1330:
        !          1331:     minf1,minf2 : Floating_Number;
        !          1332:
        !          1333:   begin
        !          1334:     if not (Empty(f1.fraction) or else Equal(f1.fraction,0))
        !          1335:      then if not (Empty(f2.fraction) or else Equal(f2.fraction,0))
        !          1336:            then if Multprec_Integer_Numbers.Positive(f1.fraction)
        !          1337:                  then if Multprec_Integer_Numbers.Positive(f2.fraction)
        !          1338:                        then Pos_Div(f1,f2);
        !          1339:                        else minf2.fraction := -f2.fraction;
        !          1340:                             minf2.exponent := f2.exponent;
        !          1341:                             Pos_Div(f1,minf2);
        !          1342:                             Clear(minf2.fraction); Min(f1);
        !          1343:                       end if;
        !          1344:                  else minf1 := -f1;
        !          1345:                       if Multprec_Integer_Numbers.Positive(f2.fraction)
        !          1346:                        then Pos_Div(minf1,f2);
        !          1347:                             Clear(f1); f1 := minf1; Min(f1);
        !          1348:                        else minf2.fraction := -f2.fraction;
        !          1349:                             minf2.exponent := f2.exponent;
        !          1350:                             Pos_Div(minf1,minf2);
        !          1351:                             Clear(minf2.fraction);
        !          1352:                             Clear(f1); f1 := minf1;
        !          1353:                       end if;
        !          1354:                 end if;
        !          1355:            else raise NUMERIC_ERROR;
        !          1356:           end if;
        !          1357:     end if;
        !          1358:   end Div;
        !          1359:
        !          1360: -- DESTRUCTOR :
        !          1361:
        !          1362:   procedure Clear ( f : in out Floating_Number ) is
        !          1363:   begin
        !          1364:     Clear(f.fraction);
        !          1365:     Clear(f.exponent);
        !          1366:   end Clear;
        !          1367:
        !          1368: end Multprec_Floating_Numbers;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>