all of these format specifiers are currently considered valid by Ruby
1.8 and 1.9:
Star precision before star width:
"%.**d" % [5, 10, 1] # => " 00001"
Precision before flags and width:
"%.5+05d" % 5 # => "+00005"
"%.5 5d" % 5 # => " 00005"
Overriding a star width with a numeric one: (star argument still gets
popped)
"%*1s" % [5, 1] # => "1"
Width before flags:
"%5+0d" % 1 # => "+0001"
"%5 0d" % 1 # => " 0001"
Specifying width multiple times:
"%50+30+20+10+5d" % 5 # => " +5"
"%50 30 20 10 5d" % 5 # => " 5"
I think they should be considered invalid instead. That would avoid
confusion in the case of typos.
Kind regards,
Florian Gross
"%.*.*.*.*f" % [-1, -1, -1, 5, 1] # => "1.00000"
"%\0x hello" % [] # => "%x hello"
This can be fixed by moving "case '\0':" before "p--" in sprintf.c.
Same for 1.8.
"%u" % -5 # => "..4294967291"
"%.20u" % -5 # => "..........4294967291"
"%+u" % -5 # => "-5"
big = -(2 ** 80 + 5)
"%u" % big # => "-79226953588444722964369244155"
"%.50u" % big # =>
"....................-79226953588444722964369244155"
"%+u" % big # => "-1208925819614629174706181"
big.to_s # => "-1208925819614629174706181"
I've fixed other sprintf bugs you had posted, with the tests, but:
At Mon, 2 Jul 2007 05:20:31 +0900,
Florian Gross wrote in [ruby-core:11575]:
I'm not sure if this is broken. Can you explain the results
what you expect?
--
Nobu Nakada
I'd expect negative bignums to produce results with at least two dots
(no "-"!) and the real bits for "%u" and "%.20u". I'm OK with "%+u"
producing the same as big.to_s.
That way it would match the behaviour of "%u" and fixnums.
> I'm not sure if this is broken. Can you explain the results
> what you expect?
An interesting example:
% ./ruby -ve '(-0xfffffffe).downto(-0x100000001) {|v| printf "%u\n", v }'
ruby 1.9.0 (2007-07-16 patchlevel 0) [i686-linux]
000000000002
000000000001
-e:1: warning: negative number for %u specifier
..18446744069414584320
-e:1: warning: negative number for %u specifier
..18446744069414584319
% ./ruby -ve '(-0xfffffffffffffffe).downto(-0x10000000000000001) {|v| printf "%u\n", v }'
ruby 1.9.0 (2007-07-16 patchlevel 0) [i686-linux]
-e:1: warning: negative number for %u specifier
..00000000000000000002
-e:1: warning: negative number for %u specifier
..00000000000000000001
0079228162495817593519834398720
0079228162495817593519834398719
% ./ruby -ve '(-0xfffffffffffffffffffffffe).downto(-0x1000000000000000000000001) {|v| printf "%u\n", v }'
ruby 1.9.0 (2007-07-16 patchlevel 0) [i686-linux]
0000000000000000000000000000002
0000000000000000000000000000001
00340282366841710300949110269838224261120
00340282366841710300949110269838224261119
It is difficult to define a semantics for %u with negative values.
Some idea:
1. ArgumentError
2. two dots with ten's complement
3. minus sign with absolute value (same as %d)
--
Tanaka Akira
In message "Re: sprintf: Format specifier tokens aren't checked well enough"
on Mon, 16 Jul 2007 16:20:54 +0900, Tanaka Akira <a...@fsij.org> writes:
|It is difficult to define a semantics for %u with negative values.
|
|Some idea:
|
|1. ArgumentError
|2. two dots with ten's complement
|3. minus sign with absolute value (same as %d)
After thinking while, I'd rather take No.3.
matz.
In message "Re: sprintf: Format specifier tokens aren't checked well enough"
on Mon, 2 Jul 2007 05:20:31 +0900, Florian Gross <flo...@gmail.com> writes:
|Something seems to be broken for %u with negative bignums:
Right.
|"%u" % -5 # => "..4294967291"
Dots do not work well with decimals. Maybe we should either
* prohibit negative number for %u
* or make %u works as an alias to %d (a la Python)
|"%.20u" % -5 # => "..........4294967291"
|"%+u" % -5 # => "-5"
Since %u specifies "unsigned" it should ignore "+" modifier.
|big = -(2 ** 80 + 5)
|"%u" % big # => "-79226953588444722964369244155"
|"%.50u" % big # =>
|"....................-79226953588444722964369244155"
Dots and negative sign should not co-exist. My 1.8.6 gives
".....................79226953588444722964369244155"
which is still wrong though.
matz.
Sorry for not discovering this earlier, but there is a small
regression.
In 1.8:
("%*1$.*2$3$d" % [10, 5, 1]) # => " 00001"
(%d with a positional width, precision and value argument.)
In 1.9 it raises ArgumentError: width given twice.
At Thu, 2 Aug 2007 10:07:35 +0900,
Florian Gross wrote in [ruby-core:11838]:
> Sorry for not discovering this earlier, but there is a small
> regression.
>
> In 1.8:
> ("%*1$.*2$3$d" % [10, 5, 1]) # => " 00001"
>
> (%d with a positional width, precision and value argument.)
>
> In 1.9 it raises ArgumentError: width given twice.
Thank you, fixed now.
--
Nobu Nakada