Project

General

Profile

This project is closed and read-only.

Actions

Feature #660

closed

数字を3桁ずつコンマで区切るsprintf書式指定

Feature #660: 数字を3桁ずつコンマで区切るsprintf書式指定

Added by rubikitch (rubikitch .) almost 18 years ago. Updated over 15 years ago.


Description

=begin
http://d.hatena.ne.jp/rubikitch/20081016/1224165602

1,000,000のように数字を3桁ずつ区切るsprintf書式指定が欲しいです。

「%#d」が使用されていないのでこれに割り当てるのが妥当だと思います。
区切り文字は国によって異なるらしいのでlocaleに決めさせるのがよいでしょう。
ついでに区切り文字指定で「%,」やら「%_」等も用意するといいと思います。

これも整形なのでsprintf/formatは名前も合致しています。

互換性を崩さない要望なのでRuby 1.8に登録してみました。
=end

Updated by xibbar (Takeyuki FUJIOKA) almost 18 years ago Actions #1

=begin
%#dよりも、%,dとか%_dなどのほうが直感的だと思います。
localeに自動的に決めさせるよりも使う人に決めていただいた方がいいと思います。
どうでしょう?
=end

Updated by rubikitch (rubikitch .) almost 18 years ago Actions #2

=begin
最初の段階では「%,d」や「%_d」で自分で決めるのがいいですね。
「localeに決めさせる」という要望が出るかどうかも定かではないので。

=end

Updated by shyouhei (Shyouhei Urabe) almost 18 years ago Actions #3

=begin
卜部です。

rubikitch . さんは書きました:

1,000,000のように数字を3桁ずつ区切るsprintf書式指定が欲しいです。

「%#d」が使用されていないのでこれに割り当てるのが妥当だと思います。

そのようなものがあること自体はいいのではないかと思いますが、POSIXではそ
の用途に'を割り当てているようです。
http://www.opengroup.org/onlinepubs/000095399/functions/printf.html

=end

Updated by matz (Yukihiro Matsumoto) almost 18 years ago Actions #4

=begin
まつもと ゆきひろです

In message "Re: [ruby-dev:36789] [Bug #660] 数字を3桁ずつコンマで区切るsprintf書式指定"
on Sun, 19 Oct 2008 09:46:00 +0900, "rubikitch ." writes:

|http://d.hatena.ne.jp/rubikitch/20081016/1224165602
|
|1,000,000のように数字を3桁ずつ区切るsprintf書式指定が欲しいです。

|「%#d」が使用されていないのでこれに割り当てるのが妥当だと思います。
|区切り文字は国によって異なるらしいのでlocaleに決めさせるのがよいでしょう。
|ついでに区切り文字指定で「%,」やら「%_」等も用意するといいと思います。

POSIXでは「%'d」を使うという話がありますし、もう少し具体化し
てほしいです。少なくとも、私にはここで示された提案が「妥当」
とは簡単に判断できません。たとえば、他の実装との互換性とか。

また、printfの実装では他の部分ではかたくなにlocale使用を拒否
しているのに、ここだけlocaleに従うというのも変な話です。

=end

Updated by nobu (Nobuyoshi Nakada) almost 18 years ago Actions #5

=begin
なかだです。

At Tue, 21 Oct 2008 09:14:12 +0900,
Fujioka wrote in [ruby-dev:36816]:

現状としては
%'d と %,d があればいいのではないでしょうか?
%_d は必要なのかどうなのかよくわかりません。

むしろRuby的には、_区切りにする%_dのみとか。

--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦

=end

Updated by mame (Yusuke Endoh) almost 18 years ago Actions #6

=begin
遠藤です。

2008/10/19 9:46 rubikitch . :

Bug #660: 数字を3桁ずつコンマで区切るsprintf書式指定
http://redmine.ruby-lang.org/issues/show/660

起票者: rubikitch .
ステータス: Open, 優先度: Normal

残念ながらフリーズ後ですので、1.9.1 に入ることはあり得ないです。
1.9.2 以降なら機能追加は OK なんでしたっけ。yugui さんの公式見解が欲しい
です。

以下は提案に対する意見です。

1,000,000のように数字を3桁ずつ区切るsprintf書式指定が欲しいです。

%x は 4 桁や 8 桁で区切れると便利だと思います。
また、小学校で「日本では 4 桁区切りだ」と習ってしまった記憶があります。
というわけで、区切り幅は指定できた方がいいと思います。%4_x とか?

