From: "NARUSE, Yui" Date: 2010-03-25T02:12:33+09:00 Subject: [ruby-dev:40747] Re: [Feature #2969] String#to_f が -h.hhh±pd を解釈できるように 成瀬です。 (2010/03/24 23:34), Tadayoshi Funaba wrote: >> to_i がデフォルトで prefix を見ないのは、0377 のような、 >> 0 詰めした数値文字列を、8 進数表記として解釈してしまうのを >> 問題視したからだと思っています。 >> >> 今回の to_f は to_i と異なり、このような意図に反した解釈をしやすい >> パターンが無いので、やはり事情が異なると思います。 > > そうなのかもしれないけど、浮動小数点数にも16進数表記がある、という時点 > でもう基本的条件は同じになったと考えたほうがいいと思います。 String#to_i は 0-prefix での 8 進数誤爆を防ぐために分けたのだと 思っているわけですが、String#to_f は何のために分けるんですか? 必要性があれば分けた方がいいのでしょうが、あるようには思えません。 > しかし、2進や8進も含むものとして打ち出せなかったところが提案がかなり微 > 妙であることを示しているように感じます。こういう例外的な対応を取り入れ > るのはすっきりしません。 先のパッチの対象関数が ruby_strtod である通り、 先の提案は strtod(3) をベースにしています。 よって、そこにない 2 進や 8 進を独自に追加する必要を感じません。 > printf の対になるものは scanf なので、lib/scanf.rb で対応するくらいで十 > 分という気がします。 scanf も hexadecimal-floating-constant に対応してもいいとは思いますが、 そもそもが C99 のリテラルなので、printf にこだわることも無いと思います。 > printf の変更を考えてるなら、それを仕様と実装が用意出来てからでもいいわ > けだし、今すぐ採用する必要はないと思います。 missing/vsnprintf.c 以外ならば、以下の通りです。 Windows 以外ならばこれで試すことはできるでしょう。 diff --git a/sprintf.c b/sprintf.c index bec0569..e26b833 100644 --- a/sprintf.c +++ b/sprintf.c @@ -227,6 +227,10 @@ get_hash(volatile VALUE *hash, int argc, const VALUE *argv) * | equal to the precision, or in dd.dddd form otherwise. * | The precision specifies the number of significant digits. * G | Equivalent to `g', but use an uppercase `E' in exponent form. + * a | Convert floating point argument as [-]0xh.hhhhp[+-]dd, + * | which is consisted from optional sign, "0x", fraction part + * | as hexadecimal, "p", and exponential part as decimal. + * A | Equivalent to `a', but use uppercase `X' and `P'. * * Field | Other Format * ------+-------------------------------------------------------------- @@ -244,7 +248,7 @@ get_hash(volatile VALUE *hash, int argc, const VALUE *argv) * Flag | Applies to | Meaning * ---------+---------------+----------------------------------------- * space | bBdiouxX | Leave a space at the start of - * | eEfgG | non-negative numbers. + * | aAeEfgG | non-negative numbers. * | (numeric fmt) | For `o', `x', `X', `b' and `B', use * | | a minus sign with absolute value for * | | negative values. @@ -255,19 +259,19 @@ get_hash(volatile VALUE *hash, int argc, const VALUE *argv) * | | sprintf string. * ---------+---------------+----------------------------------------- * # | bBoxX | Use an alternative format. - * | eEfgG | For the conversions `o', increase the precision + * | aAeEfgG | For the conversions `o', increase the precision * | | until the first digit will be `0' if * | | it is not formatted as complements. * | | For the conversions `x', `X', `b' and `B' * | | on non-zero, prefix the result with ``0x'', * | | ``0X'', ``0b'' and ``0B'', respectively. - * | | For `e', `E', `f', `g', and 'G', + * | | For `a', `A', `e', `E', `f', `g', and 'G', * | | force a decimal point to be added, * | | even if no digits follow. * | | For `g' and 'G', do not remove trailing zeros. * ---------+---------------+----------------------------------------- * + | bBdiouxX | Add a leading plus sign to non-negative - * | eEfgG | numbers. + * | aAeEfgG | numbers. * | (numeric fmt) | For `o', `x', `X', `b' and `B', use * | | a minus sign with absolute value for * | | negative values. @@ -275,7 +279,7 @@ get_hash(volatile VALUE *hash, int argc, const VALUE *argv) * - | all | Left-justify the result of this conversion. * ---------+---------------+----------------------------------------- * 0 (zero) | bBdiouxX | Pad with zeros, not spaces. - * | eEfgG | For `o', `x', `X', `b' and `B', radix-1 + * | aAeEfgG | For `o', `x', `X', `b' and `B', radix-1 * | (numeric fmt) | is used for negative numbers formatted as * | | complements. * ---------+---------------+----------------------------------------- @@ -983,6 +987,8 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) case 'G': case 'e': case 'E': + case 'a': + case 'A': { VALUE val = GETARG(); double fval; -- NARUSE, Yui