Bug 170258
Summary: | gawk compl function does not work | ||
---|---|---|---|
Product: | Red Hat Enterprise Linux 4 | Reporter: | Tony McConnell <tony.mcconnell> |
Component: | gawk | Assignee: | Karel Zak <kzak> |
Status: | CLOSED WONTFIX | QA Contact: | Brock Organ <borgan> |
Severity: | medium | Docs Contact: | |
Priority: | medium | ||
Version: | 4.0 | ||
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2005-10-11 08:02:25 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
Tony McConnell
2005-10-10 10:01:28 UTC
Performing a compl(0xFFFFFFFFFFFF0000) actually returns the correct result Yes, it's unpleasant bug. Thanks from report. 'info' page of gawk (on RHEL 4) gives the following program: function bits2str(bits, data, mask) { if (bits == 0) return "0" mask = 1 for (; bits != 0; bits = rshift(bits, 1)) data = (and(bits, mask) ? "1" : "0") data while ((length(data) % 8) != 0) data = "0" data return data } BEGIN { printf "123 = %s\n", bits2str(123) printf "0123 = %s\n", bits2str(0123) printf "0x99 = %s\n", bits2str(0x99) comp = compl(0x99) printf "compl(0x99) = %#x = %s\n", comp, bits2str(comp) shift = lshift(0x99, 2) printf "lshift(0x99, 2) = %#x = %s\n", shift, bits2str(shift) shift = rshift(0x99, 2) printf "rshift(0x99, 2) = %#x = %s\n", shift, bits2str(shift) } and says the output should be : $ gawk -f testbits.awk -| 123 = 01111011 -| 0123 = 01010011 -| 0x99 = 10011001 -| compl(0x99) = 0xffffff66 = 11111111111111111111111101100110 -| lshift(0x99, 2) = 0x264 = 0000001001100100 -| rshift(0x99, 2) = 0x26 = 00100110 On RH9 it is, on RHEL 4.0 its: 123 = 01111011 0123 = 01010011 0x99 = 10011001 compl(0x99) = 0x0 = 00000000 lshift(0x99, 2) = 0x264 = 0000001001100100 rshift(0x99, 2) = 0x26 = 00100110 So info page doesn't expect it to behave as it does. Thanks Possible woraround: xor(0xFFFF0000,lshift(1,32)-1)) It seems that there is not any good solution :-( Cut & past from my discussion with upstream developers: On Mon, Oct 10, 2005 at 07:27:29PM +0200, Karel Zak wrote: > On Mon, 2005-10-10 at 09:29 -0400, Andrew J. Schorr wrote: > > On Mon, Oct 10, 2005 at 02:19:49PM +0200, Karel Zak wrote: > > > $ gawk 'BEGIN {printf("%#x\n", compl(0xFFFF0000)) }' > > > 0x1fffff0000ffff > > > > > > I see same output for 3.1.5, 3.1.4 and 3.1.3. It seems that version > > > 3.1.2 returns correct output (it means 0xffff). > > > > Actually, the code seems to be working correctly. Your code > > From my point of view it's regression between version 3.1.2 and >=3.1.3. > It means the code (or docs) is incorrect :-) Well, the documentation on the bitwise functions says the following: http://www.gnu.org/software/gawk/manual/html_node/Bitwise-Functions.html For all of these functions, first the double-precision floating-point value is converted to the widest C unsigned integer type, then the bitwise operation is performed and then the result is converted back into a C `double'. (If you don't understand this paragraph, don't worry about it.) An older version of the documentation (from 3.1.0) said the following: For all of these functions, first the double-precision floating-point value is converted to a C unsigned long, then the bitwise operation is performed and then the result is converted back into a C double. (If you don't understand this paragraph, don't worry about it.) So there was a clear change of language from "C unsigned long" to "the widest C unsigned integer type". And the code was patched to start using uintmax_t for the calculations instead of u_long. I think this was done for good reasons: there are other situations where the old u_long behavior is not good. The patch seems to have initially come up here: http://sources.redhat.com/ml/bug-gnu-utils/2003-03/msg00251.html I agree the documentation is not terribly clear, and it's perhaps a mistake to encourage people to ignore the paragraph, particularly with respect to the compl() function. I'm not sure what the proper solution is here, but it seems to me that the documentation is OK (not great), and the code works as described in the docs. Perhaps some kind of warning message would be helpful. What do you suggest? I doubt that reverting to the old behavior is an option... Hmm, the "documentation is OK" stretches the definition of "OK" pretty thin ... ;) Much of the time, developers will scan documentation and leap upon an example as a better description of how to use a function - certainly, the example in the 'info' page ought to be corrected to reflect the true behaviour of compl(). I can change the stuff that uses compl() to use the xor(val, lshift(1,32)-1) technique instead, but we ought to push for a more explicit definition of compl() semantics. Most people would expect it to behave like C "~" bitwise negation :P Thank you for your help on this :) |