Size of variables in awk

Dan Nelson dnelson at allantgroup.com
Wed Mar 3 13:07:36 PST 2004


In the last episode (Mar 04), Wayne Sierke said:
> On Thu, 2004-03-04 at 02:48, Dan Nelson wrote:
> > In the last episode (Mar 03), Wayne Sierke said:
> > > I'm using the printf function in awk but something ain't right:
> > > 
> > > # jot 4 30 | awk '{ printf("%u\n", 2^$1-1) }'
> > > 2147483648
> > > 
> > > # jot 4 30 | awk '{ printf("%lu\n", 2^$1-1) }'
> > > 2147483648
> > > 
> > > # jot 4 30 | awk '{ printf("%llu\n", 2^$1-1) }'
> > > 35186519572480
> > 
> > I see nothing wrong here.  %u is an unsigned int, and on x86 systems,
> > an int is 32 bits.  %llu is a long long unsigned int, and they are 64
> > bits.  Since there is no way for C to print a number larger than 64
> > bits, you won't be able to use the numeric specifiers to print large
> > numbers.  You can use %s though.  See
> > /usr/src/contrib/one-true-awk/run.c, the format() function.
> 
> When you say "they are 64 bits" you're referring to a long
> (signed/unsigned) int (not long long unsigned int)?
> 
> In which case aren't there two problems with the results shown?
> 
> 1 - %u should print values up to 2^32-1
> 
> 2 - %lu should print values up to 2^64-1
> 
> whereas they're both hitting a limit at 2^31.

It's definitely weird.  See run.c, line 865:

        case 'o': case 'x': case 'X': case 'u':
            flag = *(s-1) == 'l' ? 'd' : 'u';
            break;

and line 897:

        case 'd':   sprintf(p, fmt, (long) getfval(x)); break;
        case 'u':   sprintf(p, fmt, (int) getfval(x)); break;

in which case I have no idea how the %llu output is working at all :)

-- 
	Dan Nelson
	dnelson at allantgroup.com


More information about the freebsd-questions mailing list