[Feature #2969] String#to_f $B$,(B -h.hhh$B!^(Bpd $B$r2r<a$G$-$k$h$&$K(B

e$B$D$^$j!"$U$J$P$5$s$Oe(B 16 e$B?J$h$j$be(B 2 e$B?J$de(B 8 e$B?J7A<0$,9%$_$G$"$k$H$3$m!"e(B
16 e$B?J$,$=$l$i$r:9$7CV$$$FF~$k$N$OG<F@$G$-$J$$$H$$$&;v$G$7$g$&$+!#e(B

e$BE}0l@-$H%P%i%s%9$NLdBj$G$9!#e(B

e$B$o$?$7$N<gD%$O!"0J2<$N$h$&$J$b$N$G$9!#e(B
(1) -h.hhhe$B!^e(Bpd e$B7A<0$O!"Id9f!&2>?t!&;X?t$H$$$&IbF0>.?tE@?t$r$=$N$^$^I=$7$F$$$k$?$a!“e(B
e$BIbF0>.?tE@$NFbMF$rCN$k$N$KM-MQ$G$”$ke(B
(2) -h.hhhe$B!^e(Bpd e$B7A<0$O!“e(BC99 e$B$NIbF0>.?tE@?t%j%F%i%k$N0l7A<0$G$”$j!“e(B
e$B$=$N7A<0$OJ8K!$K!”=PNO$Oe(B printf e$B$K!"2r<a$Oe(B strtod e$B$K5-=R$5$l$F$$$ke(B
(3) e$BM-MQ$+$D0BDj$7$?7A<0$J$N$Ge(B Ruby e$B$G$b07$($k$Y$-$@e(B

ruby e$B$Oe(B C e$B$8$c$J$$$s$G!"D>$A$Ke(B ruby
e$B$G:NMQ$7$J$1$l$P$H$$$&$3$H$K$O$i$Je(B
e$B$$$G$7$g$&!#$7$+$7!"e(Bruby
e$B$G$D$+$($F$b$$$$$H;W$$$^$9!#$G!“0l1~e(B scanf e$B$He(B
e$B$$$&BP0F$r=P$7$F$$$^$9!#$7$+$7!”$3$l$^$Ge(B strtod
e$B$,$I$&$N$H$$$&OC$r7+$je(B
e$BJV$7!"L5;k$5$l$F$$$k>uBV$G$9!#e(B

e$B@.@%$5$s$Oe(B ruby e$B$He(B strtod
e$B$N7P0^$r6K$a$F<+J,$NET9g$N$h$&$h$&$KB*$($F$$e(B
e$B$k$h$&$G$9!#KM$b??Aj$OCN$j$^$;$s$,!"IaDL$K9M$($?$i!"e(B

e$B=i4|$K$*$$$Fe(B strtod e$B$Oe(B ruby
e$B$NMW5a$K9gCW$7$F$$$?!#$@$,!"$$$D$7$+e(B
strtod e$B$,JQ2=$7;O$a$?!#<+A0$Ne(B strtod
e$B$rF@$k$HNc30$J$/e(B16e$B?J?t$O07$($J$/$J$Ce(B
e$B$?$,!";H$($F$$$?;v$O$`$7$mM=A[30$@$C$?$N$G!"m4m0$&$3$H$b$J$+$C$?!#e(B

e$B$H$$$&;v$J$N$G$O!#e(B

e$B$I$C$A$K$7$m!"e(Bstrtod e$B$O$I$&$G$b$$$$$H;W$&$N$G$9$,!#e(B

e$B@.@%$5$s$N$[$&$O!"$3$l$O@5E}$J?J2=$@$+$i%1%A$r$D$1$i$l$k6Z9g$$$O$J$$$He(B
e$B$$$&0lE@D%$j$N$h$&$G!“4JC1$K$O7hCe$,$D$J$$$@$m$&$+$i!”$9$G$K%j%]%8%H%je(B
e$B$GJQ99$5$l$F$$$kJ,$O0lC6La$5$;$FLc$*$&$H;W$$$^$9e(B
(e$B%P%0$b$"$k$h$&$@$7e(B)e$B!#e(B
e$B$4N;>52<$5$$!#e(B

e$B$($0$A!w%(%9%"%s%I%$!<$G$9e(B

2010e$BG/e(B3e$B7ne(B27e$BF|e(B21:01 NARUSE, Yui [email protected]:

e$B$3$A$i$O!"0l4S@-$HMxJX@-$,>WFM$9$k;vNc$H$$$&OC$@$H;W$$$^$9!#e(B

e$B$G!“8=:_F1$8$+$H$$$&$He(B “10”.to_f e$B$N$h$&$Je(B 10 e$B?J@0?t$O$9$G$K0[$J$C$F$$$^$9!#e(B
e$B$^$?!”%(%C%8%1!<%9$r96$a$k$He(B 4._9 e$B$O%(%i!<$K$J$k$,!“e(B
“4._9”.to_f e$B$Oe(B 4.9 e$B$rJV$9$H$$$&$h$&$JNc$b$”$j$^$9!#e(B

e$B$3$N5sF0$OLq2p$G$9!#e(B

Float(e$B!Ie(B4._9e$B!Ie(B) e$B$G$O$^$?JL$N%(%i!<$K$J$C$?$j$7$^$9!#e(B
e$B$I$&$“$k$Y$-$@$C$?$N$+$K$D$$$F$OL@3N$JO@E@$r;}$C$F$^$;$s!#e(B
e$B$?$@!”>.?tE@$H%a%=%C%I8F$S=P$7$,[#Kf$K$J$k%1!<%9$H$$$&0UL#$Ge(B
e$B:#2s$N5DO@$HF1:,$@$H;W$$$^$9!#e(B

e$B7k6I!"@)Ls$N6/$$%j%F%i%k$H!"J8;zNs$r2r<a$9$k$N$G$O>r7o$,0[$J$k$o$1$G!"e(B
e$B!Ve(BRuby e$B$N%j%F%i%k$H$7$FIbF0>.?tE@?t$H$7$F2r<a$5$l$k$J$i$P!"e(B
String#to_f e$B$G$b2r<a$5$l$k$Y$-!W$OB:=E$5$l$k$Y$-$@$H;W$$$^$9$,!"e(B
e$B$=$N5U$OI,$:$7$b@.$jN)$DI,MW$O$J$$$H;W$$$^$9!#e(B

e$B$=$l$bF’$^$($F!"!"e(B

Rubye$B%j%F%i%kI=8=$H$7$F$b;H$($kI=8=7A<0$rLO:w$7$F$+$i$G$be(B
e$BCY$/$J$$$h$&$K;W$($^$9!#e(B

e$B$($0$Ae(B

2010e$BG/e(B3e$B7ne(B27e$BF|e(B19:14 NARUSE, Yui [email protected]:

ML e$B>e$G$N:GBg$Ne(B use case e$B$OIbF0>.?tE@?t$rM}2r$7$F$$$J$$%f!<%6$X$N@bL@MQ$G$7$g$&$M!#e(B

e$B$=$NMQES$KI,MW$J$N$O!“e(BString#to_f e$B$h$j!”$^$:e(B Float#to_s
e$B$J$s$8$c$J$$$G$9$+$M!#e(B

printf e$B$G$b$$$$$G$9$,!#e(B

e$B$D$^$j!"$U$J$P$5$s$Oe(B 16 e$B?J$h$j$be(B 2 e$B?J$de(B 8 e$B?J7A<0$,9%$_$G$"$k$H$3$m!"e(B
16 e$B?J$,$=$l$i$r:9$7CV$$$FF~$k$N$OG<F@$G$-$J$$$H$$$&;v$G$7$g$&$+!#e(B

e$BE}0l@-$H%P%i%s%9$NLdBj$G$9!#e(B

e$B$3$l$@$1$@$H!VD>46E*$K5$$KF~$i$J$$!#!W$H$7$+FI$a$J$$$N$G$J$s$H$+8@8l2=$7$F$b$i$($^$;$s$+!#e(B
e$B:#$N$H$3$m$U$J$P$5$s$N0U8+$K;?@.$9$kM}M3$O$J$$$H$$$&$+!"$=$b$=$b0U?^$,e(B
e$BL@Gr$G$O$J$$$h$&$K8+$($F$$$k$N$G!"8=;~E@$G$Ne(Breverte$B$K$OH?BP$G$9!#e(B

e$B$A$c$s$H5DO@$7$F$*$+$J$$$H!":FDs0F$N;~$KF1$8OC$r>x$7JV$9$3$H$K$J$C$Fe(B
e$B$*8_$$7y$J;W$$$r$9$k$N$G$O$J$$$G$7$g$&$+!#e(B

e$B@.@%$5$s$N$[$&$O!"$3$l$O@5E}$J?J2=$@$+$i%1%A$r$D$1$i$l$k6Z9g$$$O$J$$$He(B
e$B$$$&0lE@D%$j$N$h$&$G!"e(B

e$B$3$3$O;?@.$7$^$;$s!#e(B
e$B0BDj$7$F$$$k7A<0$G$"$k$H9M$($k:,5r!"M-MQ$H9M$($k:,5r$O=q$+$l$F$$$k$h$&$KFI$a$^$9!#e(B
e$B$=$l$K;?@.$9$k$+$I$&$+$O$H$b$+$/!"0lE@D%$j$H$O;W$$$^$;$s!#e(B

e$B;d$+$i8+$k$H@.@%$5$s$N0U8+$O!V;?@.$G$-$J$$$1$I$$$$$?$$$3$H$OJ,$+$k!#!W$G$9$,e(B
e$B$U$J$P$5$s$N%a!<%k$O$=$b$=$b8@$$$?$$;v$,$h$/J,$+$i$J$$$N$GJV?.$,=q$-$K$/$$$G$9!#e(B

(2010/03/27 20:56), Tadayoshi F. wrote:

e$B$D$^$j!"$U$J$P$5$s$Oe(B 16 e$B?J$h$j$be(B 2 e$B?J$de(B 8 e$B?J7A<0$,9%$_$G$"$k$H$3$m!"e(B
16 e$B?J$,$=$l$i$r:9$7CV$$$FF~$k$N$OG<F@$G$-$J$$$H$$$&;v$G$7$g$&$+!#e(B

e$BE}0l@-$H%P%i%s%9$NLdBj$G$9!#e(B

e$B2?$NE}0l@-$H%P%i%s%9$G$7$g$&!#e(B
String#to_i e$B$H$NE}0l@-$H%P%i%s%9!"$G$7$g$&$+!#e(B

e$BJV$7!"L5;k$5$l$F$$$k>uBV$G$9!#e(B
strtod(3)
e$B$NOC$O!"e(B16e$B?J@0?tI=8=$N2r<a$O$G$-$J$$$N$+$H$NLd$$$KBP$7$F!"e(B
strtod(3) e$B$NHO0O$J$i$PL7=bL5$/3HD%$G$-$k$HJV$7$?$N$,:G=i$G$9!#e(B

e$B$^$?!"e(Bprintf e$B$NH?BP$J$N$@$+$ie(B scanf
e$B$GBP1~$9$k$Y$-$H$$$&<gD%$KBP$7$F$O!"e(B
16e$B?JIbF0>.?tE@?t7A<0$bIbF0>.?tE@?t7A<0$J$N$Ge(B printf
e$B$H$NBP1~$K$3$@$o$i$:!"e(B
String#to_f e$B$G$b07$($F$$$$$H;W$&$HJV$7$F$$$^$9!#e(B

e$B$J$*!"@h$Ke(B scanf
e$BB&$K$b<BAu$9$k$Y$-$H$N<gD%$J$i$P$=$&$+$b$7$l$^$;$s!#e(B
e$B$H!";W$C$Fe(B lib/scanf.rb e$B$r8+$k$H!D!D!"e(B

def extract_float(s); s.to_f if s &&! skip; end

e$B$(!<$C$H!“e(Blib/scanf.rb e$B$G;H$&$H$$$&%f!<%9%1!<%9$re(B
String#to_f e$B$Ke(B
e$BDI2C$7$F$$$$$G$9$+!#e(B
e$B$H$j$”$($:e(B Ruby e$B$G<BAu$9$k$J$i0J2<$NDL$j$G$7$g$&$+!#e(B

diff --git a/lib/scanf.rb b/lib/scanf.rb
index ffc0d90…dd6ba6c 100644
— a/lib/scanf.rb
+++ b/lib/scanf.rb
@@ -112,7 +112,7 @@ and tests/scanftests.rb for examples.)
[x,X]
Matches an optionally signed hexadecimal integer,

-[f,g,e,E]
+[a,e,f,g,A,E,F,G]
Matches an optionally signed floating-point number.

[s]
@@ -309,7 +309,22 @@ module Scanf

 def skip;  /^\s*%\*/.match(@spec_string); end
  • def extract_float(s); s.to_f if s &&! skip; end
  • def extract_float(s)
  •  return nil unless s &&! skip
    
  •  if 
    

/\A(?[-+]?)0xXpP/
=~ s

  •    f1, f2 = frac.split('.')
    
  •    f = f1.hex
    
  •    if f2
    
  •      len = f2.length
    
  •      if len > 0
    
  •        f += f2.hex / (16.0 ** len)
    
  •      end
    
  •    end
    
  •    (sign == ?- ? -1 : 1) * Math.ldexp(f, exp.to_i)
    
  •  else
    
  •    s.to_f
    
  •  end
    
  • end
    def extract_decimal(s); s.to_i if s &&! skip; end
    def extract_hex(s); s.hex if s &&! skip; end
    def extract_octal(s); s.oct if s &&! skip; end
    @@ -409,12 +424,12 @@ module Scanf
    [ “([-+][0-7]{1,#{$1.to_i-1}}|[0-7]{1,#{$1}})”,
    :extract_octal ]

      # %f
    
  •    when /%\*?[efgEFG]/
    
  •      [ '([-+]?(?:\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))', 
    

:extract_float ]

  •    when /%\*?[aefgAEFG]/
    
  •      [ 
    

‘([-+]?(?:0xX[pP][-+]\d+|\d+(?![\d.])|\d*.\d*(?:[eE][-+]?\d+)?))’,
:extract_float ]

       # %5f
  •    when /%\*?(\d+)[efgEFG]/
    
  •      [ '(?=[-+]?(?:\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))' +
    
  •    when /%\*?(\d+)[aefgAEFG]/
    
  •      [ 
    

‘(?=[-+]?(?:0xX[pP][-+]\d+|\d+(?![\d.])|\d*.\d*(?:[eE][-+]?\d+)?))’
+
“(\S{1,#{$1}})”, :extract_float ]

       # %5s

@@ -491,7 +506,7 @@ module Scanf
attr_reader :string_left, :last_spec_tried,
:last_match_tried, :matched_count, :space

  • SPECIFIERS = ‘diuXxofFeEgGsc’
  • SPECIFIERS = ‘diuXxofFeEgGscaA’
    REGEX = /
    # possible space, followed by…
    (?:\s*
    diff --git a/test/scanf/test_scanf.rb b/test/scanf/test_scanf.rb
    index 2ec4e54…169ffe6 100644
    — a/test/scanf/test_scanf.rb
    +++ b/test/scanf/test_scanf.rb
    @@ -276,6 +276,8 @@ module ScanfTests
    [ “%g”, “+3.25”, [3.25] ],
    [ “%G”, “+3.25e2”, [325.0] ],
    [ “%f”, “3.z”, [3.0] ],
  •  [ "%a", "0X1P+10", [1024.0] ],
    
  •  [ "%A", "0x1.deadbeefp+99", [1.1851510441583988e+30] ],
    

Testing embedded matches including literal ‘[’ behavior

   [",%d,%f", ",10,1.1", [10,1.1] ],

(2010/03/27 21:46), EGUCHI Osamu wrote:

ただ、浮動小数点リテラル表現と String#to_f は同じであろうと

それも踏まえて、、

Rubyリテラル表現としても使える表現形式を模索してからでも
遅くないように思えます。

踏まえるとなぜRubyリテラル表現としても使える表現形式を模索することに
なるのかがよくわかりません。

推測するに、前段とは独立に、よりよい形式が現れた際に今回の形式との互換性に
縛られることを懸念しているのではないかと思います。

で、mame さんに教えてもらったのですが、IEEE 754:2008 の draft に、
今回の形式と浮動小数点数との変換を求める規定があるそうです。

7.12.2 External hexadecimal character sequences representing finite
numbers

Implementations supporting binary formats shall provide conversions
between all
supported internal binary formats and external hexadecimal character
sequences.
External hexadecimal character sequences for finite numbers are of
the form
specified by ISO/IEC 9899, Programming Languages – C (C99)
subclauses:
6.4.4.2 floating constants,
20.1.3 strtod,
7.19.6.2 fscanf (a, e, f, g), and
7.19.6.1 fprintf (a, A).

IEEE 754:2008 draft 1.2.9, 27 January 2007
http://www.validlab.com/754R/nonabelian.com/754/comments/Q754.129.pdf

Ruby は IEEE 754 ã«æº–æ‹ ã—ã‚ˆã†ã¨ã„ã†æ°—ã¯ãªã‹ã£ãŸã¯ãšãªã®ã§ã€
この規定を守るいわれはありませんが、今後 IEEE 754:2008 をサポートしよう
という環境はこの形式の出力を行うことになります。
なお、C 言語 以外だと Java は 1.5 でこの形式をサポートしているようです。

というわけで、既にメジャーな 2 言語によってサポートされ、今後もサポート
する言語は増えることが予想されるので、リテラルとは独立にサポートして
いいのではないかと思います。

e$B$3$l$@$1$@$H!VD>46E*$K5$$KF~$i$J$$!#!W$H$7$+FI$a$J$$$N$G$J$s$H$+8@8l2=$7$F$b$i$($^$;$s$+!#e(B
(e$BCfN,e(B)
e$B;d$+$i8+$k$H@.@%$5$s$N0U8+$O!V;?@.$G$-$J$$$1$I$$$$$?$$$3$H$OJ,$+$k!#!W$G$9$,e(B
e$B$U$J$P$5$s$N%a!<%k$O$=$b$=$b8@$$$?$$;v$,$h$/J,$+$i$J$$$N$GJV?.$,=q$-$K$/$$$G$9!#e(B

e$B0lC6D9$a$NJV;v=q$$$?$s$@$1$I!"$^$?J,$i$J$$$C$F8@$o$l$=$&$J$s$G!"$b$&e(B
to_f e$B$Oe(B strtod(3)
e$B$G$9$C$F;v$G$$$$$+$J!#$3$s$J$H$3$m$G4hD%$C$F$b26E*$Ke(B
e$B%P%i%s%9$r7g$$$F$k$7!#e(B

e$BE}0l@-$H%P%i%s%9$NLdBj$G$9!#e(B

e$B2?$NE}0l@-$H%P%i%s%9$G$7$g$&!#e(B
String#to_i e$B$H$NE}0l@-$H%P%i%s%9!"$G$7$g$&$+!#e(B

[ruby-dev:40728] e$B$G=q$$$?$h$&$J$3$H$G$9!#e(B

e$B$?$H$($P!"e(Bto_i e$B$Oe(B16e$B?J?t$r5qH]$G$-$^$9$,!“e(Bto_f
e$B$OABr;h$,$"$j$^$;$s!#N>e(B
e$B<T$O0c$$$,=P$F$-$F$$$^$9!#KM$O@.@%$5$s$,$$$&MxE@$K$D$$$F$O$"$^$j0[O@$Oe(B
e$B$J$$$G$9$h!#<:$&$b$N$,$"$k$h$&$K46$8$F!"$=$l$,5$$K$J$C$F$$$k$@$1$G$9!#e(B
e$B<B:]!":#8e$be(B to_f
e$B$OKX$I$N>l9g$O!"e(B10e$B?J?tMQ$H$7$F$D$+$o$l$kH&$G$9!#e(Bto_i
e$B$Oe(B16e$B?J?t$b07$($^$9$,!“MxMQ<T$O$=$N$3$H$K$D$$$FK:$l$F$bLdBj$”$j$^$;$s!#e(B
e$BI,MW$J;~$O!"e(Bto_i
e$B$K%
%W%7%g%s$,$”$C$?$H$$$&$3$H$r;W$$=P$;$^$9!#e(Bto_f e$B$Ke(B
e$B$H$C$FI,MW$G$J$/$F$b!"e(Bto_i e$B$He(B to_f
e$B$r$D$+$&MxMQ<T$+$i8+$l$P!"F1$8$h$&$Je(B
e$B;H$$>!<j$G!“F1$8$h$&$K%*%W%7%g%s$,MQ0U$5$l$F$$$k$[$&$,!“J,$j0W$$$H;W$$e(B
e$B$^$9!#$3$l$,E}0l@-$NOC!#$^$?!”<:$&$b$N$,$”$k$H$9$l$P!“K\Ev$K!“e(BFloat()
e$B$de(B to_f
e$B$GDs6!$9$kI,MW@-!“2ACM$,$”$k$+!”%P%i%s%9$N$H$l$?2r@bJ}K!$J$N$+e(B
e$B5?Ld$@$C$?$N$G$9!#$5$7$”$?$j$O!“e(Blib/scanf.rb
e$B$G$b$$$$$N$G$O$J$$$+!#$3$Ne(B
e$B$”$?$j$,%P%i%s%9$NOC!#e(B

e$B$G$b!"$^$“e(B to_f e$B$Oe(B strtod(3)
e$B$J$s$@$m$&$@$+$i!”$b$&$$$$$H;W$$$^$9!#$3$le(B
e$B$bM}2r$7$F$b$i$($k$N$+$I$&$+J,$j$^$;$s$,$i!#e(B

(2010/03/27 23:49), Tanaka A. wrote:

2010e$BG/e(B3e$B7ne(B27e$BF|e(B19:14 NARUSE, Yui[email protected]:

ML e$B>e$G$N:GBg$Ne(B use case e$B$OIbF0>.?tE@?t$rM}2r$7$F$$$J$$%f!<%6$X$N@bL@MQ$G$7$g$&$M!#e(B

e$B$=$NMQES$KI,MW$J$N$O!“e(BString#to_f e$B$h$j!”$^$:e(B Float#to_s e$B$J$s$8$c$J$$$G$9$+$M!#e(B

printf e$B$G$b$$$$$G$9$,!#e(B

e$BM}2r$7$F$$$J$$%f!<%6$N$?$a$K!“DL>o$NMxJX@-$rMn$H$9$3$H$O9M$($^$;$s$G$7$?!#e(B
e$B$J$N$G!“e(Bprintf e$B$G$$$$$s$8$c$J$$$+$J$!$H;W$$$^$9!#e(B
Float#to_s(16)
e$B$G4|BT$9$k$N$,$3$N7A<0$+$H$$$&$H!”$^$?>/$7G:$`$H$3$m$,$”$j$^$9$7!#e(B

e$B$J$*!"!Ve(BML e$B>e$G$N!W$H$D$1$?$N$O4QB,2DG=$@$+$i$G$7$?!#e(B

e$B8D?ME*$JMxMQ$G$$$&$H!"e(BMath.atanh e$B$de(B Math.log
e$B<~$j$N%P%0$r=$@5$7$F$$$k$H$-$K!"e(B
e$B$=$l$>$l$N4D6-$Ne(B Ruby e$B$K%Q%C%A$rEv$F$D$D!"e(B%a
e$B$N=PNO$r$K$i$a$C$3$7$F$$$^$7$?!#e(B
10 e$B?J$@$He(B 10 e$B?JJQ49$,F~$k$N$G2?$,5/$-$F$$$k$+$o$+$i$J$$$7!“e(B
pack
e$B$@$H$I$3$^$G$,;X?tIt$+0lL$G$o$+$i$J$$$N$G!”$3$N7A<0$OM-MQ$G$7$?!#e(B

e$B$D$$$G$Ke(B missing/vsnprint.f e$B$b4^$a$?e(B printf(“%a”)
e$B$N%Q%C%A!#e(B

diff --git a/LEGAL b/LEGAL
index 991bb4d…c28a0b5 100644
— a/LEGAL
+++ b/LEGAL
@@ -123,6 +123,32 @@ win32/win32.[ch]:
You may distribute under the terms of either the GNU General Public
License or the Artistic License, as specified in the perl README
file.

+util.c (partly):
+

  • Copyright (c) 2004-2008 David S. [email protected]
  • All rights reserved.
  • Redistribution and use in source and binary forms, with or without
  • modification, are permitted provided that the following conditions
  • are met:
    1. Redistributions of source code must retain the above copyright
  •  notice, this list of conditions and the following disclaimer.
    
    1. Redistributions in binary form must reproduce the above copyright
  •  notice, this list of conditions and the following disclaimer in 
    

the

  •  documentation and/or other materials provided with the 
    

distribution.
+

  • THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS’’
    AND
  • ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    THE
  • IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    PURPOSE
  • ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
    LIABLE
  • FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL
  • DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
    GOODS
  • OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION)
  • HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    STRICT
  • LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    ANY WAY
  • OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
    OF
  • SUCH DAMAGE.

random.c

This file is under the new-style BSD license.
diff --git a/missing/vsnprintf.c b/missing/vsnprintf.c
index 4e19651…acb09c9 100644
— a/missing/vsnprintf.c
+++ b/missing/vsnprintf.c
@@ -559,7 +559,7 @@ BSD_vfprintf(FILE *fp, const char fmt0, va_list ap)
struct __suio uio; /
output information: summary /
struct __siov iov[NIOV];/
… and individual io vectors /
char buf[BUF]; /
space for %c, %[diouxX], %[eEfgG] */

  • char ox[2]; /* space for 0x hex-prefix */
  • char ox[4]; /* space for 0x hex-prefix, hexadecimal’s 1. */
    char *const ebuf = buf + sizeof(buf);
    #if SIZEOF_LONG > SIZEOF_INT
    long ln;
    @@ -784,6 +784,11 @@ reswitch: switch (ch) {
    base = 10;
    goto number;
    #ifdef FLOATING_POINT
  • case ‘a’:
  • case ‘A’:
  •  if (prec >= 0)
    
  •    prec++;
    
  •  goto fp_begin;
    
    case ‘e’: /* anomalous precision */
    case ‘E’:
    if (prec != 0)
    @@ -822,7 +827,12 @@ fp_begin: _double = va_arg(ap, double);
    else
    ch = ‘g’;
    }
  •  if (ch <= 'e') {  /* 'e' or 'E' fmt */
    
  •  if (ch == 'a' || ch == 'A') {
    
  •    --expt;
    
  •    expsize = exponent(expstr, expt, ch + 'p' - 'a');
    
  •    size = expsize + ndig;
    
  •  }
    
  •  else if (ch <= 'e') {  /* 'e' or 'E' fmt */
       --expt;
       expsize = exponent(expstr, expt, ch);
       size = expsize + ndig;
    

@@ -1048,7 +1058,20 @@ long_len:
if ((flags & FPT) == 0) {
PRINT(cp, fieldsz);
} else { /* glue together f_p fragments */

  •  if (ch >= 'f') {  /* 'f' or 'g' */
    
  •  if (ch == 'a' || ch == 'A') {
    
  •    ox[0] = '0';
    
  •    ox[1] = ch + ('x' - 'a');
    
  •    PRINT(ox, 2);
    
  •    if (ndig > 1 || flags & ALT) {
    
  •      ox[2] = *cp++;
    
  •      ox[3] = '.';
    
  •      PRINT(ox+2, 2);
    
  •      PRINT(cp, ndig-1);
    
  •    } else  /* XpYYY */
    
  •      PRINT(cp, 1);
    
  •    PRINT(expstr, expsize);
    
  •  }
    
  •  else if (ch >= 'f') {  /* 'f' or 'g' */
       if (_double == 0) {
       /* kludge for __dtoa irregularity */
         if (ndig <= 1 &&
    

@@ -1112,6 +1135,7 @@ error:
#ifdef FLOATING_POINT

extern char *BSD__dtoa __P((double, int, int, int *, int *, char **));
+extern char *BSD__hdtoa(double, const char *, int, int *, int *, char
**);

static char *
cvt(value, ndigits, flags, sign, decpt, ch, length, buf)
@@ -1135,7 +1159,14 @@ cvt(value, ndigits, flags, sign, decpt, ch,
length, buf)
} else {
*sign = ‘\000’;
}

  • digits = BSD__dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
  • if (ch == ‘a’ || ch ==‘A’) {
  •  digits = BSD__hdtoa(value,
    
  •    ch == 'a' ? "0123456789abcdef" : "0123456789ABCDEF",
    
  •    ndigits, decpt, &dsgn, &rve);
    
  • }
  • else {
  •  digits = BSD__dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
    
  • }
    memcpy(buf, digits, rve - digits);
    xfree(digits);
    rve = buf + (rve - digits);
    @@ -1181,7 +1212,7 @@ exponent(p0, exp, fmtch)
    for (; t < expbuf + MAXEXP; *p++ = *t++);
    }
    else {
  • *p++ = ‘0’;
  • if (fmtch & 15) p++ = ‘0’; / other than p or P */
    *p++ = to_char(exp);
    }
    return (int)(p - p0);
    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;
    diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb
    index 15424d9…f8dbbd5 100644
    — a/test/ruby/test_sprintf.rb
    +++ b/test/ruby/test_sprintf.rb
    @@ -191,6 +191,19 @@ class TestSprintf < Test::Unit::TestCase
    assert_equal(" Inf", sprintf(“% 0e”, 1.0/0.0), “moved from
    btest/knownbug”)
    end

  • def test_float_hex

  • assert_equal(“-0x0p+0”, sprintf(“%a”, -0.0))

  • assert_equal(“0x0p+0”, sprintf(“%a”, 0.0))

  • assert_equal(“0x1p-1”, sprintf(“%a”, 0.5))

  • assert_equal(“0x1p+0”, sprintf(“%a”, 1.0))

  • assert_equal(“0x1p+1”, sprintf(“%a”, 2.0))

  • assert_equal(“0x1.193ea7aad030ap+0”, sprintf(“%a”, Math.log(3)))

  • assert_equal(“0X1.193EA7AAD030AP+0”, sprintf(“%A”, Math.log(3)))

  • assert_equal(“0x1p+10”, sprintf(“%a”, 1024))

  • assert_equal(“0x1.23456p+789”, sprintf(“%a”,
    3.704450999893983e+237))

  • assert_equal(“0x1p-1074”, sprintf(“%a”, 4.9e-324))

  • end

  • BSIZ = 120

    def test_skip
    diff --git a/util.c b/util.c
    index 9cdb563…88914be 100644
    — a/util.c
    +++ b/util.c
    @@ -3860,6 +3857,149 @@ ruby_each_words(const char str, void
    (func)(const char, int, void
    ), void *ar
    }
    }

+/*-

    • All rights reserved.
    • Redistribution and use in source and binary forms, with or without
    • modification, are permitted provided that the following conditions
    • are met:
      1. Redistributions of source code must retain the above copyright
    • notice, this list of conditions and the following disclaimer.
      1. Redistributions in binary form must reproduce the above copyright
    • notice, this list of conditions and the following disclaimer in
      the
    • documentation and/or other materials provided with the
      distribution.
    • THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS’’
      AND
    • ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
      THE
    • IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      PURPOSE
    • ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
      LIABLE
    • FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      CONSEQUENTIAL
    • DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
      GOODS
    • OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      INTERRUPTION)
    • HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      STRICT
    • LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
      ANY WAY
    • OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
      OF
    • SUCH DAMAGE.
  • */

+#define DBL_MANH_SIZE 20
+#define DBL_MANL_SIZE 32
+#define INFSTR “Infinity”
+#define NANSTR “NaN”
+#define DBL_ADJ (DBL_MAX_EXP - 2)
+#define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1)
+#define dexp_get(u) ((int)(word0(u) >> Exp_shift) & ~Exp_msk1)
+#define dexp_set(u,v) (word0(u) = (((int)(word0(u)) & ~Exp_mask) | (v
<< Exp_shift)))
+#define dmanh_get(u) ((int)(word0(u) & Frac_mask))
+#define dmanl_get(u) ((int)word1(u))
+
+
+/*

    • This procedure converts a double-precision number in IEEE format
    • into a string of hexadecimal digits and an exponent of 2. Its
    • behavior is bug-for-bug compatible with dtoa() in mode 2, with the
    • following exceptions:
      • An ndigits < 0 causes it to use as many digits as necessary to
    • represent the number exactly.
      • The additional xdigs argument should point to either the string
    • “0123456789ABCDEF” or the string “0123456789abcdef”, depending on
    • which case is desired.
      • This routine does not repeat dtoa’s mistake of setting decpt
    • to 9999 in the case of an infinity or NaN. INT_MAX is used
    • for this purpose instead.
    • Note that the C99 standard does not specify what the leading digit
    • should be for non-zero numbers. For instance, 0x1.3p3 is the same
    • as 0x2.6p2 is the same as 0x4.cp3. This implementation always makes
    • the leading digit a 1. This ensures that the exponent printed is the
    • actual base-2 exponent, i.e., ilogb(d).
    • Inputs: d, xdigs, ndigits
    • Outputs: decpt, sign, rve
  • */
    +char *
    +BSD__hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int
    *sign,
  • char **rve)
    +{
  • U u;
  • char *s, *s0;
  • int bufsize;
  • uint32_t manh, manl;
  • u.d = d;
  • if (word0(u) & Sign_bit) {
  •  /* set sign for everything, including 0's and NaNs */
    
  •  *sign = 1;
    
  •  word0(u) &= ~Sign_bit;  /* clear sign bit */
    
  • }
  • else
  •  *sign = 0;
    
  • switch (fpclassify(d)) {
  • case FP_NORMAL:
  • *decpt = dexp_get(u) - DBL_ADJ;
  • break;
  • case FP_ZERO:
  • *decpt = 1;
  • return (nrv_alloc(“0”, rve, 1));
  • case FP_SUBNORMAL:
  • u.d = 5.363123171977039e+154 / 0x1p514 */;
  • *decpt = dexp_get(u) - (514 + DBL_ADJ);
  • break;
  • case FP_INFINITE:
  • *decpt = INT_MAX;
  • return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1));
  • default: /* FP_NAN or unrecognized */
  • *decpt = INT_MAX;
  • return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1));
  • }
  • /* FP_NORMAL or FP_SUBNORMAL */
  • if (ndigits == 0) /* dtoa() compatibility */
  • ndigits = 1;
  • /*
    • If ndigits < 0, we are expected to auto-size, so we allocate
    • enough space for all the digits.
  • */
  • bufsize = (ndigits > 0) ? ndigits : SIGFIGS;
  • s0 = rv_alloc(bufsize);
  • /* Round to the desired number of digits. */
  • if (SIGFIGS > ndigits && ndigits > 0) {
  • float redux = 1.0;
  • int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG;
  • dexp_set(u, offset);
  • u.d += redux;
  • u.d -= redux;
  • *decpt += dexp_get(u) - offset;
  • }
  • manh = dmanh_get(u);
  • manl = dmanl_get(u);
  • *s0 = ‘1’;
  • for (s = s0 + 1; s < s0 + bufsize; s++) {
  • *s = xdigs[(manh >> (DBL_MANH_SIZE - 4)) & 0xf];
  • manh = (manh << 4) | (manl >> (DBL_MANL_SIZE - 4));
  • manl <<= 4;
  • }
  • /* If ndigits < 0, we are expected to auto-size the precision. */
  • if (ndigits < 0) {
  • for (ndigits = SIGFIGS; s0[ndigits - 1] == ‘0’; ndigits–)
  •  ;
    
  • }
  • s = s0 + ndigits;
  • *s = ‘\0’;
  • if (rve != NULL)
  • *rve = s;
  • return (s0);
    +}

#ifdef __cplusplus
#if 0
{

e$B@.@%$G$9!#e(B

(2010/03/29 7:04), Yukihiro M. wrote:

|e$B5/I<<Te(B: Yui NARUSE
| and e$B!Fe(Bnane$B!Ge(B, respectively.
e$B4V$K9g$o$J$$$N$Ge(B printf e$B$ODs0F$7$J$$$H$$$&$3$H$G$7$?$i!"L5M}e(B
e$B$Ke(B 1.9.2 e$B$KF3F~$;$:$K!"e(Bprintfe$B$N<BAu$bBP$K$9$k$Y$-$@$H;W$$$^e(B
e$B$9!#e(B

missing e$B$r4^$a$?e(B printf e$B$N<BAu$O!“e(B[ruby-dev:40801]
e$B$K$”$j$^$9!#e(B
e$B$N$G!"$3$NE@$K4X$7$F;~4|E*$JLdBj$O$J$$$+$H;W$$$^$9!#e(B

e$B$9$k2DG=@-$,$"$k$N$Ge(B (a) e$B$OBP>]$K$7$J$$$H$$$&$N$,%3%s%;%s%5e(B

e$B$H$9$k$H!">-Mhe(B %a e$BI=8=$N2r<a$rF3F~$9$k:]$K$Oe(BFloat()e$B$,$3$N7A<0e(B
e$B$r2r<a$7!“e(Bto_fe$B$O9T$o$J$$$H$$$&$N$,!”<+A3$G$O$J$$$N$+$H;W$$$^e(B
e$B$9!#$b$C$H$b!"$3$l$O;d$N0U8+$H8@$&$@$1$G!":G=*7hDj$G$O$"$j$^e(B
e$B$;$s$,!#e(B

e$B$J$k$[$I!"$o$?$7$O<j7Z$K;H$($l$P$h$$$N$G0[O@$O$"$j$^$;$s!#e(B

e$B:G8e$Ke(B (d) scanf e$B$G$9$,!“e(Bprintfe$B$,e(B %a e$B$r:NMQ$7$?$”$+$D$-$K$O!"e(B
scanf e$B$be(B %a e$B$rF3F~$7$?J}$,$h$$$H;W$$$^$9!#e(B

scanf e$B$N<BAu$Oe(B [ruby-dev:40799] e$B$K<($7$F$$$^$9!#e(B

to_ie$B$de(Bto_fe$B$,%(%i!<$KBP$7$Fe(B 0 e$B$rJV$9$N$O!“8e2y$7$F$$$k;EMM$Ne(B
e$B0l$D$G$9$,!”:#$5$iJQ$($i$l$J$$$G$9$M!#e(B

e$B<!$N%A%c%s%9$Oe(B 2.0 e$B$G$9$+$M$’!#e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:40816] Re: [Feature #2969] String#to_f
e$B$,e(B -h.hhhe$B!^e(Bpd e$B$r2r<a$G$-$k$h$&$Ke(B”
on Mon, 29 Mar 2010 08:08:37 +0900, “NARUSE, Yui”
[email protected] writes:

|> * 1.9.2e$B$K$OF3F~$7$J$$!#>-Mh$H$b5qH]$H$$$&$o$1$G$O$J$$!#e(B
|>
|> e$B$^$:!"$3$N5!G=$G$9$,!“I,MW@-$O$5$[$I9b$/$J$$$N$G!“F3F~$9$k$Ne(B
|> e$B$G$”$l$Pe(B printf e$B$HF1;~$KF3F~$9$Y$-$@$H;W$$$^$9!#$G$b!”<BAu$,e(B
|> e$B4V$K9g$o$J$$$N$Ge(B printf e$B$ODs0F$7$J$$$H$$$&$3$H$G$7$?$i!"L5M}e(B
|> e$B$Ke(B 1.9.2 e$B$KF3F~$;$:$K!“e(Bprintfe$B$N<BAu$bBP$K$9$k$Y$-$@$H;W$$$^e(B
|> e$B$9!#e(B
|
|missing e$B$r4^$a$?e(B printf e$B$N<BAu$O!“e(B[ruby-dev:40801] e$B$K$”$j$^$9!#e(B
|e$B$N$G!”$3$NE@$K4X$7$F;~4|E*$JLdBj$O$J$$$+$H;W$$$^$9!#e(B

e$B$$!“$=$l$O8+Mn$H$7$F$^$7$?!#$G$b!”@.@%$5$s$O!Ve(Bprintfe$B$Oe(B1.9.3
e$B$^$GBT$D!W$H$$C$7$c$C$F$$$?$h$&$K;W$$$^$9!#;~4|E$JLdBj$O$Je(B
e$B$$$H$9$k$H!"$=$l$O$J$<!)e(B

|> e$B:G8e$Ke(B (d) scanf e$B$G$9$,!“e(Bprintfe$B$,e(B %a e$B$r:NMQ$7$?$”$+$D$-$K$O!"e(B
|> scanf e$B$be(B %a e$B$rF3F~$7$?J}$,$h$$$H;W$$$^$9!#e(B
|
|scanf e$B$N<BAu$Oe(B [ruby-dev:40799] e$B$K<($7$F$$$^$9!#e(B

e$B$3$l$K$D$$$F$b;~4|E*$JLdBj$O$J$$$o$1$G$9$M!#e(B

|> to_ie$B$de(Bto_fe$B$,%(%i!<$KBP$7$Fe(B 0 e$B$rJV$9$N$O!“8e2y$7$F$$$k;EMM$Ne(B
|> e$B0l$D$G$9$,!”:#$5$iJQ$($i$l$J$$$G$9$M!#e(B
|
|e$B<!$N%A%c%s%9$Oe(B 2.0 e$B$G$9$+$M$'!#e(B

e$B$$$d$!!"8e2y$7$F$$$k$+$i$H$$$C$F8_49@-LdBj$r0B0W$KF3F~$7$A$ce(B
e$B$&$H!"0\9T$NK8$2$K$J$C$A$c$$$^$9$+$i$M$(!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

e$B$9$$$^$;$s!"K;$7$/$FJ|CV$7$F$^$7$?!#e(B

In message “Re: [ruby-dev:40650] [Feature #2969] String#to_f e$B$,e(B
-h.hhhe$B!^e(Bpd e$B$r2r<a$G$-$k$h$&$Ke(B”
on Tue, 16 Mar 2010 04:01:52 +0900, Yui NARUSE
[email protected] writes:
|
|Feature #2969: String#to_f e$B$,e(B -h.hhhe$B!^e(Bpd e$B$r2r<a$G$-$k$h$&$Ke(B
|http://redmine.ruby-lang.org/issues/show/2969
|
|e$B5/I<<Te(B: Yui NARUSE
|e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Normal
|
|C99 e$B$Ne(B printf e$B$K$Oe(B a e$B$H$$$&;XDj;R$,$"$j$^$9!#e(B
|
| aA The argument is printed in style e$B!Fe(B[-h.hhhe$B!^e(Bpd]e$B!Ge(B where there is
| one digit before the hexadecimal point and the number after
| is equal to the precision specification for the argument;
| when the precision is missing, enough digits are produced to
| convey the argument’s exact double-precision floating-point
| representation. The values e$B!ge(B and NaN are printed as e$B!Fe(Binfe$B!Ge(B
| and e$B!Fe(Bnane$B!Ge(B, respectively.

|e$B$G!"$3$N7A<0$r;H$C$F$$$k$N$G$9$,!"e(BRubye$B$Ne(BString#to_f e$B$G2r<a$7$F$/$l$:Ha$7$/$J$k$N$G!"e(B
|e$B2r<a$G$-$k$h$&$K$7$^$;$s$+!#e(B

e$B:G=*7hDj$G$O$“$j$^$;$s$,!”;d$NH=CG$O0J2<$NDL$j$G$9!#e(B

  • 1.9.2e$B$K$OF3F~$7$J$$!#>-Mh$H$b5qH]$H$$$&$o$1$G$O$J$$!#e(B

e$B$^$:!"$3$N5!G=$G$9$,!“I,MW@-$O$5$[$I9b$/$J$$$N$G!“F3F~$9$k$Ne(B
e$B$G$”$l$Pe(B printf e$B$HF1;~$KF3F~$9$Y$-$@$H;W$$$^$9!#$G$b!”<BAu$,e(B
e$B4V$K9g$o$J$$$N$Ge(B printf e$B$ODs0F$7$J$$$H$$$&$3$H$G$7$?$i!"L5M}e(B
e$B$Ke(B 1.9.2
e$B$KF3F~$;$:$K!"e(Bprintfe$B$N<BAu$bBP$K$9$k$Y$-$@$H;W$$$^e(B
e$B$9!#e(B

e$B$5$F!“;~4|$NLdBj$O$H$b$+$/$H$7$F!”:G=E$J;EMM$,$I$&$"$k$Y$-e(B
e$B$+$K$D$$$F$G$9$,!“e(BRubye$B$K$O!VIbF0>.?tE@I=8=$N2r<a!W$r9T$&5!G=e(B
e$B$OJ#?t$”$j$^$9!#e(B

(a) e$BIbF0>.?tE@%j%F%i%ke(B
(b) Float#to_f
(c) Float()
(d) lib/scanf.rb

e$B$G!“:#2sF3F~8!F$$7$F$$$kI=8=$O%a%=%C%I8F$S=P$7$H%3%s%U%j%/%He(B
e$B$9$k2DG=@-$,$”$k$N$Ge(B (a) e$B$OBP>]$K$7$J$$$H$$$&$N$,%3%s%;%s%5e(B
e$B%9$@$H;W$$$^$9!#;d$b;?@.$7$^$9!#e(B

e$B<!$Ke(B (b) e$B$He(B (c) e$B$G$9$,!"8=:_$Ne(B Float() e$B$He(B to_f
e$B$K$O!"e(B

  • Float()e$B$OI=8=$K87$7$/!"4V0c$C$?I=8=$O@Q6KE*$KNc30$K$9$ke(B
  • to_f e$B$OE,Ev$K2r<a$7!"4V0c$C$?I=8=$K$Oe(B0.0e$B$rJV$9e(B

e$B$H$$$&0c$$$,$"$j$^$9!#$5$i$Ke(B Integer() e$B$He(B to_i
e$B$H$NN`?d$+$i$O!"e(B
e$B!Ve(B0xe$B!W$J$I$N2r<a$Oe(BFloate$B$,9T$$!"e(Bto_fe$B$O9T$o$J$$$H$$$&$3$H$r4|BTe(B
e$B$7$F$b$h$$$N$G$O$J$$$+$H;W$$$^$9!#e(B

e$B$H$9$k$H!“>-Mhe(B %a
e$BI=8=$N2r<a$rF3F~$9$k:]$K$Oe(BFloat()e$B$,$3$N7A<0e(B
e$B$r2r<a$7!“e(Bto_fe$B$O9T$o$J$$$H$$$&$N$,!”<+A3$G$O$J$$$N$+$H;W$$$^e(B
e$B$9!#$b$C$H$b!”$3$l$O;d$N0U8+$H8@$&$@$1$G!“:G=*7hDj$G$O$”$j$^e(B
e$B$;$s$,!#e(B

e$B:G8e$Ke(B (d) scanf e$B$G$9$,!“e(Bprintfe$B$,e(B %a
e$B$r:NMQ$7$?$”$+$D$-$K$O!"e(B
scanf e$B$be(B %a e$B$rF3F~$7$?J}$,$h$$$H;W$$$^$9!#e(B

to_ie$B$de(Bto_fe$B$,%(%i!<$KBP$7$Fe(B 0
e$B$rJV$9$N$O!“8e2y$7$F$$$k;EMM$Ne(B
e$B0l$D$G$9$,!”:#$5$iJQ$($i$l$J$$$G$9$M!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

p.s.
e$B$=$l$O$=$l$H$7$F!“e(B"4._9”.to_f e$B$,e(B 4.9 e$B$J$N$O!"$&!<$s!#e(B

e$B@.@%$G$9!#e(B

2010e$BG/e(B3e$B7ne(B29e$BF|e(B9:08 Yukihiro M.
[email protected]:

|> e$B$Ke(B 1.9.2 e$B$KF3F~$;$:$K!“e(Bprintfe$B$N<BAu$bBP$K$9$k$Y$-$@$H;W$$$^e(B
|> e$B$9!#e(B
|
|missing e$B$r4^$a$?e(B printf e$B$N<BAu$O!“e(B[ruby-dev:40801] e$B$K$”$j$^$9!#e(B
|e$B$N$G!”$3$NE@$K4X$7$F;~4|E*$JLdBj$O$J$$$+$H;W$$$^$9!#e(B

e$B$$!“$=$l$O8+Mn$H$7$F$^$7$?!#$G$b!”@.@%$5$s$O!Ve(Bprintfe$B$Oe(B1.9.3
e$B$^$GBT$D!W$H$$C$7$c$C$F$$$?$h$&$K;W$$$^$9!#;~4|E$JLdBj$O$Je(B
e$B$$$H$9$k$H!"$=$l$O$J$<!)e(B

e$B$“$!!”$=$3$r<u$1$F$$$?$N$G$9$M!"Ev;~$O$b$C$H<BAu$K;~4V$,$+$+$k$H;W$C$?$+$i$G$9!#e(B
e$B<B:]$KI,MW$@$C$?$N$O4X?t0l$D$ND4@0$@$C$?$N$G!"e(B
e$BEZF|$G=*$o$je(B [ruby-dev:40801] e$B$G$NEj9F$K$D$J$,$k$o$1$G$9!#e(B

|> e$B:G8e$Ke(B (d) scanf e$B$G$9$,!“e(Bprintfe$B$,e(B %a e$B$r:NMQ$7$?$”$+$D$-$K$O!"e(B
|> scanf e$B$be(B %a e$B$rF3F~$7$?J}$,$h$$$H;W$$$^$9!#e(B
|
|scanf e$B$N<BAu$Oe(B [ruby-dev:40799] e$B$K<($7$F$$$^$9!#e(B

e$B$3$l$K$D$$$F$b;~4|E*$JLdBj$O$J$$$o$1$G$9$M!#e(B

e$B$O$$!#e(B

|> to_ie$B$de(Bto_fe$B$,%(%i!<$KBP$7$Fe(B 0 e$B$rJV$9$N$O!“8e2y$7$F$$$k;EMM$Ne(B
|> e$B0l$D$G$9$,!”:#$5$iJQ$($i$l$J$$$G$9$M!#e(B
|
|e$B<!$N%A%c%s%9$Oe(B 2.0 e$B$G$9$+$M$'!#e(B

e$B$$$d$!!"8e2y$7$F$$$k$+$i$H$$$C$F8_49@-LdBj$r0B0W$KF3F~$7$A$ce(B
e$B$&$H!"0\9T$NK8$2$K$J$C$A$c$$$^$9$+$i$M$(!#e(B

e$B0JA0e(B [ruby-dev:39851] e$B$Ge(B to_hoge
e$B<~$j$N@0M}$r6D$C$F$$$^$7$?$,!“e(B
e$B$=$NJU$,e(B 2.0 e$B$G$O5DO@$,Mn$ACe$/$@$m$&e(B
(e$B$$$d!“Mn$ACe$$$FM_$7$$e(B) e$B$He(B
e$B;W$C$F$$$^$7$F!”$=$N>l9g$O$=$N%I%5%/%5$KJ6$l$FJQ$($i$l$k$+$J!<$H!#e(B
to_f
e$B$O$=$N$^$^$G!”?7L@<(E*JQ49;X<(%a%=%C%I$@$1JQ$($k$G$b$$$$$N$G$7$g$&$,!#e(B

e$B$($0$A!w%(%9%"%s%I%$!<$G$9e(B

2010e$BG/e(B3e$B7ne(B28e$BF|e(B15:24 NARUSE, Yui [email protected]:

e$BF’$^$($k$H$J$<e(BRubye$B%j%F%i%kI=8=$H$7$F$b;H$($kI=8=7A<0$rLO:w$9$k$3$H$Ke(B
e$B$J$k$N$+$,$h$/$o$+$j$^$;$s!#e(B

e$B?dB,$9$k$K!“A0CJ$H$OFHN)$K!”$h$j$h$$7A<0$,8=$l$?:]$K:#2s$N7A<0$H$N8_49@-$Ke(B
e$BG{$i$l$k$3$H$r7|G0$7$F$$$k$N$G$O$J$$$+$H;W$$$^$9!#e(B

e$B8_49@-!“$”$k$$$OF1$8MQES$K#2$D$N7A<0$,JBN)$9$k;v$K$h$k:.Mp!&!&$G$9$M!#e(B

e$B$^$?!"%j%F%i%k$K$3$@$o$j$r;}$C$?GX7J$H$7$F$O!"e(B
e$B!V%o%s%i%$%J!<$G$b<j7Z$K;H$$$?$$!We(B
e$B$H8@$&0U<1$,6/$$$G$9!#e(B

e$B<B:]!"e(B%a e$B$rCN$k$?$a$Ke(B printf(1) e$B$Ge(B

% printf “%a\n” 3.1425926536
0x1.924079dfee515p+1
% printf “%1.20e\n” 0x0.924079dfee515p+1
1.14259265359999995226e+00

e$B$H<B:]$K;n$7M}2r$,Aa$^$C$?$+$i$G$9!#e(B

e$B!Ve(BRuby e$B$N%a%=%C%I$,e(B %a
e$B7A<0$rFI$_=q$-=PMh$k$h$&$K$J$k$3$H!We(B
e$B$H$O!"I,$:$7$bBPN)35G0$G$O$J$$$N$G!V%j%F%i%kI=8=$NLO:w!W$H$Oe(B
e$BFHN)$7$F9M$($k$Y$-$@$m$&$H:#$O9M$($F$$$^$9!#e(B

2.0 e$B$G%a%=%C%I$O0z?t$J$7$G$be(B () e$BI,?$K$J$l$P>WFM$Oe(B
e$B2sHr=PMh$k$h$&$J5$$,$7$^$9$,!"?<9o$J8_49@-LdBj$K$J$j$^$9$M!#e(B

e$B!!$($0$Ae(B

2010e$BG/e(B3e$B7ne(B27e$BF|e(B20:26 EGUCHI Osamu [email protected]:

e$B%j%F%i%kI=8=$K$O!J$=$N$^$^$N!Ke(BaA e$BI=8=$OF3F~IT2DG=$H$$$&E@$K$Oe(B
e$B0[O@$O$J$$$H$$$&6&DLG’<1$rF’$^$($?>e$G!#!#e(B

e$B$=$&$G$9$+$Me(B?

e$B$?$7$+$KHs8_49$G$O$"$j$^$9$,!"IT2DG=$H$$$&$[$I$G$b$J$$5$$,$7$^$9!#e(B

0x1.badp+0 e$B$Oe(B Float e$B$N%j%F%i%k$H$$$&$3$H$K$7$F!“e(B
Integer#badp e$B$r8F$S=P$7$?$1$l$Pe(B
(0x1).badp+0
e$B$H=q$1$P$$$$$o$1$G$9$+$i!”$J$K$+$,L5M}$K$J$k$o$1$G$O$"$j$^$;$s!#e(B

e$B2r<a$,JQ2=$9$k$N$Oe(B 16e$B?J@0?t%j%F%i%k$Ke(B [a-f][0-9a-f]*p?
e$B$H$$$&%a%=%C%I$r8F$s$Ge(B
e$B$$$k%1!<%9$G$9$,!"B?$$$G$9$+$M!)e(B
e$B;X?tIt$Ne(B p e$B$,I,?$J$i$5$i$K@)8B$G$-$k$+$J!#e(B

e$B$=$&$$$($P!"8=:_$G$be(B 1 e$B$H$$$&%a%=%C%I$ODj5A$G$-$^$9$,!“e(B
0.1 e$B$H$$$&$N$Oe(B Float
e$B$H$7$F2r<a$5$l!”%a%=%C%I8F$S=P$7$K$O$J$i$J$$$G$9$M!#e(B

% ruby -e ’
class Integer
define_method(“1”) { :hahaha }
end
p 0.1
p 0.send(“1”)

0.1
:hahaha

2010e$BG/e(B3e$B7ne(B29e$BF|e(B10:50 Tanaka A. [email protected]:

e$B$?$7$+$KHs8_49$G$O$"$j$^$9$,!"IT2DG=$H$$$&$[$I$G$b$J$$5$$,$7$^$9!#e(B

0x1.badp+0 e$B$Oe(B Float e$B$N%j%F%i%k$H$$$&$3$H$K$7$F!“e(B
Integer#badp e$B$r8F$S=P$7$?$1$l$Pe(B
(0x1).badp+0 e$B$H=q$1$P$$$$$o$1$G$9$+$i!”$J$K$+$,L5M}$K$J$k$o$1$G$O$"$j$^$;$s!#e(B

e$B2r<a$,JQ2=$9$k$N$Oe(B 16e$B?J@0?t%j%F%i%k$Ke(B [a-f][0-9a-f]*p? e$B$H$$$&%a%=%C%I$r8F$s$Ge(B
e$B$$$k%1!<%9$G$9$,!"B?$$$G$9$+$M!)e(B
e$B;X?tIt$Ne(B p e$B$,I,?$J$i$5$i$K@)8B$G$-$k$+$J!#e(B

e$B$5$i$K9M$($k$H!"$3$N%a%=%C%I$OEvA3e(B Integer
e$B$KBP$7$F8F$P$l$k$o$1$G!"e(B
e$B8=:$N$H$3$m!"$=$N$h$&$J%a%=%C%I$OB8:$7$J$$$h$&$G$9!#e(B

% ./ruby -e ‘p Integer.instance_methods.grep(/\A[0-9a-fA-F_]*p?\z/)’
[]

e$B$H$9$k$H!“Hs8_49@-$,H/@8$9$k$N$O!”$@$l$+$,e(B Integer
e$B$K%a%=%C%I$rDI2C$7$Fe(B
e$B;H$C$F$$$F!“$+$D!”$=$NL>A0$,e(B [a-f][0-9a-f]*p?
e$B$H$$$&%Q%?!<%s$K9gCW$7$F$$$k>l9ge(B
e$B$H$$$&$3$H$K$J$j$^$9!#e(B

e$B$"$s$^$jLdBj$J$$5$$,$9$k$J$!!#e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:40820] Re: [Feature #2969] String#to_f
e$B$,e(B -h.hhhe$B!^e(Bpd e$B$r2r<a$G$-$k$h$&$Ke(B”
on Mon, 29 Mar 2010 09:33:27 +0900, “NARUSE, Yui”
[email protected] writes:

|> e$B$$!“$=$l$O8+Mn$H$7$F$^$7$?!#$G$b!”@.@%$5$s$O!Ve(Bprintfe$B$Oe(B1.9.3
|> e$B$^$GBT$D!W$H$$C$7$c$C$F$$$?$h$&$K;W$$$^$9!#;~4|E$JLdBj$O$Je(B
|> e$B$$$H$9$k$H!“$=$l$O$J$<!)e(B
|
|e$B$”$!!"$=$3$r<u$1$F$$$?$N$G$9$M!"Ev;~$O$b$C$H<BAu$K;~4V$,$+$+$k$H;W$C$?$+$i$G$9!#e(B
|e$B<B:]$KI,MW$@$C$?$N$O4X?t0l$D$ND4@0$@$C$?$N$G!"e(B
|e$BEZF|$G=*$o$je(B [ruby-dev:40801] e$B$G$NEj9F$K$D$J$,$k$o$1$G$9!#e(B

e$B;~7ONs$r8+<:$C$F$$$?$h$&$G$9!#<BAu$,$“$k$H$9$k$H!”;D$k$Oe(B

  • e$B;d$,Ds<($7$?;EMM$GLdBj$J$$$+e(B
  • e$B$=$l$Oe(B 1.9.2 e$B$K4^$a$k$+$I$&$+e(B

e$B$G$9$M!#A0<T$O<B:]$KMxMQ$9$k$3$H$r9M$($F$*$i$l$kJ}$,H=CG$7$Fe(B
e$B$/$@$5$$!#8e<T$Oe(B Yuguie$B$5$s$Ne(B issue e$B$G$9$M!#e(B

|e$B0JA0e(B [ruby-dev:39851] e$B$Ge(B to_hoge e$B<~$j$N@0M}$r6D$C$F$$$^$7$?$,!“e(B
|e$B$=$NJU$,e(B 2.0 e$B$G$O5DO@$,Mn$ACe$/$@$m$&e(B (e$B$$$d!“Mn$ACe$$$FM_$7$$e(B) e$B$He(B
|e$B;W$C$F$$$^$7$F!”$=$N>l9g$O$=$N%I%5%/%5$KJ6$l$FJQ$($i$l$k$+$J!<$H!#e(B
|to_f e$B$O$=$N$^$^$G!”?7L@<(E*JQ49;X<(%a%=%C%I$@$1JQ$($k$G$b$$$$$N$G$7$g$&$,!#e(B

e$B$=$&$&$^$/$$$/$+$J$"!#9M$($5$;$F$/$@$5$$!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

e$B$($0$A!w%(%9%"%s%I%$!<$G$9e(B

2010e$BG/e(B3e$B7ne(B29e$BF|e(B10:50 Tanaka A. [email protected]:

2010e$BG/e(B3e$B7ne(B27e$BF|e(B20:26 EGUCHI Osamu [email protected]:

e$B%j%F%i%kI=8=$K$O!J$=$N$^$^$N!Ke(BaA e$BI=8=$OF3F~IT2DG=$H$$$&E@$K$Oe(B
e$B0[O@$O$J$$$H$$$&6&DLG’<1$rF’$^$($?>e$G!#!#e(B

e$B$=$&$G$9$+$Me(B?
e$B$?$7$+$KHs8_49$G$O$"$j$^$9$,!"IT2DG=$H$$$&$[$I$G$b$J$$5$$,$7$^$9!#e(B

e$B!VHs8_49@-$r5vMF$7$J$1$l$PF3F~IT2DG=!W$H8@$&0UL#$G$9!#e(B

0x1.badp+0 e$B$Oe(B Float e$B$N%j%F%i%k$H$$$&$3$H$K$7$F!“e(B
Integer#badp e$B$r8F$S=P$7$?$1$l$Pe(B
(0x1).badp+0 e$B$H=q$1$P$$$$$o$1$G$9$+$i!”$J$K$+$,L5M}$K$J$k$o$1$G$O$"$j$^$;$s!#e(B

e$BJL2r$H$7$F!"e(B 0x1. badp+0 e$B$G$b2sHr$G$-$^$9$M!#e(B
e$B2?$l$K$7$F$b>WFM2sHr$OI,MW$G$9!#e(B

e$B2r<a$,JQ2=$9$k$N$Oe(B 16e$B?J@0?t%j%F%i%k$Ke(B [a-f][0-9a-f]*p? e$B$H$$$&%a%=%C%I$r8F$s$Ge(B
e$B$$$k%1!<%9$G$9$,!"B?$$$G$9$+$M!)e(B

e$BB?$/$O$J$$$HA[A|$7$^$9$,!“3’L5$G$O$J$$$G$9$M!#e(B
e$B$=$N>l9g!”>WFM$KAx6x$7$?%W%m%0%i%^$,2?$,5/$3$C$F$$$k$N$+$re(B
e$B@5$7$/GD0.$9$k$N$,$+$J$j:$Fq$@$H;W$$$^$9!#e(B
e$BFC$K!"e(BaA e$B$JIbF0>.?tE@?t=q<0$NB8:_$rCN$i$J$$$H>l9g$O!#e(B
e$BE,@Z$J%(%i!<%a%C%;!<%8$Ge(B

e$B;X?tIt$Ne(B p e$B$,I,?$J$i$5$i$K@)8B$G$-$k$+$J!#e(B

e$B=PMh$l$P$3$N@)8B$O$J$$$[$&$,NI$$$H;W$$$^$9$,!“e(B
e$B47$l$NLdBj$G$b$”$k$N$G8!F$$KCM$9$k$H;W$$$^$9!#e(B

0.1
:hahaha

e$B$3$l$OAG$G%P%0$J$s$8$c$J$$$+$H;W$$$^$9!#e(B
e$B%7%s%%kL>$H$7$FM-8z$G$J$$J8;zNs$O%(%i!<$K$9$Y$-!)e(B

e$B$($0$Ae(B