Aldy Hernandez <al...@redhat.com> writes: > On Tue, Oct 17, 2017 at 6:05 PM, Richard Sandiford > <richard.sandif...@linaro.org> wrote: >> Andrew MacLeod <amacl...@redhat.com> writes: >>> On 10/17/2017 08:18 AM, Richard Sandiford wrote: >>>> Aldy Hernandez <al...@redhat.com> writes: >>>>> Hi folks! >>>>> >>>>> Calling print_hex() on a widest_int with the most significant bit turned >>>>> on can lead to a leading zero being printed (0x0ffff....). This produces >>>>> confusing dumps to say the least, especially when you incorrectly assume >>>>> an integer is NOT signed :). >>>> That's the intended behaviour though. wide_int-based types only use as >>>> many HWIs as they need to store their current value, with any other bits >>>> in the value being a sign extension of the top bit. So if the most >>>> significant HWI in a widest_int is zero, that HWI is there to say that >>>> the previous HWI should be zero- rather than sign-extended. >>>> >>>> So: >>>> >>>> 0x0ffffffff -> (1 << 32) - 1 to infinite precision >>>> (i.e. a positive value) >>>> 0xffffffff -> -1 >>>> >>>> Thanks, >>>> Richard >>> >>> I for one find this very confusing. If I have a 128 bit value, I don't >>> expect to see a 132 bits. And there are enough 0's its not obvious when >>> I look. >> >> But Aldy was talking about widest_int, which is wider than 128 bits. >> It's an approximation of infinite precision. > > IMO, we should document this leading zero in print_hex, as it's not > inherently obvious. > > But yes, I was talking about widest_int. I should explain what I am > trying to accomplish, since perhaps there is a better way. > > I am printing a a wide_int (bounds[i] below), but I really don't want > to print the sign extension nonsense, since it's a detail of the > underlying representation.
Ah! OK. Yeah, I agree it doesn't make sense to print sign-extension bits above the precision. I think it'd work if print_hex used extract_uhwi insteead of elt, which would also remove the need to handle "negative" numbers specially. I'll try that tomorrow. > Currently I'm doing this to chop off the unnecessary bits: > > /* Wide ints may be sign extended to the full extent of the > underlying HWI storage, even if the precision we care about > is smaller. Chop off the excess bits for prettier output. */ > signop sign = TYPE_UNSIGNED (type) ? UNSIGNED : SIGNED; > widest_int val = widest_int::from (bounds[i], sign); > val &= wi::mask<widest_int> (bounds[i].get_precision (), false); > > if (val > 0xffff) > print_hex (val, pp_buffer (buffer)->digit_buffer); > else > print_dec (val, pp_buffer (buffer)->digit_buffer, sign); > > Since I am calling print_hex() on the widest_int, I get the leading 0. > > Do you recommend another way of accomplishing this? Is it just print_hex that's the problem? Does print_dec handle big negative numbers properly? I agree we should make it so that wide-int-print.cc does the right thing for this without the need to switch to widest_int. Thanks, Richard > >> >> wide_int is the type to use if you want an N-bit number (for some N). >> >>> I don't think a leading 0 should be printed if "precision" bits have >>> already been printed. >> >> Does 0 get printed in that case though? Aldy's patch skips an upper > > No. > > Thanks for your input Richard. > Aldy