区切り文字は国によって異なるらしいのでlocaleに決めさせるのがよいでしょう。

特定環境でしか発現しないバグになりそうで、抵抗があります。
あと、Ruby の数値リテラルは _ 区切りなので、デフォルトは _ の方が
いいのでは、とちょっと思いました。

--
Yusuke ENDOH

=end

Updated by matz (Yukihiro Matsumoto) almost 18 years ago Actions #7

=begin
まつもと ゆきひろです

In message "Re: [ruby-dev:36816] Re: [Bug #660] 数字を3桁ずつコンマで区切るsprintf書式指定"
on Tue, 21 Oct 2008 09:14:12 +0900, Fujioka writes:

|> また、printfの実装では他の部分ではかたくなにlocale使用を拒否
|> しているのに、ここだけlocaleに従うというのも変な話です。
|>
|rubikitchさんも
|
|最初の段階では「%,d」や「%_d」で自分で決めるのがいいですね。
|「localeに決めさせる」という要望が出るかどうかも定かではないので。
|
|と発言しているので、ロケールの話は置いといて、
|3桁の区切りの話だけでいいのではないかと思います。

それならそれで、

  • 「,」や「_」は他の言語でformatを拡張するために使われてい
    たりしないのか

  • 3桁区切りだけでよいのか、あるいは桁数を指定できるように
    するのか

など、いろいろ考えるべきことはあると思います。まあ、すぐには
入れられないでしょうから、ゆっくり議論すればいいことですが。

=end

Updated by mame (Yusuke Endoh) almost 18 years ago Actions #8

=begin
遠藤です。

2008/10/21 15:09 Yukihiro Matsumoto :

まつもと ゆきひろです

In message "Re: [ruby-dev:36816] Re: [Bug #660] 数字を3桁ずつコンマで区切るsprintf書式指定"
on Tue, 21 Oct 2008 09:14:12 +0900, Fujioka writes:

|> また、printfの実装では他の部分ではかたくなにlocale使用を拒否
|> しているのに、ここだけlocaleに従うというのも変な話です。
|>
|rubikitchさんも
|
|最初の段階では「%,d」や「%_d」で自分で決めるのがいいですね。
|「localeに決めさせる」という要望が出るかどうかも定かではないので。
|
|と発言しているので、ロケールの話は置いといて、
|3桁の区切りの話だけでいいのではないかと思います。

それならそれで、

  • 「,」や「_」は他の言語でformatを拡張するために使われてい
    たりしないのか

  • 3桁区切りだけでよいのか、あるいは桁数を指定できるように
    するのか

など、いろいろ考えるべきことはあると思います。まあ、すぐには
入れられないでしょうから、ゆっくり議論すればいいことですが。

たたき台として、

$ ./ruby -e 'p "%_d" % 1000000'
"1_000_000"

となるようにパッチを書いてみました。が、

$ ./ruby -e 'p "%3_ 12d" % 1000000'
" 1_000_000"
$ ./ruby -e 'p "%3_012d" % 1000000'
"000_001_000_000"

で結果の幅が変わるのがそこはかとなく気持ち悪いですね。
prec の幅指定を優先するとすると、

$ ./ruby -e 'p "%3_012d" % 1000000'
"_001_000_000"

になりそうですが、これも気持ち悪いです。

Index: sprintf.c

--- sprintf.c (revision 19874)
+++ sprintf.c (working copy)
@@ -437,6 +437,8 @@
VALUE nextvalue;
VALUE tmp;
VALUE str;

  • int delimit_length;
  • char delimiter;
    volatile VALUE hash = Qundef;

#define CHECK_FOR_WIDTH(f)
@@ -483,6 +485,8 @@

width = prec = -1;
nextvalue = Qundef;
  • delimit_length = 0;

  • delimiter = '\0';
    retry:
    switch (*p) {
    default:
    @@ -522,6 +526,15 @@
    p++;
    goto retry;

  • case ',': case '_':

  •  if (delimit_length != 0) {
    
  •  rb_raise(rb_eArgError, "delimiter given twice - %c", *p);
    
  •  }
    
  •  delimit_length = 3;
    
  •  delimiter = *p;
    
  •  p++;
    
  •  goto retry;
    
  • case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    n = 0;
    @@ -534,6 +547,15 @@
    p++;
    goto retry;
    }

  •  if (*p == ',' || *p == '_') {
    
  •  if (delimit_length != 0) {
    
  •      rb_raise(rb_eArgError, "delimiter given twice - %d%c", n, *p);
    
  •  }
    
  •  delimit_length = n;
    
  •  delimiter = *p;
    
  •  p++;
    
  •  goto retry;
    
  •  }
     CHECK_FOR_WIDTH(flags);
     width = n;
     flags |= FWIDTH;
    

@@ -705,7 +727,7 @@
char fbuf[32], nbuf[64], *s;
const char *prefix = 0;
int sign = 0, dots = 0;

  •  char sc = 0;
    
  •  char sc = 0, c = 0;
     long v = 0;
     int base, bignum = 0;
     int len, pos;
    

@@ -925,26 +947,40 @@
int plen = strlen(prefix);
PUSH(prefix, plen);
}

  •  CHECK(prec - len);
     if (dots) PUSH("..", 2);
     if (!bignum && v < 0) {
    
  •      char c = sign_bits(base, p);
    
  •      while (len < prec--) {
    
  •  	buf[blen++] = c;
    
  •      }
    
  •      c = sign_bits(base, p);
     }
     else if ((flags & (FMINUS|FPREC)) != FMINUS) {
    
  •      char c;
    
  •      if (!sign && bignum && !RBIGNUM_SIGN(val))
     	c = sign_bits(base, p);
         else
     	c = '0';
    
  •      while (len < prec--) {
    
  •  	buf[blen++] = c;
    
  •  }
    
  •  if (delimit_length == 0) {
    
  •      if (c != 0) FILL(c, prec - len);
    
  •      PUSH(s, len);
    
  •  }
    
  •  else {
    
  •      int i;
    
  •      if (c != 0) {
    
  •  	i = (prec - 1) % delimit_length + 1;
    
  •  	while (prec - len >= i) {
    
  •  	    FILL(c, i);
    
  •  	    PUSH(&delimiter, 1);
    
  •  	    prec -= i;
    
  •  	    i = delimit_length;
    
  •  	}
    
  •  	if (prec - len > 0) FILL(c, prec - len);
         }
    
  •      i = (len - 1) % delimit_length + 1;
    
  •      PUSH(s, i);
    
  •      for (len -= i; len > 0; len -= delimit_length) {
    
  •  	PUSH(&delimiter, 1);
    
  •  	PUSH(&s[i], delimit_length);
    
  •  	i += delimit_length;
    
  •      }
     }
    
  •  PUSH(s, len);
     CHECK(width);
     while (width-- > 0) {
         buf[blen++] = ' ';
    

--
Yusuke ENDOH

=end

Updated by znz (Kazuhiro NISHIYAMA) almost 18 years ago Actions #9

=begin
西山和広です。

At Tue, 21 Oct 2008 23:53:15 +0900,
Yusuke ENDOH wrote:

たたき台として、

$ ./ruby -e 'p "%_d" % 1000000'
"1_000_000"

となるようにパッチを書いてみました。が、

$ ./ruby -e 'p "%3_ 12d" % 1000000'
" 1_000_000"
$ ./ruby -e 'p "%3_012d" % 1000000'
"000_001_000_000"

で結果の幅が変わるのがそこはかとなく気持ち悪いですね。
prec の幅指定を優先するとすると、

$ ./ruby -e 'p "%3_012d" % 1000000'
"_001_000_000"

になりそうですが、これも気持ち悪いです。

Debianの/usr/bin/printfだと以下のようになりました。

% /usr/bin/printf "%'012d\n" 1000000
0001,000,000
%

--
|ZnZ(ゼット エヌ ゼット)
|西山和広(Kazuhiro NISHIYAMA)

=end

Updated by yugui (Yuki Sonoda) almost 18 years ago Actions #10

=begin
Yuguiです。

Yusuke ENDOH さんは書きました:

残念ながらフリーズ後ですので、1.9.1 に入ることはあり得ないです。
1.9.2 以降なら機能追加は OK なんでしたっけ。yugui さんの公式見解が欲しい
です。

OKです。
機能としては良いものだと思います。仕様が固まって合意がとれればコミットし
てくださって結構ですが、1.9.1のブランチが分岐した以降にしてください。
25日か26日あたりにブランチを切る予定です。

--
Yugui
http://yugui.jp
私は私をDumpする

=end

Updated by shyouhei (Shyouhei Urabe) over 17 years ago Actions #11

  • Status changed from Open to Rejected
  • Assignee set to matz (Yukihiro Matsumoto)

=begin

=end

Actions

Also available in: PDF Atom