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