Annotation of OpenXM_contrib/PHC/Ada/Math_Lib/Numbers/multprec_floating_numbers_io.adb, Revision 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>