[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