[MacRuby-devel] [MacRuby] #159: "%d" with large integer argument gives conversion error

MacRuby ruby-noreply at macosforge.org
Fri Dec 11 18:03:51 PST 2009


#159: "%d" with large integer argument gives conversion error
---------------------------------+------------------------------------------
 Reporter:  jamis@…              |       Owner:  lsansonetti@…        
     Type:  defect               |      Status:  new                  
 Priority:  major                |   Milestone:                       
Component:  MacRuby              |    Keywords:                       
---------------------------------+------------------------------------------

Comment(by emoy@…):

 Part 2 of 3

 So I wondered if it was possible to port the ruby 1.9.1 version of sprintf
 to MacRuby.  I decided to remove all the multibyte and encoding stuff, and
 just convert the format string to UTF-16, so I didn't have to worry about
 encoding.  Then I just used a NSMutableString to accumulate the output.
 After dealing with padding and floating point conversion (which I do in
 ASCII and then append to the NSMutableString), and merging some code from
 the previous sprintf.cpp, it finally compiled.  Then more bug diagnosis
 and iteration, and I finally got it to produce the same output as ruby
 1.9.1, in all 148901 test cases (well, actually there was one difference,
 but that was due to String#inspect and String at dump, and is a different
 issue).

 As it always seems to turn out, there was yet-another issue that I had to
 fix.  Floating point conversion seemed to produce slightly different
 numbers than ruby 1.9 (and 1.8).  This turned out to be due to the fact
 that in MacRuby, only Fixfloat format, so the last two bits of the value
 are stomped on.  The struct RFloat structure that wraps floating point
 numbers in ruby 1.x, isn't being used.

 So I changed the code to use Fixfloat if it doesn't use those last two
 bits, otherwise switch to struct RFloat (in 32-bit mode, it is worse,
 since Fixfloat uses 32-bit floating point numbers, which seriously limits
 precision, so I always use struct RFloat in 32-bit).  Then I run into a
 problem in the compiler; it doesn't know how to deal with the struct
 RFloat when creating floating point literals.  So I add code to numeric.c,
 that converts a floating point number to a string (using the %a hex format
 of the C-based sprintf, which is a exact translation to and from).  Then I
 duplicate the Bignum code literal code, and change it to do floating
 point.  The compiler is now happy.

 I also looked for occurrences of DBL2FIXFLOAT and FIXFLOAT2DBL, and where
 appropriate, replaced them with DOUBLE2NUM and RFLOAT_VALUE, respectively.
 FIXFLOAT_P(x) gets replaced with TYPE(x) == T_FLOAT.  marshal.c needed to
 know about the struct RFloat instances, and even rb_type (aka TYPE())
 needed to know about struct RFloat (and I added T_BIGNUM support, which
 was missing).

 '''Note: I have found a few other places in the compiler that assume
 Fixfloat, and stomps on those lower two bits.  What it should do is call
 the appropriate rb_float_* routines, but I'm new to LLVM, so I haven't
 figure out how to change it yet.  If anyone has any pointers (other than
 RTFM, which I'm now doing), I'd be appreciative.'''

 (Continued...)

-- 
Ticket URL: <http://www.macruby.org/trac/ticket/159#comment:4>
MacRuby <http://macruby.org/>



More information about the MacRuby-devel mailing list