tbreeden
2010-08-23 20:21:12 UTC
I'm trying to figure out what the ISO Std Library procs WriteReal()
and StrToReal() should output for various inputs.
Anyone thought about this?
I've stopped looking at various implementations and gone back to the
ISO document. There is not much more text there than the comment that
appears in the Definition file:
PROCEDURE RealToStr(real : REAL; VAR str : ARRAY OF CHAR);
(* Converts the value of real as RealToFixed if the sign and
magnitude
can be shown within the capacity of str, or otherwise as
RealToFloat,
and copies the possibly truncated result to str. The number of
places
or significant digits depend on the capacity of str. *)
In particular, "magnitude" is not defined in the text, but I think it
refers to the whole number part of the absolute value of the real.
That leads me to believe that WriteReal() is most appropriate for
numbers that you don't care how small they get if they are really
small, but you do care to know how big they get.
Unfortunately, unlike for RealToFixed() and RealToFloat(), the ISO
Standard neglected to put in a nice little table with example inputs
and outputs. :(
Looking at the VDM-SL definition, it seems that the RealToFixed() (or
WriteFixed()) is used only if the characters in the string
representation of that whole number part (plus 1 if a negative sign is
needed) are less than or equal to the available output character slots
(width). ie, the VDM code first counts the characters in the number
rounded to the nearest 0.5
This also implies that any number of absolute value less than 1.0 will
surely be output as WriteFixed()
So, I would expect these outputs:
r := 3.14159265358979;
WriteReal(r, 10); WriteLn; (* 3.14159265 *)
r := 314159.265358979;
WriteReal(r, 10); WriteLn; (* 314159.265 *)
r := 31415926535.8979;
WriteReal(r, 10); WriteLn; (* 3.14159E10 *)
r := 0.314159265358979;
WriteReal(r, 10); WriteLn; (* 0.31415926 *)
r := 0.0314159265358979;
WriteReal(r, 10); WriteLn; (* 0.03141592 *)
r := 0.00000314159265358979;
WriteReal(r, 10); WriteLn; (* 0.00000314 *)
r := 0.000000000314159265358979;
WriteReal(r, 10); WriteLn; (* 0.00000000 *)
This does not seem to be the way it is usually(?) implemented (eg,
StonyBrook). Rather it looks as if the implementation always uses
WriteFloat() format for any number whose absolute value is < 1.0
Have I missed something?
Thanks,
Tom
and StrToReal() should output for various inputs.
Anyone thought about this?
I've stopped looking at various implementations and gone back to the
ISO document. There is not much more text there than the comment that
appears in the Definition file:
PROCEDURE RealToStr(real : REAL; VAR str : ARRAY OF CHAR);
(* Converts the value of real as RealToFixed if the sign and
magnitude
can be shown within the capacity of str, or otherwise as
RealToFloat,
and copies the possibly truncated result to str. The number of
places
or significant digits depend on the capacity of str. *)
In particular, "magnitude" is not defined in the text, but I think it
refers to the whole number part of the absolute value of the real.
That leads me to believe that WriteReal() is most appropriate for
numbers that you don't care how small they get if they are really
small, but you do care to know how big they get.
Unfortunately, unlike for RealToFixed() and RealToFloat(), the ISO
Standard neglected to put in a nice little table with example inputs
and outputs. :(
Looking at the VDM-SL definition, it seems that the RealToFixed() (or
WriteFixed()) is used only if the characters in the string
representation of that whole number part (plus 1 if a negative sign is
needed) are less than or equal to the available output character slots
(width). ie, the VDM code first counts the characters in the number
rounded to the nearest 0.5
This also implies that any number of absolute value less than 1.0 will
surely be output as WriteFixed()
So, I would expect these outputs:
r := 3.14159265358979;
WriteReal(r, 10); WriteLn; (* 3.14159265 *)
r := 314159.265358979;
WriteReal(r, 10); WriteLn; (* 314159.265 *)
r := 31415926535.8979;
WriteReal(r, 10); WriteLn; (* 3.14159E10 *)
r := 0.314159265358979;
WriteReal(r, 10); WriteLn; (* 0.31415926 *)
r := 0.0314159265358979;
WriteReal(r, 10); WriteLn; (* 0.03141592 *)
r := 0.00000314159265358979;
WriteReal(r, 10); WriteLn; (* 0.00000314 *)
r := 0.000000000314159265358979;
WriteReal(r, 10); WriteLn; (* 0.00000000 *)
This does not seem to be the way it is usually(?) implemented (eg,
StonyBrook). Rather it looks as if the implementation always uses
WriteFloat() format for any number whose absolute value is < 1.0
Have I missed something?
Thanks,
Tom