Re: 80-bit subnormals printed incorrectly on Debian 11 M68K
Hello Nelson,
On 7/21/21 7:45 AM, Nelson H. F. Beebe wrote:
> I run a large farm of physical and virtual machines that we use for
> software testing. We have multiple versions of most of the major
> operating systems, covering the major CPU families of the past 30
> years, including M68K.
>
> In testing some numerical software on Debian 11 on M68k (emulated by
> QEMU 4.2.1), I discovered that 80-bit subnormals are printed
> incorrectly: they are exactly HALF their correct values.
>
> A test program is provided below, and a snippet of its identical and
> correct output on x86_64 and IA-64 (Itanium) physical hardware looks
> like this around the transition from tiny normal numbers to subnormal
> numbers:
>
> k = -16380 x = 0x8.0000000000000000p-16383 = 1.344841257244837403e-4931 = 0x0003_80000000_00000000
> k = -16381 x = 0x8.0000000000000000p-16384 = 6.724206286224187013e-4932 = 0x0002_80000000_00000000
> k = -16382 x = 0x8.0000000000000000p-16385 = 3.362103143112093506e-4932 = 0x0001_80000000_00000000
>
> ---------- begin subnormals ----------
>
> k = -16383 x = 0x4.0000000000000000p-16385 = 1.681051571556046753e-4932 = 0x0000_40000000_00000000
> k = -16384 x = 0x2.0000000000000000p-16385 = 8.405257857780233766e-4933 = 0x0000_20000000_00000000
> k = -16385 x = 0x1.0000000000000000p-16385 = 4.202628928890116883e-4933 = 0x0000_10000000_00000000
>
> Here is the output from Debian 11 on M68k (identical with both gcc-9
> and gcc-10):
>
> k = -16380 x = 0x8.0000000000000000p-16383 = 1.344841257244837403e-4931 = 0x0003_80000000_00000000
> k = -16381 x = 0x8.0000000000000000p-16384 = 6.724206286224187013e-4932 = 0x0002_80000000_00000000
> k = -16382 x = 0x8.0000000000000000p-16385 = 3.362103143112093506e-4932 = 0x0001_80000000_00000000
>
> ---------- begin subnormals ----------
>
> k = -16383 x = 0x4.0000000000000000p-16386 = 8.405257857780233766e-4933 = 0x0000_40000000_00000000
> k = -16384 x = 0x2.0000000000000000p-16386 = 4.202628928890116883e-4933 = 0x0000_20000000_00000000
> k = -16385 x = 0x1.0000000000000000p-16386 = 2.101314464445058441e-4933 = 0x0000_10000000_00000000
>
Here's the output of your program from a Mac IIci running Debian SID
(using gcc version 9.2.1):
-----
$ cat /proc/cpuinfo
CPU: 68030
MMU: 68030
FPU: 68882
Clocking: 23.1MHz
BogoMips: 5.78
Calibration: 28928 loops
$ cc bug-float80.c
$ ./a.out
Addressing is big-endian
sizeof(long double) = 12
LDBL_MANT_DIG = 64
LDBL_MIN_EXP = -16382
LDBL_MIN = 0x8.0000000000000000p-16386 = 1.681051571556046753e-4932
k = -16381 x = 0xd.eadbeefcafefeed0p-16385 = 5.848974526544159967e-4932
= 0x0001_deadbeef_cafefeed
k = -16381 x = 0xd.eadbeefcafefeed0p-16385 = 5.848974526544159967e-4932
= 0x0001_deadbeef_cafefeed
k = -16376 x = 0x8.0000000000000000p-16379 = 2.151746011591739844e-4930
= 0x0007_80000000_00000000
k = -16377 x = 0x8.0000000000000000p-16380 = 1.075873005795869922e-4930
= 0x0006_80000000_00000000
k = -16378 x = 0x8.0000000000000000p-16381 = 5.379365028979349610e-4931
= 0x0005_80000000_00000000
k = -16379 x = 0x8.0000000000000000p-16382 = 2.689682514489674805e-4931
= 0x0004_80000000_00000000
k = -16380 x = 0x8.0000000000000000p-16383 = 1.344841257244837403e-4931
= 0x0003_80000000_00000000
k = -16381 x = 0x8.0000000000000000p-16384 = 6.724206286224187013e-4932
= 0x0002_80000000_00000000
k = -16382 x = 0x8.0000000000000000p-16385 = 3.362103143112093506e-4932
= 0x0001_80000000_00000000
---------- begin subnormals ----------
k = -16383 x = 0x8.0000000000000000p-16386 = 1.681051571556046753e-4932
= 0x0000_80000000_00000000
k = -16384 x = 0x4.0000000000000000p-16386 = 8.405257857780233766e-4933
= 0x0000_40000000_00000000
k = -16385 x = 0x2.0000000000000000p-16386 = 4.202628928890116883e-4933
= 0x0000_20000000_00000000
k = -16386 x = 0x1.0000000000000000p-16386 = 2.101314464445058441e-4933
= 0x0000_10000000_00000000
k = -16387 x = 0x0.8000000000000000p-16386 = 1.050657232222529221e-4933
= 0x0000_08000000_00000000
k = -16388 x = 0x0.4000000000000000p-16386 = 5.253286161112646104e-4934
= 0x0000_04000000_00000000
k = -16389 x = 0x0.2000000000000000p-16386 = 2.626643080556323052e-4934
= 0x0000_02000000_00000000
-----
> In the output, k is the power of 2. The M68K normals are correct, but
> the subnormals are half their correct size in both hexadecimal and
> decimal. The storage values shown in hex on the right prove that the
> hardware, and QEMU, are doing the right thing, so it is definitely not
> a QEMU bug.
>
> The cause MIGHT be the incorrect value in <float.h> of LDBL_MIN_EXP:
> the M68K system has -16382, whereas test output from every other
> system in our farm that supports an 80-bit IEEE 754 format has -16381.
>
> For another possibly independent check, I tried to install clang on
> M68K: clang is listed in the Debian 11 package repertoire, but it
> fails to install because of a missing dependency.
>
> It is unclear to me what the appropriate bug reporting address is for
> this problem: the wrong output is produced by the printf() family in
> libc, but the <float.h> file is provided by the compiler. Both need
> fixing.
>
> A local patch to <float.h> won't fix the problem, because the value of
> the macro LDBL_MIN_EXP has already been compiled and frozen into code
> in libc.
>
> Perhaps a seasoned debian-68k list member might be kind enough to
> suggest an appropriate bug-reporting address.
>
> At present, I have no other operating system than Debian 11 on M68K.
> Web searches indicate that OpenBSD 5.1 ran on that CPU, but its
> package archives have been been deleted. NetBSD 9.2 has an ISO image
> for M68K, but I have not yet successfully created a VM for it.
> Suggestions for other O/Ses to try are welcome.
NetBSD runs on m68k systems; see http://www.netbsd.org. You could also
try an earlier version of Debian (3.0 or 4.0) on m68k. And you might
want to compare the musl libc to glibc; see
https://wiki.musl-libc.org/functional-differences-from-glibc.html
...
-Stan Johnson
Reply to: