Summary: | double subnormals are not well printed on printing with printf (and friends) | ||||||||
---|---|---|---|---|---|---|---|---|---|
Product: | Base System | Reporter: | Luis Colorado <luiscoloradourcola> | ||||||
Component: | misc | Assignee: | freebsd-bugs (Nobody) <bugs> | ||||||
Status: | New --- | ||||||||
Severity: | Affects Many People | CC: | marklmi26-fbsd, pstef | ||||||
Priority: | --- | ||||||||
Version: | 11.0-STABLE | ||||||||
Hardware: | Any | ||||||||
OS: | Any | ||||||||
Attachments: |
|
Created attachment 188840 [details]
program to display correct values (except for rounding errors)
This is a simple program I wrote to get the expected values (compared also with glibc output, they differ in the two less significant digits at position 17)
I'm getting the expected output, but this is on amd64 and stable/13. Actually, below is what I'm getting on stable/13. amd64: $ ./test | tail 0x0000000000000200 2.5296161067071825d-321 0x0000000000000100 1.2648080533535913d-321 0x0000000000000080 6.3240402667679563d-322 0x0000000000000040 3.1620201333839781d-322 0x0000000000000020 1.5810100666919891d-322 0x0000000000000010 7.9050503334599451d-323 0x0000000000000008 3.9525251667299726d-323 0x0000000000000004 1.9762625833649863d-323 0x0000000000000002 9.8813129168249318d-324 0x0000000000000001 4.9406564584124659d-324 arm64: % ./test | tail 0x0000000000000200 2.5296161067071825d-321 0x0000000000000100 1.2648080533535913d-321 0x0000000000000080 6.3240402667679563d-322 0x0000000000000040 3.1620201333839781d-322 0x0000000000000020 1.5810100666919891d-322 0x0000000000000010 7.9050503334599451d-323 0x0000000000000008 3.9525251667299726d-323 0x0000000000000004 1.9762625833649863d-323 0x0000000000000002 9.8813129168249318d-324 0x0000000000000001 4.9406564584124659d-324 So better than 0x0000000000000200 1.1125369292537272e-308 0x0000000000000100 1.1125369292536639e-308 0x0000000000000080 1.1125369292536323e-308 0x0000000000000040 1.1125369292536165e-308 0x0000000000000020 1.1125369292536086e-308 0x0000000000000010 1.1125369292536046e-308 0x0000000000000008 1.1125369292536027e-308 0x0000000000000004 1.1125369292536017e-308 0x0000000000000002 1.1125369292536012e-308 0x0000000000000001 1.1125369292536009e-308 but not exactly 0x0000000000000200 2.5296161067071823e-321 0x0000000000000100 1.2648080533535912e-321 0x0000000000000080 6.3240402667679558e-322 0x0000000000000040 3.1620201333839779e-322 0x0000000000000020 1.5810100666919889e-322 0x0000000000000010 7.9050503334599447e-323 0x0000000000000008 3.9525251667299724e-323 0x0000000000000004 1.9762625833649862e-323 0x0000000000000002 9.8813129168249309e-324 0x0000000000000001 4.9406564584124654e-324 Hi Piotr, Yeah, on intel it works.... I was working in a raspberry pi, model 2+, which is where I addressed the bug (more than four years ago!!!!) The expected behaviour was produced by running the program in intel architecture. I think the bug is related with the raspberry processor not supporting subnormals and the software accepting them as they are in intel, But I have no time to dig on this problem. My apologies. (In reply to Luis Colorado from comment #4) Please note that "arm64" in comment #3 is non-intel (although not RPi as in your case but the first pinebook). arm64 is not the architecture I'm talking about, as the rpi 2+ is 32 bit arch and not arm64. Anyway I suspect the problem will be also there, as both architectures will probably share the floating point unit. But you tell me that you are getting correct results in AMD64 (which is the intel 64 bit architecture, and not ARM at all) Sorry, but I don't get the point here. It is four years this bug is rolling over there. My impression is that arm architectures don't support 64bit floating point subnormals at all, and that's the reason the software is failing, as it doesn't cut the thing and makes them as 0 (which obviously the hardware is not doing) IMHO, the floating point library should check if the processor supports subnormals or not, which is something required by the ieee standard, and round the values to 0.0, instead. That is easy to check, as the exponent field is all zeros for subnormals. (In reply to Luis Colorado from comment #4) RPi2 v1.0 and v1.1 were Cortex-A7 (armv7) based. RPi2 v1.2 was Cortext-A53 (aarch64) based. (I sometimes have access to a v1.1 and/or v v1.2, but not currently.) RPi2 v1.2's can use either armv7 FreeBSD or aarch64 FreeBSD. So things can be confusing/ambiguus when RPi2 is used as a point of reference. SO it is better to specify which FreeBSD is in use, such as via: # uname -apKU FreeBSD OPiP2E_RPi2v11 14.0-CURRENT FreeBSD 14.0-CURRENT #10 main-n249978-032448cd2c52-dirty: Sat Oct 9 02:11:35 PDT 2021 root@CA72_16Gp_ZFS:/usr/obj/BUILDs/main-CA7-nodbg-clang/usr/main-src/arm.armv7/sys/GENERIC-NODBG-CA7 arm armv7 1400036 1400036 (Not an RPi* example.) (In reply to Luis Colorado from comment #0) On/for armv7, for compiling/linking the test program via any of: system clang (so: 12) clang13 (from devel/llvm13) gcc11 (from lang/gcc11) and then running the test, all produce the e-308 "from here on, all are incorrect" type of results. Side note: For reference, # gcc11 -O2 -pedantic -Wall subnormal_test.c subnormal_test.c: In function 'main': subnormal_test.c:10:49: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 10 | printf("0x%016llx %-0.17lg\n", *(unsigned long long *)&val, val); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ subnormal_test.c:10:24: warning: '0' flag ignored with '-' flag in gnu_printf format [-Wformat=] 10 | printf("0x%016llx %-0.17lg\n", *(unsigned long long *)&val, val); | ^~~~~~~~~~~~~~~~~~~~~~ and: # clang13 -O2 -pedantic -Wall subnormal_test.c subnormal_test.c:10:23: warning: flag '0' is ignored when flag '-' is present [-Wformat] printf("0x%016llx %-0.17lg\n", *(unsigned long long *)&val, val); ~~^~~~~~ (In reply to Mark Millard from comment #8) For gcc11 I forgot : -Wl,-rpath=/usr/local/lib/gcc11 so that: # ldd a.out a.out: libgcc_s.so.1 => /usr/local/lib/gcc11/libgcc_s.so.1 (0x2008d000) libc.so.7 => /lib/libc.so.7 (0x200bc000) (Not that it makes any difference in the bad -e308's that result.) |
Created attachment 188809 [details] program run to get the expected and obtained output. subnormals are not recognized as such in doubles (they are in float) and long double. I cannot do a make update to get the last version of the libc, as I'm in a Tier 2 (raspberry pi) architecture. I'm running 11.0-STABLE. I get this output for a program that consists in dividing by two a normalized number until I get zero: (only the four first numbers are normalized) (wrong output, expected follows) 0x0040000000000000 1.7800590868057611e-307 (ok, but normalized) 0x0030000000000000 8.9002954340288055e-308 (ok, but normalized) 0x0020000000000000 4.4501477170144028e-308 (ok, but normalized) 0x0010000000000000 2.2250738585072014e-308 (ok, but normalized) 0x0008000000000000 1.668805393880401e-308 (from here on, all are incorrect) 0x0004000000000000 1.3906711615670009e-308 0x0002000000000000 1.2516040454103008e-308 0x0001000000000000 1.1820704873319507e-308 0x0000800000000000 1.1473037082927757e-308 0x0000400000000000 1.1299203187731882e-308 0x0000200000000000 1.1212286240133944e-308 0x0000100000000000 1.1168827766334976e-308 0x0000080000000000 1.1147098529435491e-308 0x0000040000000000 1.1136233910985749e-308 0x0000020000000000 1.1130801601760878e-308 0x0000010000000000 1.1128085447148442e-308 0x0000008000000000 1.1126727369842225e-308 0x0000004000000000 1.1126048331189116e-308 0x0000002000000000 1.1125708811862561e-308 0x0000001000000000 1.1125539052199284e-308 0x0000000800000000 1.1125454172367646e-308 0x0000000400000000 1.1125411732451826e-308 0x0000000200000000 1.1125390512493917e-308 0x0000000100000000 1.1125379902514962e-308 0x0000000080000000 1.1125374597525484e-308 0x0000000040000000 1.1125371945030746e-308 0x0000000020000000 1.1125370618783376e-308 0x0000000010000000 1.1125369955659692e-308 0x0000000008000000 1.1125369624097849e-308 0x0000000004000000 1.1125369458316928e-308 0x0000000002000000 1.1125369375426468e-308 0x0000000001000000 1.1125369333981237e-308 0x0000000000800000 1.1125369313258622e-308 0x0000000000400000 1.1125369302897314e-308 0x0000000000200000 1.1125369297716661e-308 0x0000000000100000 1.1125369295126334e-308 0x0000000000080000 1.112536929383117e-308 0x0000000000040000 1.1125369293183589e-308 0x0000000000020000 1.1125369292859798e-308 0x0000000000010000 1.1125369292697902e-308 0x0000000000008000 1.1125369292616955e-308 0x0000000000004000 1.1125369292576481e-308 0x0000000000002000 1.1125369292556244e-308 0x0000000000001000 1.1125369292546125e-308 0x0000000000000800 1.1125369292541066e-308 0x0000000000000400 1.1125369292538537e-308 0x0000000000000200 1.1125369292537272e-308 0x0000000000000100 1.1125369292536639e-308 0x0000000000000080 1.1125369292536323e-308 0x0000000000000040 1.1125369292536165e-308 0x0000000000000020 1.1125369292536086e-308 0x0000000000000010 1.1125369292536046e-308 0x0000000000000008 1.1125369292536027e-308 0x0000000000000004 1.1125369292536017e-308 0x0000000000000002 1.1125369292536012e-308 0x0000000000000001 1.1125369292536009e-308 while expected behaviour is: 0x0040000000000000 1.7800590868057611e-307 0x0030000000000000 8.9002954340288055e-308 0x0020000000000000 4.4501477170144028e-308 0x0010000000000000 2.2250738585072014e-308 0x0008000000000000 1.1125369292536007e-308 0x0004000000000000 5.5626846462680035e-309 0x0002000000000000 2.7813423231340017e-309 0x0001000000000000 1.3906711615670009e-309 0x0000800000000000 6.9533558078350043e-310 0x0000400000000000 3.4766779039175022e-310 0x0000200000000000 1.7383389519587511e-310 0x0000100000000000 8.6916947597937554e-311 0x0000080000000000 4.3458473798968777e-311 0x0000040000000000 2.1729236899484389e-311 0x0000020000000000 1.0864618449742194e-311 0x0000010000000000 5.4323092248710971e-312 0x0000008000000000 2.7161546124355486e-312 0x0000004000000000 1.3580773062177743e-312 0x0000002000000000 6.7903865310888714e-313 0x0000001000000000 3.3951932655444357e-313 0x0000000800000000 1.6975966327722179e-313 0x0000000400000000 8.4879831638610893e-314 0x0000000200000000 4.2439915819305446e-314 0x0000000100000000 2.1219957909652723e-314 0x0000000080000000 1.0609978954826362e-314 0x0000000040000000 5.3049894774131808e-315 0x0000000020000000 2.6524947387065904e-315 0x0000000010000000 1.3262473693532952e-315 0x0000000008000000 6.631236846766476e-316 0x0000000004000000 3.315618423383238e-316 0x0000000002000000 1.657809211691619e-316 0x0000000001000000 8.289046058458095e-317 0x0000000000800000 4.1445230292290475e-317 0x0000000000400000 2.0722615146145237e-317 0x0000000000200000 1.0361307573072619e-317 0x0000000000100000 5.1806537865363094e-318 0x0000000000080000 2.5903268932681547e-318 0x0000000000040000 1.2951634466340773e-318 0x0000000000020000 6.4758172331703867e-319 0x0000000000010000 3.2379086165851934e-319 0x0000000000008000 1.6189543082925967e-319 0x0000000000004000 8.0947715414629834e-320 0x0000000000002000 4.0473857707314917e-320 0x0000000000001000 2.0236928853657458e-320 0x0000000000000800 1.0118464426828729e-320 0x0000000000000400 5.0592322134143646e-321 0x0000000000000200 2.5296161067071823e-321 0x0000000000000100 1.2648080533535912e-321 0x0000000000000080 6.3240402667679558e-322 0x0000000000000040 3.1620201333839779e-322 0x0000000000000020 1.5810100666919889e-322 0x0000000000000010 7.9050503334599447e-323 0x0000000000000008 3.9525251667299724e-323 0x0000000000000004 1.9762625833649862e-323 0x0000000000000002 9.8813129168249309e-324 0x0000000000000001 4.9406564584124654e-324