On 26/04/2020 18:41, Segher Boessenkool wrote: > On Sun, Apr 26, 2020 at 10:38:57AM +0200, Iain Buclaw wrote: >> On 25/04/2020 22:50, Segher Boessenkool wrote: >>> On Sat, Apr 25, 2020 at 02:20:19AM +0200, Iain Buclaw via Gcc-patches wrote: >>>> + // Parse DoubleDoubles as a pair of doubles. >>>> + // The layout of the type is: >>>> + // >>>> + // [1| 7 | 56 ][ 8 | 56 ] >>>> + // [S| Exp | Fraction (hi) ][ Unused | Fraction (low) ] >>>> + // >>>> + // We can get the least significant bits by subtracting the >>>> IEEE >>>> + // double precision portion from the real value. >>> >>> That's not correct. There is no "Unused" field, and the lower fraction >>> is not always an immediate extension of the higher fraction. >>> >>> (It's not 1,7,56 -- it is 1,11,52). >> >> Thanks, I did a quick look-up of where the original might have came >> from, and I've found another extended floating point format of IBM. >> I'll send the correction upstream. >> >>> A "double double" is really a pair of double precision numbers, both >>> with sign and exponent fields. If the first number has maximum >>> exponent (so, it is infinity or a NaN), the second number is not >>> significant; otherwise, the sum of the two numbers (taken as exact >>> numbers, no rounding, no truncation, etc.) is the represented number. >>> The first number should be that, rounded to double precision. >>> >>> So the second double does "add fraction bits" somewhat like this, but >>> there is an implicit leading 1, for normal numbers, and there can be a >>> gap between the two halves, too (like in 0x1p0 + 0x1p-100). >> >> The job of this routine is to pry out the byte representation of real >> (long double) values at compile-time for hashing-related purposes. >> >> As zero, infinity and NaN are already handled, unless a mismatch between >> compile and run-time computed hashes is found (I haven't seen any >> unit-tests trigger failures in the testsuite), I don't think that there >> is any immediate problem with the current implementation. >> >> Thanks for the information though. > > All bits are significant to the value, there are no unused bits, for > most values. The sign and exponent of the second number are very much > relevant, in general. > > I didn't look at your actual implementation, just this comment, but it > sounds like your tests miss a lot of cases, if no problems were found? >
All these tests pass. That is, the computed compile-time byte layout (the result of this function) is the same as the layout at run-time. Don't mind that these are all strings, they are all passed to mixin(). /**Test special values*/ testNumberConvert!("-real.infinity"); testNumberConvert!("real.infinity"); testNumberConvert!("-0.0L"); testNumberConvert!("0.0L"); testNumberConvert!("real.nan"); /**Test min and max values values*/ testNumberConvert!("real.min_normal"); testNumberConvert!("real.max"); /**Test common values*/ testNumberConvert!("-0.17L"); testNumberConvert!("3.14L"); /**Test immutable and const*/ testNumberConvert!("cast(const)3.14L"); testNumberConvert!("cast(immutable)3.14L"); /**Test denormalized values*/ testNumberConvert!("real.min_normal/2"); testNumberConvert!("real.min_normal/2UL^^63"); // check subnormal storage edge case for Quadruple testNumberConvert!("real.min_normal/2UL^^56"); testNumberConvert!("real.min_normal/19"); testNumberConvert!("real.min_normal/17"); /**Test imaginary values: convert algorithm is same with real values*/ testNumberConvert!("0.0Li"); /**True random values*/ testNumberConvert!("-0x9.0f7ee55df77618fp-13829L"); testNumberConvert!("0x7.36e6e2640120d28p+8797L"); testNumberConvert!("-0x1.05df6ce4702ccf8p+15835L"); testNumberConvert!("0x9.54bb0d88806f714p-7088L"); /**Big overflow or underflow*/ testNumberConvert!("cast(double)-0x9.0f7ee55df77618fp-13829L"); testNumberConvert!("cast(double)0x7.36e6e2640120d28p+8797L"); testNumberConvert!("cast(double)-0x1.05df6ce4702ccf8p+15835L"); testNumberConvert!("cast(double)0x9.54bb0d88806f714p-7088L"); testNumberConvert!("cast(float)-0x9.0f7ee55df77618fp-13829L"); testNumberConvert!("cast(float)0x7.36e6e2640120d28p+8797L"); Iain.