[BACK]Return to multprec_floating_numbers_io.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_io.adb, Revision 1.1.1.1

1.1       maekawa     1: with integer_io;                         use integer_io;
                      2: with Characters_and_Numbers;             use Characters_and_Numbers;
                      3: with Multprec_Natural_Numbers;           use Multprec_Natural_Numbers;
                      4: with Multprec_Natural_Numbers_io;        use Multprec_Natural_Numbers_io;
                      5: with Multprec_Integer_Numbers;           use Multprec_Integer_Numbers;
                      6: with Multprec_Integer_Numbers_io;        use Multprec_Integer_Numbers_io;
                      7:
                      8: package body Multprec_Floating_Numbers_io is
                      9:
                     10: -- NOTE :
                     11: --   No exceptions are raised when the input format is incorrect.
                     12:
                     13: -- AUXILIARIES FOR OUTPUT :
                     14:
                     15:   function Head ( i : Integer_Number ) return integer is
                     16:
                     17:   -- DESCRIPTION :
                     18:   --   Returns the leading decimal number of the i, can be negative.
                     19:
                     20:     res : integer;
                     21:     wrk : Integer_Number;
                     22:
                     23:   begin
                     24:     if Multprec_Integer_Numbers.Positive(i)
                     25:      then Copy(i,wrk);
                     26:           while wrk > 9 loop
                     27:             Div(wrk,10);
                     28:           end loop;
                     29:           res := Create(wrk);
                     30:           Clear(wrk);
                     31:      elsif Negative(i)
                     32:          then Copy(i,wrk);
                     33:               while wrk < -9 loop
                     34:                 Div(wrk,10);
                     35:               end loop;
                     36:               res := Create(wrk);
                     37:               Clear(wrk);
                     38:          else res := 0;
                     39:     end if;
                     40:     return res;
                     41:   end Head;
                     42:
                     43:   function Tail ( i : Integer_Number ) return Natural_Number is
                     44:
                     45:   -- DESCRIPTION :
                     46:   --   Returns the decimals after the leading decimal of i.
                     47:   --   The number on return has the same size as i.
                     48:
                     49:     res : Natural_Number;
                     50:     res_rep : Array_of_Naturals(0..Size(i));
                     51:     acc,wrk,prod : Integer_Number;
                     52:     cnt : natural := 0;
                     53:     r : integer;
                     54:
                     55:   begin
                     56:     if Multprec_Integer_Numbers.Positive(i)
                     57:      then Copy(i,wrk);
                     58:           while wrk > 9 loop
                     59:             cnt := cnt+1;
                     60:             Div(wrk,10,r);
                     61:             if r /= 0
                     62:              then prod := Create(r);
                     63:                   for i in 1..cnt-1 loop
                     64:                     Mul(prod,10);
                     65:                   end loop;
                     66:                   Add(acc,prod);
                     67:                   Clear(prod);
                     68:             end if;
                     69:           end loop;
                     70:           Clear(wrk);
                     71:      elsif Negative(i)
                     72:          then Copy(i,wrk);
                     73:               while wrk < -9 loop
                     74:                 cnt := cnt+1;
                     75:                 Div(wrk,10,r);
                     76:                 if r /= 0
                     77:                  then prod := Create(r);
                     78:                       for i in 1..cnt-1 loop
                     79:                         Mul(prod,10);
                     80:                       end loop;
                     81:                       Add(acc,prod);
                     82:                       Clear(prod);
                     83:                 end if;
                     84:               end loop;
                     85:               Clear(wrk);
                     86:          else acc := Create(0);
                     87:     end if;
                     88:     for i in res_rep'range loop
                     89:       res_rep(i) := Coefficient(acc,i);
                     90:     end loop;
                     91:     Clear(acc);
                     92:     res := Create(res_rep);
                     93:     return res;
                     94:   end Tail;
                     95:
                     96:   procedure Write_Number ( file : in file_type; n : in natural;
                     97:                            cnt : in out natural ) is
                     98:   begin
                     99:     if n < 10
                    100:      then put(file,n,1);
                    101:           cnt := cnt - 1;
                    102:      else Write_Number(file,n/10,cnt);
                    103:           if cnt > 0
                    104:            then put(file,n mod 10,1);
                    105:                 cnt := cnt - 1;
                    106:           end if;
                    107:     end if;
                    108:   end Write_Number;
                    109:
                    110:   procedure Write_Block ( file : in file_type; n : in natural;
                    111:                           cnt : in out natural ) is
                    112:
                    113:   -- DESCRIPTION :
                    114:   --   This procedure writes the leading zeros, not exceeding cnt.
                    115:
                    116:     expo : constant natural := Multprec_Natural_Numbers.Exponent;
                    117:     nbz,acc : natural := 0;
                    118:
                    119:   begin
                    120:     if n = 0
                    121:      then for i in 1..expo loop
                    122:             put(file,"0");
                    123:             cnt := cnt - 1;
                    124:             exit when (cnt = 0);
                    125:           end loop;
                    126:      else acc := 10;
                    127:           for i in 1..(expo-1) loop
                    128:             if n < acc
                    129:              then nbz := expo-i;
                    130:              else acc := acc*10;
                    131:             end if;
                    132:             exit when (nbz /= 0);
                    133:           end loop;
                    134:           for i in 1..nbz loop
                    135:             put(file,"0");
                    136:             cnt := cnt - 1;
                    137:             exit when (cnt = 0);
                    138:           end loop;
                    139:           if cnt > 0
                    140:            then Write_Number(file,n,cnt);
                    141:           end if;
                    142:     end if;
                    143:   end Write_Block;
                    144:
                    145:   procedure Write_Zero_Block ( file : in file_type; cnt : in out natural ) is
                    146:
                    147:   -- DESCRIPTION :
                    148:   --   Writes as many zeros as there are in one block, not exceeding cnt.
                    149:
                    150:     expo : constant natural := Multprec_Natural_Numbers.Exponent;
                    151:
                    152:   begin
                    153:     for i in 1..expo loop
                    154:       put(file,"0");
                    155:       cnt := cnt - 1;
                    156:       exit when (cnt = 0);
                    157:     end loop;
                    158:   end Write_Zero_Block;
                    159:
                    160:   procedure put ( file : in file_type;
                    161:                   n : in Natural_Number; dp : in natural ) is
                    162:
                    163:   -- DESCRIPTION :
                    164:   --   Writes the natural number n using dp decimal places.
                    165:   --   If n is too long, then the leading dp decimal places will be written,
                    166:   --   otherwise zeros will be added.
                    167:
                    168:     deciplan : natural := Decimal_Places(n);
                    169:     first : boolean;
                    170:     coeff,cnt : natural;
                    171:
                    172:   begin
                    173:     if deciplan <= dp
                    174:      then put(file,n);
                    175:           for i in 1..(dp-deciplan) loop
                    176:             put(file,"0");
                    177:           end loop;
                    178:      else first := true;
                    179:           cnt := dp;
                    180:           for i in reverse 0..Size(n) loop
                    181:             coeff := Coefficient(n,i);
                    182:             if coeff /= 0
                    183:              then if first
                    184:                    then Write_Number(file,coeff,cnt);
                    185:                         first := false;
                    186:                    else Write_Block(file,coeff,cnt);
                    187:                   end if;
                    188:              elsif not first
                    189:                  then Write_Zero_Block(file,cnt);
                    190:               -- else skip leading zeros in representation
                    191:             end if;
                    192:             exit when (cnt = 0);
                    193:           end loop;
                    194:     end if;
                    195:   end put;
                    196:
                    197: -- INPUT ROUTINES :
                    198:
                    199:   procedure get ( f : in out Floating_Number ) is
                    200:   begin
                    201:     get(Standard_Input,f);
                    202:   end get;
                    203:
                    204:   procedure get ( file : in file_type; f : in out Floating_Number ) is
                    205:
                    206:     fraction,decifrac,exponent : Integer_Number;
                    207:     shifexpo : integer := 0;
                    208:     deciplac : natural;
                    209:     c : character := ' ';
                    210:
                    211:   begin
                    212:     get(file,c,fraction);
                    213:     if c = '.'
                    214:      then get(file,c);
                    215:           while c = '0' loop
                    216:             Mul(fraction,10);
                    217:             shifexpo := shifexpo - 1;
                    218:             exit when End_of_Line(file);
                    219:             get(file,c);
                    220:           end loop;
                    221:           if Convert(c) < 10
                    222:            then get(file,c,decifrac);
                    223:                 deciplac := Decimal_Places(decifrac);
                    224:                 shifexpo := shifexpo - deciplac;
                    225:                 for i in 1..deciplac loop
                    226:                   Mul(fraction,10);
                    227:                 end loop;
                    228:                 if Negative(fraction)
                    229:                  then Sub(fraction,decifrac);
                    230:                  else Add(fraction,decifrac);
                    231:                 end if;
                    232:           end if;
                    233:     end if;
                    234:     if c = 'E'
                    235:      then get(file,exponent);
                    236:           if Equal(fraction,0)
                    237:            then Clear(exponent);
                    238:                 exponent := Create(0);
                    239:            elsif shifexpo /= 0
                    240:                then Add(exponent,shifexpo);
                    241:           end if;
                    242:      else if Equal(fraction,0)
                    243:            then exponent := Create(0);
                    244:            else exponent := Create(shifexpo);
                    245:           end if;
                    246:     end if;
                    247:     f := Create(fraction,exponent);
                    248:   end get;
                    249:
                    250: -- OUTPUT ROUTINES :
                    251:
                    252:   procedure put ( f : in Floating_Number ) is
                    253:   begin
                    254:     put(Standard_Output,f);
                    255:   end put;
                    256:
                    257:   procedure put ( file : in file_type; f : in Floating_Number ) is
                    258:
                    259:     frac,expo : Integer_Number;
                    260:     tafr : Natural_Number;
                    261:     decifrac,decitafr : natural;
                    262:     hd : integer;
                    263:
                    264:   begin
                    265:     Copy(Fraction(f),frac);
                    266:     if Equal(frac,0)
                    267:      then put(file,"0");
                    268:      else hd := Head(frac);
                    269:           put(file,hd,1); put(file,".");
                    270:           tafr := Tail(Fraction(f));
                    271:           decifrac := Decimal_Places(frac);
                    272:           decitafr := Decimal_Places(tafr);
                    273:           if not Equal(tafr,0)
                    274:            then for i in 1..decifrac-decitafr-1 loop
                    275:                   put(file,"0");
                    276:                 end loop;
                    277:                 put(file,tafr);
                    278:            else put(file,"0");
                    279:           end if;
                    280:           expo := Exponent(f) + (decifrac - 1);
                    281:           if not Equal(expo,0)
                    282:            then put(file,"E");
                    283:                 if expo > 0
                    284:                  then put(file,"+");
                    285:                 end if;
                    286:                 put(file,expo);
                    287:           end if;
                    288:           Clear(tafr);
                    289:           Clear(expo);
                    290:     end if;
                    291:     Clear(frac);
                    292:   end put;
                    293:
                    294:   procedure put ( f : in Floating_Number; fore,aft,exp : in natural ) is
                    295:   begin
                    296:     put(Standard_Output,f,fore,aft,exp);
                    297:   end put;
                    298:
                    299:   procedure put ( file : in file_type;
                    300:                   f : in Floating_Number; fore,aft,exp : in natural ) is
                    301:
                    302:     frac,expo : Integer_Number;
                    303:     tafr : Natural_Number;
                    304:     decifrac,decitafr,deciexpo,cnt : natural;
                    305:     hd : integer;
                    306:
                    307:   begin
                    308:     Copy(Fraction(f),frac);
                    309:     if Equal(frac,0)
                    310:      then for i in 1..(fore-1) loop
                    311:             put(file," ");
                    312:           end loop;
                    313:           put(file,"0.");
                    314:           for i in 1..aft loop
                    315:             put(file,"0");
                    316:           end loop;
                    317:           put(file,"E+");
                    318:           for i in 1..(exp-1) loop
                    319:             put(file,"0");
                    320:           end loop;
                    321:      else hd := Head(frac);
                    322:           if hd > 0
                    323:            then for i in 1..(fore-1) loop
                    324:                   put(file," ");
                    325:                 end loop;
                    326:            else for i in 1..(fore-2) loop
                    327:                   put(file," ");
                    328:                 end loop;
                    329:           end if;
                    330:           put(file,hd,1); put(file,".");
                    331:           tafr := Tail(Fraction(f));
                    332:           decifrac := Decimal_Places(frac);
                    333:           decitafr := Decimal_Places(tafr);
                    334:           if Equal(tafr,0)
                    335:            then for i in 1..aft loop
                    336:                   put(file,"0");
                    337:                 end loop;
                    338:            else cnt := aft;
                    339:                 for i in 1..decifrac-decitafr-1 loop
                    340:                   put(file,"0");
                    341:                   cnt := cnt-1;
                    342:                   exit when (cnt = 0);
                    343:                 end loop;
                    344:                 if cnt /= 0
                    345:                  then put(file,tafr,cnt);
                    346:                 end if;
                    347:           end if;
                    348:           expo := Exponent(f) + (decifrac - 1);
                    349:           deciexpo := Decimal_Places(expo);
                    350:           put(file,"E");
                    351:           if Equal(expo,0)
                    352:            then put(file,"+");
                    353:                 for i in 1..(exp-1) loop
                    354:                   put(file,"0");
                    355:                 end loop;
                    356:            else if expo > 0
                    357:                  then put(file,"+");
                    358:                  else put(file,"-");
                    359:                 end if;
                    360:                 for i in 1..(exp-deciexpo-1) loop
                    361:                   put(file,"0");
                    362:                 end loop;
                    363:                 put(file,Unsigned(expo));
                    364:           end if;
                    365:           Clear(tafr);
                    366:           Clear(expo);
                    367:     end if;
                    368:     Clear(frac);
                    369:   end put;
                    370:
                    371:   procedure put ( f : in Floating_Number; dp : in natural ) is
                    372:   begin
                    373:     put(f,dp,dp,dp);
                    374:   end put;
                    375:
                    376:   procedure put ( file : in file_type;
                    377:                   f : in Floating_Number; dp : in natural ) is
                    378:   begin
                    379:     put(file,f,dp,dp,dp);
                    380:   end put;
                    381:
                    382: end Multprec_Floating_Numbers_io;

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