I took another little look at the behaviour here.

My basic assumption is that, for any Real32.real r,

Real32.== (PackReal32Big.fromBytes (PackReal32Big.toBytes r), r)

should hold. (and the same for Little obviously)

With the current repo code, it's possible to construct values for which this is 
not true - if you apply fromBytes to something with the lowest-order bit set, 
and then take Real32.nextAfter, you get a value that "should" have one more bit 
set than is preserved through this transformation. The value 1.000060916 is an 
example:

> val r : Real32.real = 1.000060916;
val r = 1.000060916: Real32.real
> PackReal32Big.toBytes r;
val it = fromList[0wx1F, 0wxC0, 0wx0, 0wxFF]: Word8Vector.vector
> PackReal32Big.fromBytes (PackReal32Big.toBytes r);
val it = 1.000060797: PackReal32Big.real
> Real32.== (PackReal32Big.fromBytes (PackReal32Big.toBytes r), r);
val it = false: bool

Note the result has been rounded down by 2^-23, which makes sense since the 
IEEE 754 fraction part is 23 bits. 

I experimentally went into PackReal32Tagged, subtracted 1 from all the shift 
constants (the 56, 48, 40, 32), and rebuilt. With this change:

> val r : Real32.real = 1.000060916;
val r = 1.000060916: Real32.real
> PackReal32Big.toBytes r;
val it = fromList[0wx3F, 0wx80, 0wx1, 0wxFF]: Word8Vector.vector
> Real32.== (PackReal32Big.fromBytes (PackReal32Big.toBytes r), r);
val it = true: bool

Also now

> PackReal32Big.toBytes 1.0;
val it = fromList[0wx3F, 0wx80, 0wx0, 0wx0]: Word8Vector.vector

which is the expected result I mentioned in the previous email.

I'm imagining all this has something to do with the tag bit, but I don't really 
know.


Chris

On Sun, 7 Feb 2021, at 18:06, Chris Cannam wrote:
> Oh, thank you!
> 
> I had thought that the difference between x87 and SSE, and the 
> different internal precisions, mattered only for intermediate register 
> values during calculation - and that when a 32-bit float was "at rest", 
> i.e. being stored in 32 bits, it would always have IEEE 754 
> representation (as described e.g. at 
> https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_single-precision_binary_floating-point_format:_binary32)
> 
> Is this not right? Do I have the wrong mental model here?
> 
> The current behaviour does indeed seem a bit off (Poly/ML rev 
> 62a56474f0, 64-bit Linux).
> 
> If I take, say, 1.0 and convert it to bytes big-endian, I think I expect to 
> see
> 
> sign bit: 0
> exponent (8 bits): 127 (exponent is 0, stored unsigned with an offset of 127)
> fraction (23 bits): 0 (as the 1 in 1.0 x 2^0 is implicit)
> 
> so 0111 1111 1000 0000 0000 0000 0000 0000 or 3F 80 00 00 
> 
> and that's what PackReal32Big.toBytes 1.0 returns in MLton. In Poly/ML 
> I'm getting this
> 
> > PackReal32Big.toBytes 1.0;
> val it = fromList[0wx1F, 0wxC0, 0wx0, 0wx0]: Word8Vector.vector
> 
> 1F C0 00 00 is the same bit pattern as 3F 80 00 00, but shifted right 
> by one bit, and no longer a normal IEEE 754 number I think. Is it 
> possible there's an off-by-one error in the bit lookup, or is this all 
> a symptom of my having the wrong idea about what's going on?
> 
> Thanks,
> 
> 
> Chris
> 
> On Sat, 6 Feb 2021, at 16:24, David Matthews wrote:
> > I've added this to master.  It seemed like a good idea although it was a 
> > bit more complicated than PackReal because Real32.real values are 
> > "boxed" in 32-bit Poly/ML but tagged in 64-bit.
> > 
> > I'm not exactly clear how useful PackRealN operations are for general 
> > data interchange.  Currently they just store and load the bytes that 
> > make up the number but how those are interpreted will depend on the 
> > platform.  For example it seems that the X87 format used on X86/32 is 
> > different from the SSE format used on X86/64.
> > 
> > David
> > 
> > On 02/02/2021 09:25, Chris Cannam wrote:
> > > Hello! I find I could do with the PackReal32{Big,Little} structures, 
> > > 32-bit floats being often more amenable to serialisation and used in some 
> > > storage formats.
> > > 
> > > Would there be any appetite for adding these?
> > > 
> > > Thanks,
> > > 
> > > 
> > > Chris
> > > _______________________________________________
> > > polyml mailing list
> > > polyml@inf.ed.ac.uk
> > > http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
> > > 
> >
_______________________________________________
polyml mailing list
polyml@inf.ed.ac.uk
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

Reply via email to