Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   ***** BEGIN LICENSE BLOCK *****
   * Version: CPL 1.0/GPL 2.0/LGPL 2.1
   *
   * The contents of this file are subject to the Common Public
   * License Version 1.0 (the "License"); you may not use this file
   * except in compliance with the License. You may obtain a copy of
   * the License at http://www.eclipse.org/legal/cpl-v10.html
   *
  * Software distributed under the License is distributed on an "AS
  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  * implied. See the License for the specific language governing
  * rights and limitations under the License.
  *
  * Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
  * Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
  * Copyright (C) 2002 Don Schwartz <schwardo@users.sourceforge.net>
  * Copyright (C) 2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
  * Copyright (C) 2002-2004 Thomas E Enebo <enebo@acm.org>
  * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
  * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
  * Copyright (C) 2004 Charles O Nutter <headius@headius.com>
  * Copyright (C) 2006 Miguel Covarrubias <mlcovarrubias@gmail.com>
  * Copyright (C) 2008 Joseph LaFata <joe@quibb.org>
  * 
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the CPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the CPL, the GPL or the LGPL.
  ***** END LICENSE BLOCK *****/
 package org.jruby;
 
 import static org.jruby.util.Numeric.f_abs;
 import static org.jruby.util.Numeric.f_add;
 import static org.jruby.util.Numeric.f_expt;
 import static org.jruby.util.Numeric.f_lshift;
 import static org.jruby.util.Numeric.f_mul;
 import static org.jruby.util.Numeric.f_negate;
 import static org.jruby.util.Numeric.f_negative_p;
 import static org.jruby.util.Numeric.f_sub;
 import static org.jruby.util.Numeric.f_to_r;
 import static org.jruby.util.Numeric.f_zero_p;
 import static org.jruby.util.Numeric.frexp;
 import static org.jruby.util.Numeric.ldexp;
 import static org.jruby.util.Numeric.nurat_rationalize_internal;
 
 
 
 import static org.jruby.javasupport.util.RuntimeHelpers.invokedynamic;
 import static org.jruby.runtime.invokedynamic.MethodNames.OP_EQUAL;

A representation of a float object
 
 @JRubyClass(name="Float", parent="Numeric", include="Precision")
 public class RubyFloat extends RubyNumeric {
     public static final int ROUNDS = 1;
     public static final int RADIX = 2;
     public static final int MANT_DIG = 53;
     public static final int DIG = 15;
     public static final int MIN_EXP = -1021;
     public static final int MAX_EXP = 1024;
     public static final int MAX_10_EXP = 308;
     public static final int MIN_10_EXP = -307;
     public static final double EPSILON = 2.2204460492503131e-16;
     public static final double INFINITY = .;
     public static final double NAN = .;
 
     public static RubyClass createFloatClass(Ruby runtime) {
         RubyClass floatc = runtime.defineClass("Float"runtime.getNumeric(), .);
         runtime.setFloat(floatc);
 
         floatc.index = .;
         floatc.setReifiedClass(RubyFloat.class);
         
        floatc.kindOf = new RubyModule.KindOf() {
            @Override
            public boolean isKindOf(IRubyObject objRubyModule type) {
                return obj instanceof RubyFloat;
            }
        };        
        floatc.getSingletonClass().undefineMethod("new");
        if (!runtime.is1_9()) {
            floatc.includeModule(runtime.getPrecision());
        }
        // Java Doubles are 64 bit long:            
        floatc.defineConstant("ROUNDS", RubyFixnum.newFixnum(runtime));
        floatc.defineConstant("RADIX", RubyFixnum.newFixnum(runtime));
        floatc.defineConstant("MANT_DIG", RubyFixnum.newFixnum(runtime));
        floatc.defineConstant("DIG", RubyFixnum.newFixnum(runtime));
        // Double.MAX_EXPONENT since Java 1.6
        floatc.defineConstant("MIN_EXP", RubyFixnum.newFixnum(runtime));
        // Double.MAX_EXPONENT since Java 1.6            
        floatc.defineConstant("MAX_EXP", RubyFixnum.newFixnum(runtime));
        floatc.defineConstant("MIN_10_EXP", RubyFixnum.newFixnum(runtime));
        floatc.defineConstant("MAX_10_EXP", RubyFixnum.newFixnum(runtime));
        floatc.defineConstant("MIN", RubyFloat.newFloat(runtime.));
        floatc.defineConstant("MAX", RubyFloat.newFloat(runtime.));
        floatc.defineConstant("EPSILON", RubyFloat.newFloat(runtime));
        if (runtime.is1_9()) {
            floatc.defineConstant("INFINITY", RubyFloat.newFloat(runtime));
            floatc.defineConstant("NAN", RubyFloat.newFloat(runtime));
        }
        floatc.defineAnnotatedMethods(RubyFloat.class);
        return floatc;
    }
    private final double value;
    
    @Override
    public int getNativeTypeIndex() {
        return .;
    }
    public RubyFloat(Ruby runtime) {
        this(runtime, 0.0);
    }
    public RubyFloat(Ruby runtimedouble value) {
        super(runtime.getFloat());
        this. = value;
    }
    @Override
    public Class<?> getJavaClass() {
        return double.class;
    }

    
Getter for property value.

Returns:
Value of property value.
    public double getValue() {
        return this.;
    }
    @Override
    public double getDoubleValue() {
        return ;
    }
    @Override
    public long getLongValue() {
        return (long;
    }
    @Override
    public BigInteger getBigIntegerValue() {
        return BigInteger.valueOf((long));
    }
    
    @Override
    public RubyFloat convertToFloat() {
    	return this;
    }
    protected int compareValue(RubyNumeric other) {
        double otherVal = other.getDoubleValue();
        return getValue() > otherVal ? 1 : getValue() < otherVal ? -1 : 0;
    }
    public static RubyFloat newFloat(Ruby runtimedouble value) {
        return new RubyFloat(runtimevalue);
    }
    /*  ================
     *  Instance Methods
     *  ================ 
     */

    
rb_flo_induced_from
    @JRubyMethod(name = "induced_from", meta = true, compat = .)
    public static IRubyObject induced_from(ThreadContext contextIRubyObject recvIRubyObject number) {
        if (number instanceof RubyFixnum || number instanceof RubyBignum || number instanceof RubyRational) {
            return number.callMethod(context"to_f");
        } else if (number instanceof RubyFloat) {
            return number;
        }
        throw recv.getRuntime().newTypeError(
                "failed to convert " + number.getMetaClass() + " into Float");
    }
    private final static DecimalFormat FORMAT = new DecimalFormat("##############0.0##############",
            new DecimalFormatSymbols(.));

    
flo_to_s
    @JRubyMethod(name = "to_s")
    @Override
    public IRubyObject to_s() {
        Ruby runtime = getRuntime();
        if (Double.isInfinite()) return RubyString.newString(runtime < 0 ? "-Infinity" : "Infinity");
        if (Double.isNaN()) return RubyString.newString(runtime"NaN");
        ByteList buf = new ByteList();
        // Under 1.9, use full-precision float formatting (JRUBY-4846).
        // Double-precision can represent around 16 decimal digits;
        // we use 20 to ensure full representation.
        if (runtime.is1_9()) {
            Sprintf.sprintf(buf."%#.20g"this);
        } else {
            Sprintf.sprintf(buf."%#.15g"this);
        }
        int e = buf.indexOf('e');
        if (e == -1) e = buf.getRealSize();
        ASCIIEncoding ascii = .
        if (!ascii.isDigit(buf.get(e - 1))) {
            buf.setRealSize(0);
            Sprintf.sprintf(buf."%#.14e"this);
            e = buf.indexOf('e');
            if (e == -1) e = buf.getRealSize();
        }
        int p = e;
        while (buf.get(p - 1) == '0' && ascii.isDigit(buf.get(p - 2))) p--;
        System.arraycopy(buf.getUnsafeBytes(), ebuf.getUnsafeBytes(), pbuf.getRealSize() - e);
        buf.setRealSize(p + buf.getRealSize() - e);
        if (getRuntime().is1_9()) buf.setEncoding(.);
        return runtime.newString(buf);
    }

    
flo_coerce
    @JRubyMethod(name = "coerce", required = 1)
    @Override
    public IRubyObject coerce(IRubyObject other) {
        return getRuntime().newArray(RubyKernel.new_float(thisother), this);
    }

    
flo_uminus
    @JRubyMethod(name = "-@")
    public IRubyObject op_uminus() {
        return RubyFloat.newFloat(getRuntime(), -);
    }

    
flo_plus
    @JRubyMethod(name = "+", required = 1)
    public IRubyObject op_plus(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            return RubyFloat.newFloat(getRuntime(),  + ((RubyNumericother).getDoubleValue());
        default:
            return coerceBin(context"+"other);
        }
    }
    public IRubyObject op_plus(ThreadContext contextdouble other) {
        return RubyFloat.newFloat(getRuntime(),  + other);
    }

    
flo_minus
    @JRubyMethod(name = "-", required = 1)
    public IRubyObject op_minus(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            return RubyFloat.newFloat(getRuntime(),  - ((RubyNumericother).getDoubleValue());
        default:
            return coerceBin(context"-"other);
        }
    }
    public IRubyObject op_minus(ThreadContext contextdouble other) {
        return RubyFloat.newFloat(getRuntime(),  - other);
    }

    
flo_mul
    @JRubyMethod(name = "*", required = 1)
    public IRubyObject op_mul(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            return RubyFloat.newFloat(
                    getRuntime(),  * ((RubyNumericother).getDoubleValue());
        default:
            return coerceBin(context"*"other);
        }
    }
    public IRubyObject op_mul(ThreadContext contextdouble other) {
        return RubyFloat.newFloat(
                getRuntime(),  * other);
    }
    
    
flo_div
    @JRubyMethod(name = "/", required = 1)
    public IRubyObject op_fdiv(ThreadContext contextIRubyObject other) { // don't override Numeric#div !
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            return RubyFloat.newFloat(getRuntime(),  / ((RubyNumericother).getDoubleValue());
        default:
            return coerceBin(context"/"other);
        }
    }
    public IRubyObject op_fdiv(ThreadContext contextdouble other) { // don't override Numeric#div !
        return RubyFloat.newFloat(getRuntime(),  / other);
    }

    
flo_quo
    @JRubyMethod(name = "quo", compat = .)
        public IRubyObject magnitude(ThreadContext contextIRubyObject other) {
        return callMethod(context"/"other);
    }

    
flo_mod
    @JRubyMethod(name = {"%""modulo"}, required = 1, compat = .)
    public IRubyObject op_mod(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            double y = ((RubyNumericother).getDoubleValue();
            return op_mod(contexty);
        default:
            return coerceBin(context"%"other);
        }
    }
    public IRubyObject op_mod(ThreadContext contextdouble other) {
        // Modelled after c ruby implementation (java /,% not same as ruby)
        double x = ;
        double mod = Math.IEEEremainder(xother);
        if (other * mod < 0) {
            mod += other;
        }
        return RubyFloat.newFloat(getRuntime(), mod);
    }

    
flo_mod
    @JRubyMethod(name = {"%""modulo"}, required = 1, compat = .)
    public IRubyObject op_mod19(ThreadContext contextIRubyObject other) {
        if (!other.isNil() && other instanceof RubyNumeric
            && ((RubyNumeric)other).getDoubleValue() == 0) {
            throw context.runtime.newZeroDivisionError();
        }
        return op_mod(contextother);
    }

    
flo_divmod
    @JRubyMethod(name = "divmod", required = 1, compat = .)
    @Override
    public IRubyObject divmod(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            double y = ((RubyNumericother).getDoubleValue();
            double x = ;
            double mod = Math.IEEEremainder(xy);
            // MRI behavior:
            if (Double.isNaN(mod)) {
                throw getRuntime().newFloatDomainError("NaN");
            }
            double div = Math.floor(x / y);
            if (y * mod < 0) {
                mod += y;
            }
            final Ruby runtime = getRuntime();
            IRubyObject car = dbl2num(runtimediv);
            RubyFloat cdr = RubyFloat.newFloat(runtimemod);
            return RubyArray.newArray(runtimecarcdr);
        default:
            return coerceBin(context"divmod"other);
        }
    }
    
    
flo_divmod
    @JRubyMethod(name = "divmod", required = 1, compat = .)
    public IRubyObject divmod19(ThreadContext contextIRubyObject other) {
        if (!other.isNil() && other instanceof RubyNumeric
            && ((RubyNumeric)other).getDoubleValue() == 0) {
            throw context.runtime.newZeroDivisionError();
        }
        return divmod(contextother);
    }
    
    
flo_pow
    @JRubyMethod(name = "**", required = 1)
    public IRubyObject op_pow(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            return RubyFloat.newFloat(getRuntime(), Math.pow(, ((RubyNumericother)
                    .getDoubleValue()));
        default:
            return coerceBin(context"**"other);
        }
    }
    public IRubyObject op_pow(ThreadContext contextdouble other) {
        return RubyFloat.newFloat(getRuntime(), Math.pow(other));
    }
    
    @JRubyMethod(name = "**", required = 1, compat = .)
    public IRubyObject op_pow19(ThreadContext contextIRubyObject other) {
        double d_other = ((RubyNumericother).getDoubleValue();
        if ( < 0 && (d_other != Math.round(d_other))) {
            return RubyComplex.newComplexRaw(getRuntime(), this).callMethod(context"**"other);
        } else {
            return op_pow(contextother);
        }
    }

    
flo_eq
    @JRubyMethod(name = "==", required = 1)
    @Override
    public IRubyObject op_equal(ThreadContext contextIRubyObject other) {
        if (Double.isNaN()) {
            return getRuntime().getFalse();
        }
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            return RubyBoolean.newBoolean(getRuntime(),  == ((RubyNumericother)
                    .getDoubleValue());
        default:
            // Numeric.equal            
            return super.op_num_equal(contextother);
        }
    }
    public IRubyObject op_equal(ThreadContext contextdouble other) {
        if (Double.isNaN()) {
            return getRuntime().getFalse();
        }
        return RubyBoolean.newBoolean(getRuntime(),  == other);
    }
    public boolean fastEqual(RubyFloat other) {
        if (Double.isNaN()) {
            return false;
        }
        return  == ((RubyFloat)other).;
    }
    @Override
    public final int compareTo(IRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            return Double.compare(, ((RubyNumericother).getDoubleValue());
        default:
            return (int)coerceCmp(getRuntime().getCurrentContext(), "<=>"other).convertToInteger().getLongValue();
        }
    }

    
flo_cmp
    @JRubyMethod(name = "<=>", required = 1)
    public IRubyObject op_cmp(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
            if (Double.isInfinite()) {
                return  > 0.0 ? RubyFixnum.one(getRuntime()) : RubyFixnum.minus_one(getRuntime());
            }
        case .:
            double b = ((RubyNumericother).getDoubleValue();
            return dbl_cmp(getRuntime(), b);
        default:
            return coerceCmp(context"<=>"other);
        }
    }
    public IRubyObject op_cmp(ThreadContext contextdouble other) {
        return dbl_cmp(getRuntime(), other);
    }

    
flo_gt
    @JRubyMethod(name = ">", required = 1)
    public IRubyObject op_gt(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            double b = ((RubyNumericother).getDoubleValue();
            return RubyBoolean.newBoolean(getRuntime(), !Double.isNaN(b) &&  > b);
        default:
            return coerceRelOp(context">"other);
        }
    }
    public IRubyObject op_gt(ThreadContext contextdouble other) {
        return RubyBoolean.newBoolean(getRuntime(), !Double.isNaN(other) &&  > other);
    }

    
flo_ge
    @JRubyMethod(name = ">=", required = 1)
    public IRubyObject op_ge(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            double b = ((RubyNumericother).getDoubleValue();
            return RubyBoolean.newBoolean(getRuntime(), !Double.isNaN(b) &&  >= b);
        default:
            return coerceRelOp(context">="other);
        }
    }
    public IRubyObject op_ge(ThreadContext contextdouble other) {
        return RubyBoolean.newBoolean(getRuntime(), !Double.isNaN(other) &&  >= other);
    }

    
flo_lt
    @JRubyMethod(name = "<", required = 1)
    public IRubyObject op_lt(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            double b = ((RubyNumericother).getDoubleValue();
            return RubyBoolean.newBoolean(getRuntime(), !Double.isNaN(b) &&  < b);
        default:
            return coerceRelOp(context"<"other);
		}
    }
    public IRubyObject op_lt(ThreadContext contextdouble other) {
        return RubyBoolean.newBoolean(getRuntime(), !Double.isNaN(other) &&  < other);
    }

    
flo_le
    @JRubyMethod(name = "<=", required = 1)
    public IRubyObject op_le(ThreadContext contextIRubyObject other) {
        switch (other.getMetaClass().) {
        case .:
        case .:
        case .:
            double b = ((RubyNumericother).getDoubleValue();
            return RubyBoolean.newBoolean(getRuntime(), !Double.isNaN(b) &&  <= b);
        default:
            return coerceRelOp(context"<="other);
		}
	}
    public IRubyObject op_le(ThreadContext contextdouble other) {
        return RubyBoolean.newBoolean(getRuntime(), !Double.isNaN(other) &&  <= other);
	}

    
flo_eql
    @JRubyMethod(name = "eql?", required = 1)
    @Override
    public IRubyObject eql_p(IRubyObject other) {
        if (other instanceof RubyFloat) {
            double b = ((RubyFloatother).;
            if (Double.isNaN() || Double.isNaN(b)) {
                return getRuntime().getFalse();
            }
            if ( == b) {
                return getRuntime().getTrue();
            }
        }
        return getRuntime().getFalse();
    }

    
flo_hash
    @JRubyMethod(name = "hash")
    @Override
    public RubyFixnum hash() {
        return getRuntime().newFixnum(hashCode());
    }
    @Override
    public final int hashCode() {
        long l = Double.doubleToLongBits();
        return (int)(l ^ l >>> 32);
    }    

    
flo_fo
    @JRubyMethod(name = "to_f")
    public IRubyObject to_f() {
        return this;
    }

    
flo_abs
    @JRubyMethod(name = "abs")
    @Override
    public IRubyObject abs(ThreadContext context) {
        if (Double.doubleToLongBits() < 0) {
            return RubyFloat.newFloat(context.runtime, Math.abs());
        }
        return this;
    }

    
flo_abs/1.9
    @JRubyMethod(name = "magnitude", compat = .)
    @Override
    public IRubyObject magnitude(ThreadContext context) {
        return abs(context);
    }

    
flo_zero_p
    @JRubyMethod(name = "zero?")
    public IRubyObject zero_p() {
        return RubyBoolean.newBoolean(getRuntime(),  == 0.0);
    }

    
flo_truncate
    @JRubyMethod(name = {"truncate""to_i""to_int"})
    @Override
    public IRubyObject truncate() {
        double f = ;
        if (f > 0.0) f = Math.floor(f);
        if (f < 0.0) f = Math.ceil(f);
        return dbl2num(getRuntime(), f);
    }

    
flo_numerator
    @JRubyMethod(name = "numerator", compat = .)
    @Override
    public IRubyObject numerator(ThreadContext context) {
        if (Double.isInfinite() || Double.isNaN()) return this;
        return super.numerator(context);
    }

    
flo_denominator
    @JRubyMethod(name = "denominator", compat = .)
    @Override
    public IRubyObject denominator(ThreadContext context) {
        if (Double.isInfinite() || Double.isNaN()) {
            return RubyFixnum.one(context.runtime);
        }
        return super.denominator(context);
    }

    
float_to_r, float_decode
    static final int DBL_MANT_DIG = 53;
    static final int FLT_RADIX = 2;
    @JRubyMethod(name = "to_r", compat = .)
    public IRubyObject to_r(ThreadContext context) {
        long[]exp = new long[1]; 
        double f = frexp(exp);
        f = ldexp(f);
        long n = exp[0] - ;
        Ruby runtime = context.runtime;
        IRubyObject rf = RubyNumeric.dbl2num(runtimef);
        IRubyObject rn = RubyFixnum.newFixnum(runtimen);
        return f_mul(contextrff_expt(context, RubyFixnum.newFixnum(runtime), rn));
    }

    
float_rationalize
    @JRubyMethod(name = "rationalize", optional = 1, compat = .)
    public IRubyObject rationalize(ThreadContext contextIRubyObject[] args) {
        if (f_negative_p(contextthis))
            return f_negate(context, ((RubyFloatf_abs(contextthis)).rationalize(contextargs));
        Ruby runtime = context.runtime;
        RubyFixnum one = RubyFixnum.one(runtime);
        RubyFixnum two = RubyFixnum.two(runtime);
        IRubyObject epsab;
        if (args.length != 0) {
            eps = f_abs(contextargs[0]);
            a = f_sub(contextthiseps);
            b = f_add(contextthiseps);
        } else {
            long[] exp = new long[1];
            double f = frexp(exp);
            f = ldexp(f);
            long n = exp[0] - ;
            IRubyObject rf = RubyNumeric.dbl2num(runtimef);
            IRubyObject rn = RubyFixnum.newFixnum(runtimen);
            if (f_zero_p(contextrf) || !(f_negative_p(contextrn) || f_zero_p(contextrn)))
                return RubyRational.newRationalRaw(runtimef_lshift(context,rf,rn));
            a = RubyRational.newRationalRaw(runtime,
                    f_sub(context,f_mul(contexttworf),one),
                    f_lshift(contextonef_sub(context,one,rn)));
            b = RubyRational.newRationalRaw(runtime,
                    f_add(context,f_mul(contexttworf),one),
                    f_lshift(contextonef_sub(context,one,rn)));
        }
        if (invokedynamic(contextab).isTrue()) return f_to_r(contextthis);
        IRubyObject[] ary = new IRubyObject[2];
        ary[0] = a;
        ary[1] = b;
        IRubyObject[] ans = nurat_rationalize_internal(contextary);
        return RubyRational.newRationalRaw(runtimeans[0], ans[1]);
    }

    
floor
    @JRubyMethod(name = "floor")
    @Override
    public IRubyObject floor() {
        return dbl2num(getRuntime(), Math.floor());
    }

    
flo_ceil
    @JRubyMethod(name = "ceil")
    @Override
    public IRubyObject ceil() {
        return dbl2num(getRuntime(), Math.ceil());
    }

    
flo_round
    @JRubyMethod(name = "round")
    @Override
    public IRubyObject round() {
        return dbl2num(getRuntime(), val2dbl());
    }
    
    @JRubyMethod(name = "round", optional = 1, compat = .)
    public IRubyObject round(ThreadContext contextIRubyObject[] args) {
        if (args.length == 0) return round();
        double digits = num2dbl(args[0]);
        double magnifier = Math.pow(10.0, Math.abs(digits));
        double number = ;
        
        if (Double.isInfinite(magnifier)) {
            if (digits < 0) number = 0;
        } else {
            if (digits < 0) {
                number /= magnifier;
            } else {
                number *= magnifier;
            }
            number = Math.round(number);
            if (digits < 0) {
                number *= magnifier;
            } else {
                number /= magnifier;
            }
        }
        
        if (digits > 0) {
            return RubyFloat.newFloat(context.runtimenumber);
        } else {
            return dbl2num(context.runtime, (long)number);
        }
    }
    
    private double val2dbl() {
        double f = ;
        if (f > 0.0) {
            f = Math.floor(f);
            if ( - f >= 0.5) {
                f += 1.0;
            }
        } else if (f < 0.0) {
            f = Math.ceil(f);
            if (f -  >= 0.5) {
                f -= 1.0;
            }
        }
        
        return f;
    }
        
    
flo_is_nan_p
    @JRubyMethod(name = "nan?")
    public IRubyObject nan_p() {
        return RubyBoolean.newBoolean(getRuntime(), Double.isNaN());
    }

    
flo_is_infinite_p
    @JRubyMethod(name = "infinite?")
    public IRubyObject infinite_p() {
        if (Double.isInfinite()) {
            return RubyFixnum.newFixnum(getRuntime(),  < 0 ? -1 : 1);
        }
        return getRuntime().getNil();
    }
            
    
flo_is_finite_p
    @JRubyMethod(name = "finite?")
    public IRubyObject finite_p() {
        if (Double.isInfinite() || Double.isNaN()) {
            return getRuntime().getFalse();
        }
        return getRuntime().getTrue();
    }
    private ByteList marshalDump() {
        if (Double.isInfinite()) return  < 0 ?  : ;
        if (Double.isNaN()) return ;
        ByteList byteList = new ByteList();
        // Always use US locale, to ensure "." separator. JRUBY-5918
        Sprintf.sprintf(byteList."%.17g", RubyArray.newArray(getRuntime(), this));
        return byteList;
    }
    public static void marshalTo(RubyFloat aFloatMarshalStream outputthrows java.io.IOException {
        output.registerLinkTarget(aFloat);
        output.writeString(aFloat.marshalDump());
    }
        
    public static RubyFloat unmarshalFrom(UnmarshalStream inputthrows java.io.IOException {
        ByteList value = input.unmarshalString();
        RubyFloat result;
        if (value.equals()) {
            result = RubyFloat.newFloat(input.getRuntime(), .);
        } else if (value.equals()) {
            result = RubyFloat.newFloat(input.getRuntime(), .);
        } else if (value.equals()) {
            result = RubyFloat.newFloat(input.getRuntime(), .);
        } else {
            result = RubyFloat.newFloat(input.getRuntime(),
                    ConvertDouble.byteListToDouble(valuefalse));
        }
        input.registerLinkTarget(result);
        return result;
    }
    private static final ByteList NAN_BYTELIST = new ByteList("nan".getBytes());
    private static final ByteList NEGATIVE_INFINITY_BYTELIST = new ByteList("-inf".getBytes());
    private static final ByteList INFINITY_BYTELIST = new ByteList("inf".getBytes());