الفرق بين المراجعتين ل"Ruby/Float"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
سطر 1: سطر 1:
<noinclude>{{DISPLAYTITLE: الأعداد العشرية Float في روبي}}</noinclude>
+
<noinclude>{{DISPLAYTITLE: الصنف Float في روبي}}</noinclude>
 +
تمثِّل كائنات الصنف Float أعدادًا حقيقيةً غير دقيقة (inexact real numbers) باستخدام التمثيل العشري ذي الدقة المضاعفة للبنية الأصلية.
  
تمثل كائنات Float أرقامًا حقيقية غير دقيقة باستخدام تمثيل النقطة العائمة المزدوجة الدقة للبنية الأصلية.
+
للفاصلة العشرية حساب مختلف وهو عدد غير دقيق، لذا يجب معرفة نظامها الخاص. اطلع على الصفحات التالية:
  
للنقطة العائمة حساب مختلف وهو رقم غير دقيق. لذا يجب معرفة نظامها الخاص. انظر التالي:
+
* [[docs.sun.com/source/806-3568/ncg_goldberg.html]]
  
[[docs.sun.com/source/806-3568/ncg_goldberg.html]]
+
* [[wiki.github.com/rdp/ruby_tutorials_core/ruby-talk-faq#wiki-floats_imprecise]]
  
[[wiki.github.com/rdp/ruby_tutorials_core/ruby-talk-faq#wiki-floats_imprecise]]
+
* [[en.wikipedia.org/wiki/Floating_point#Accuracy_problems]]
 
 
[[en.wikipedia.org/wiki/Floating_point#Accuracy_problems]]
 
 
===الثوابت===
 
===الثوابت===
 
====<code>DIG</code>====
 
====<code>DIG</code>====
سطر 74: سطر 73:
 
<code>3</code> : التقريب نحو اللانهاية السالبة.
 
<code>3</code> : التقريب نحو اللانهاية السالبة.
 
===توابع المثيل العام===
 
===توابع المثيل العام===
====<code>float % other → float</code>====
+
===<code>[[Ruby/Float/modulo|%]]</code>===
إعادة الوحدة بعد قسمة <code>float</code> على <code>other</code>.<syntaxhighlight lang="ruby">
+
يعيد المعامل <code>%‎</code> باقي عملية قسمة عدد عشري على عدد آخر.
6543.21.modulo(137)      #=> 104.21000000000004
 
6543.21.modulo(137.24)  #=> 92.92999999999961
 
 
 
</syntaxhighlight><syntaxhighlight lang="ruby">
 
              static VALUE
 
flo_mod(VALUE x, VALUE y)
 
{
 
    double fy;
 
 
 
    if (RB_TYPE_P(y, T_FIXNUM)) {
 
        fy = (double)FIX2LONG(y);
 
    }
 
    else if (RB_TYPE_P(y, T_BIGNUM)) {
 
        fy = rb_big2dbl(y);
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        fy = RFLOAT_VALUE(y);
 
    }
 
    else {
 
        return rb_num_coerce_bin(x, y, '%');
 
    }
 
    return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(x), fy));
 
}
 
           
 
</syntaxhighlight>
 
====<code>float * other → float</code>====
 
إعادة Float جديد والذي يكون هو نتاج حاصل ضرب <code>float</code> و <code>other</code>.<syntaxhighlight lang="ruby">
 
 
              static VALUE
 
flo_mul(VALUE x, VALUE y)
 
{
 
    if (RB_TYPE_P(y, T_FIXNUM)) {
 
        return DBL2NUM(RFLOAT_VALUE(x) * (double)FIX2LONG(y));
 
    }
 
    else if (RB_TYPE_P(y, T_BIGNUM)) {
 
        return DBL2NUM(RFLOAT_VALUE(x) * rb_big2dbl(y));
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        return DBL2NUM(RFLOAT_VALUE(x) * RFLOAT_VALUE(y));
 
    }
 
    else {
 
        return rb_num_coerce_bin(x, y, '*');
 
    }
 
}
 
</syntaxhighlight>
 
====<code>float ** other → float</code>====
 
رفع <code>float</code> للأس <code>other</code>.<syntaxhighlight lang="ruby">
 
2.0**3  #=> 8.0
 
 
 
</syntaxhighlight><syntaxhighlight lang="ruby">
 
 
              VALUE
 
rb_float_pow(VALUE x, VALUE y)
 
{
 
    double dx, dy;
 
    if (RB_TYPE_P(y, T_FIXNUM)) {
 
        dx = RFLOAT_VALUE(x);
 
        dy = (double)FIX2LONG(y);
 
    }
 
    else if (RB_TYPE_P(y, T_BIGNUM)) {
 
        dx = RFLOAT_VALUE(x);
 
        dy = rb_big2dbl(y);
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        dx = RFLOAT_VALUE(x);
 
        dy = RFLOAT_VALUE(y);
 
        if (dx < 0 && dy != round(dy))
 
            return num_funcall1(rb_complex_raw1(x), idPow, y);
 
    }
 
    else {
 
        return rb_num_coerce_bin(x, y, idPow);
 
    }
 
    return DBL2NUM(pow(dx, dy));
 
}
 
           
 
</syntaxhighlight>
 
====<code>float + other → float</code>====
 
إعادة Float جديد والذي يكون هو نتاج حاصل جمع <code>float</code> و <code>other</code>.<syntaxhighlight lang="ruby">
 
 
              static VALUE
 
flo_plus(VALUE x, VALUE y)
 
{
 
    if (RB_TYPE_P(y, T_FIXNUM)) {
 
        return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y));
 
    }
 
    else if (RB_TYPE_P(y, T_BIGNUM)) {
 
        return DBL2NUM(RFLOAT_VALUE(x) + rb_big2dbl(y));
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        return DBL2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y));
 
    }
 
    else {
 
        return rb_num_coerce_bin(x, y, '+');
 
    }
 
}
 
</syntaxhighlight>
 
====<code>float - other → float</code>====
 
إعادة Float جديد والذي يكون هو الفرق بين <code>float</code> و <code>other</code>.<syntaxhighlight lang="ruby">
 
 
 
              static VALUE
 
flo_minus(VALUE x, VALUE y)
 
{
 
    if (RB_TYPE_P(y, T_FIXNUM)) {
 
        return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
 
    }
 
    else if (RB_TYPE_P(y, T_BIGNUM)) {
 
        return DBL2NUM(RFLOAT_VALUE(x) - rb_big2dbl(y));
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        return DBL2NUM(RFLOAT_VALUE(x) - RFLOAT_VALUE(y));
 
    }
 
    else {
 
        return rb_num_coerce_bin(x, y, '-');
 
    }
 
}
 
           
 
</syntaxhighlight>
 
====<code>‎-float → float</code>====
 
إعادة <code>float</code> بعلامة سالبة.<syntaxhighlight lang="ruby">
 
 
              VALUE
 
rb_float_uminus(VALUE flt)
 
{
 
    return DBL2NUM(-RFLOAT_VALUE(flt));
 
}
 
           
 
</syntaxhighlight>
 
====<code>float / other → float</code>====
 
إعادة Float جديد والذي يكون نتاج حاصل قسمة <code>float</code> على <code>other</code>.<syntaxhighlight lang="ruby">
 
 
              static VALUE
 
flo_div(VALUE x, VALUE y)
 
{
 
    long f_y;
 
    double d;
 
 
 
    if (RB_TYPE_P(y, T_FIXNUM)) {
 
        f_y = FIX2LONG(y);
 
        return DBL2NUM(RFLOAT_VALUE(x) / (double)f_y);
 
    }
 
    else if (RB_TYPE_P(y, T_BIGNUM)) {
 
        d = rb_big2dbl(y);
 
        return DBL2NUM(RFLOAT_VALUE(x) / d);
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        return DBL2NUM(RFLOAT_VALUE(x) / RFLOAT_VALUE(y));
 
    }
 
    else {
 
        return rb_num_coerce_bin(x, y, '/');
 
    }
 
}
 
</syntaxhighlight>
 
====<code>float < real → true or false</code>====
 
إعادة <code>true</code> إذا كان <code>float</code> أقل من <code>real</code>.
 
 
 
نتيجة NaN < NaN غير مُعرَّفة، لذا تُعاد قيمة تعتمد على التنفيذ.<syntaxhighlight lang="ruby">
 
 
              static VALUE
 
flo_lt(VALUE x, VALUE y)
 
{
 
    double a, b;
 
 
 
    a = RFLOAT_VALUE(x);
 
    if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
 
        VALUE rel = rb_integer_float_cmp(y, x);
 
        if (FIXNUM_P(rel))
 
            return -FIX2INT(rel) < 0 ? Qtrue : Qfalse;
 
        return Qfalse;
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        b = RFLOAT_VALUE(y);
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
        if (isnan(b)) return Qfalse;
 
#endif
 
    }
 
    else {
 
        return rb_num_coerce_relop(x, y, '<');
 
    }
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
    if (isnan(a)) return Qfalse;
 
#endif
 
    return (a < b)?Qtrue:Qfalse;
 
}
 
         
 
</syntaxhighlight>
 
====<code>float <= real → true or false</code>====
 
إعادة <code>true</code> إذا كان <code>float</code> أقل من أو يساوي <code>real</code>.
 
 
 
نتيجة NaN <= NaN غير معرفة، لذا تُعاد قيمة تعتمد على التنفيذ.<syntaxhighlight lang="ruby">
 
 
 
              static VALUE
 
flo_le(VALUE x, VALUE y)
 
{
 
    double a, b;
 
 
 
    a = RFLOAT_VALUE(x);
 
    if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
 
        VALUE rel = rb_integer_float_cmp(y, x);
 
        if (FIXNUM_P(rel))
 
            return -FIX2INT(rel) <= 0 ? Qtrue : Qfalse;
 
        return Qfalse;
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        b = RFLOAT_VALUE(y);
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
        if (isnan(b)) return Qfalse;
 
#endif
 
    }
 
    else {
 
        return rb_num_coerce_relop(x, y, idLE);
 
    }
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
    if (isnan(a)) return Qfalse;
 
#endif
 
    return (a <= b)?Qtrue:Qfalse;
 
}
 
       
 
</syntaxhighlight>
 
====<code>float <=> real → -1, 0, +1, or nil</code>====
 
إعادة ‎-1 ، 0 أو ‎+1 اعتمادًا على ما إذا كان <code>float</code> أقل من أو يساوي أو أكبر من <code>real</code>. هذا هو أساس الاختبارات في وحدة [[Ruby/Comparable|Comparable]].
 
  
نتيجة NaN <=> NaN غير مُعرَّفة، لذا تُعاد قيمة تعتمد علي التنفيذ.
+
===<code>[[Ruby/Float/multiplication|*]]</code>===
 +
يعيد المعامل <code>*‎</code> ناتج عملية ضرب عدد عشري بعدد آخر.
  
إعادة <code>nil</code> إذا كانت القيمتين غير صالحتين للمقارنة.<syntaxhighlight lang="ruby">
+
===<code>[[Ruby/Float/expo|**]]</code>===
 +
يعيد المعامل <code>**‎</code> ناتج عملية رفع عدد عشري (الأساس) إلى قوة عدد محدد (الأس).
  
              static VALUE
+
===<code>[[Ruby/Float/plus|+]]</code>===
flo_cmp(VALUE x, VALUE y)
+
يعيد المعامل <code>+</code> ناتج عملية الجمع بين عددين.
{
 
    double a, b;
 
    VALUE i;
 
  
    a = RFLOAT_VALUE(x);
+
===<code>[[Ruby/Float/minus|-]]</code>===
    if (isnan(a)) return Qnil;
+
يعيد المعامل <code>-‎</code> ناتج عملية الطرح بين عددين.
    if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
 
        VALUE rel = rb_integer_float_cmp(y, x);
 
        if (FIXNUM_P(rel))
 
            return INT2FIX(-FIX2INT(rel));
 
        return rel;
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        b = RFLOAT_VALUE(y);
 
    }
 
    else {
 
        if (isinf(a) && (i = rb_check_funcall(y, rb_intern("infinite?"), 0, 0)) != Qundef) {
 
            if (RTEST(i)) {
 
                int j = rb_cmpint(i, x, y);
 
                j = (a > 0.0) ? (j > 0 ? 0 : +1) : (j < 0 ? 0 : -1);
 
                return INT2FIX(j);
 
            }
 
            if (a > 0.0) return INT2FIX(1);
 
            return INT2FIX(-1);
 
        }
 
        return rb_num_coerce_cmp(x, y, id_cmp);
 
    }
 
    return rb_dbl_cmp(a, b);
 
}
 
         
 
</syntaxhighlight>
 
====<code>float == obj → true or false</code>====
 
إعادة <code>true</code> فقط إذا كانت قيمة <code>obj</code> نفس قيمة <code>float</code>. علي عكس ذلك تحتاج ‎<code>#eql?</code>أن يكون <code>obj</code> من النوع Float.<syntaxhighlight lang="ruby">
 
1.0 == 1  #=> true
 
  
</syntaxhighlight>نتيجة NaN == NaN غير مُعرَّفة، لذا تُعاد قيمة تعتمد علي التنفيذ.<syntaxhighlight lang="ruby">
+
===<code>[[Ruby/Float/negation|-]]</code>===
+
إن استُعمِل المعامل <code>-</code> بالشكل <code>‎-Float</code>، فسيعيد القيمة المعاكسة للعدد <code>Float</code> العشري (أي القيمة السالبة إن كان <code>Float</code> موجبًا أو العكس بالعكس).
              VALUE
 
rb_float_equal(VALUE x, VALUE y)
 
{
 
    volatile double a, b;
 
  
    if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
+
===<code>[[Ruby/Float/division|/]]</code>===
        return rb_integer_float_eq(y, x);
+
يعيد المعامل <code>/</code> ناتج عملية القسمة بين عدد عشري وعدد آخر.
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        b = RFLOAT_VALUE(y);
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
        if (isnan(b)) return Qfalse;
 
#endif
 
    }
 
    else {
 
        return num_equal(x, y);
 
    }
 
    a = RFLOAT_VALUE(x);
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
    if (isnan(a)) return Qfalse;
 
#endif
 
    return (a == b)?Qtrue:Qfalse;
 
}
 
           
 
</syntaxhighlight>
 
====<code>float == obj → true or false</code>====
 
إعادة <code>true</code> فقط إذا كانت قيمة <code>obj</code> نفس قيمة <code>float</code>. علي عكس ذلك تحتاج ‎<code>#eql?</code>‎ أن يكون <code>obj</code> من نوع Float.
 
 
 
نتيجة NaN == NaN غير مُعرَّفة، لذا تُعاد قيمة تعتمد علي التنفيذ.<syntaxhighlight lang="ruby">
 
    VALUE
 
rb_float_equal(VALUE x, VALUE y)
 
{
 
    volatile double a, b;
 
 
 
    if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
 
        return rb_integer_float_eq(y, x);
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        b = RFLOAT_VALUE(y);
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
        if (isnan(b)) return Qfalse;
 
#endif
 
    }
 
    else {
 
        return num_equal(x, y);
 
    }
 
    a = RFLOAT_VALUE(x);
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
    if (isnan(a)) return Qfalse;
 
#endif
 
    return (a == b)?Qtrue:Qfalse;
 
}
 
</syntaxhighlight>
 
====<code>float > real → true or false</code>====
 
إعادة <code>true</code> إذا كان <code>float</code> أكبر من <code>real</code>.
 
 
 
نتيجة NaN > NaN غير مُعرَّفة، لذا تُعاد قيمة تعتمد علي التنفيذ.<syntaxhighlight lang="ruby">
 
 
              VALUE
 
rb_float_gt(VALUE x, VALUE y)
 
{
 
    double a, b;
 
  
    a = RFLOAT_VALUE(x);
+
===<code>[[Ruby/Float/lt|>]]</code>===
    if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
+
يعيد المعامل <code>></code> القيمة <code>true</code> إن كانت قيمة العدد العشري الواقع على يساره أصغر من قيمة العدد المواقع على يمينه.
        VALUE rel = rb_integer_float_cmp(y, x);
 
        if (FIXNUM_P(rel))
 
            return -FIX2INT(rel) > 0 ? Qtrue : Qfalse;
 
        return Qfalse;
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        b = RFLOAT_VALUE(y);
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
        if (isnan(b)) return Qfalse;
 
#endif
 
    }
 
    else {
 
        return rb_num_coerce_relop(x, y, '>');
 
    }
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
    if (isnan(a)) return Qfalse;
 
#endif
 
    return (a > b)?Qtrue:Qfalse;
 
}
 
</syntaxhighlight>
 
====<code>float >= real → true or false</code>====
 
إعادة <code>true</code> إذا كان <code>float</code> أكبر من أو يساوي <code>real</code>.
 
  
نتيجة NaN >= NaN غير معرفة، لذا تُعاد قيمة تعتمد على التنفيذ.<syntaxhighlight lang="ruby">
+
===<code>[[Ruby/Float/le|=>]]</code>===
 +
يعيد المعامل <code>=></code> القيمة <code>true</code> إن كانت قيمة العدد العشري الواقع على يساره أصغر من أو تساوي قيمة العدد الواقع على يمينه.
  
              static VALUE
+
===<code>[[Ruby/Float/comparison|<=>]]</code>===
flo_ge(VALUE x, VALUE y)
+
يعيد معامل الموازنة <code><=></code> عددً‎ا صحيحًا (‎-1 أو 0 أو ‎+1) إذا كان العدد العشري الواقع على يساره أصغر من أو يساوي أو أكبر من العدد الآخر الواقع على يمينه على التوالي.
{
 
    double a, b;
 
  
    a = RFLOAT_VALUE(x);
+
===<code>[[Ruby/Float/equal|==]]</code>===
    if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
+
يعيد المعامل <code>==</code> القيمة <code>true</code> إن كان العدد العشري الواقع على يساره يساوي القيمة الواقعة على يمينه. 
        VALUE rel = rb_integer_float_cmp(y, x);
 
        if (FIXNUM_P(rel))
 
            return -FIX2INT(rel) >= 0 ? Qtrue : Qfalse;
 
        return Qfalse;
 
    }
 
    else if (RB_TYPE_P(y, T_FLOAT)) {
 
        b = RFLOAT_VALUE(y);
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
        if (isnan(b)) return Qfalse;
 
#endif
 
    }
 
    else {
 
        return rb_num_coerce_relop(x, y, idGE);
 
    }
 
#if defined(_MSC_VER) && _MSC_VER < 1300
 
    if (isnan(a)) return Qfalse;
 
#endif
 
    return (a >= b)?Qtrue:Qfalse;
 
}
 
     
 
</syntaxhighlight>
 
====<code>abs → float</code>====
 
إعادة القيمة المطلقة للتابع <code>float</code>.<syntaxhighlight lang="ruby">
 
(-34.56).abs  #=> 34.56
 
-34.56.abs    #=> 34.56
 
34.56.abs      #=> 34.56
 
</syntaxhighlight>‎<code><nowiki>#</nowiki>magnitude</code> اسم مستعار للتابع <code>‎#abs</code>.<syntaxhighlight lang="ruby">
 
 
              VALUE
 
rb_float_abs(VALUE flt)
 
{
 
    double val = fabs(RFLOAT_VALUE(flt));
 
    return DBL2NUM(val);
 
}
 
           
 
</syntaxhighlight>
 
====<code>angle → 0 or float</code>====
 
إعادة 0 إذا كانت القيمة موجبة، أو "ط (pi)" خلاف ذلك.<syntaxhighlight lang="ruby">
 
  
              static VALUE
+
===<code>[[Ruby/Float/gt|<]]</code>===
float_arg(VALUE self)
+
يعيد المعامل <code><</code> القيمة <code>true</code> إن كانت قيمة العدد العشري الواقع على يساره أكبر من قيمة العدد الآخر الواقع على يمينه.
{
 
    if (isnan(RFLOAT_VALUE(self)))
 
        return self;
 
    if (f_tpositive_p(self))
 
        return INT2FIX(0);
 
    return rb_const_get(rb_mMath, id_PI);
 
}
 
</syntaxhighlight>
 
====<code>arg → 0 or float</code>====
 
إعادة 0 إذا كانت القيمة موجبة، أو "ط (pi)" خلاف ذلك.<syntaxhighlight lang="ruby">
 
 
              static VALUE
 
float_arg(VALUE self)
 
{
 
    if (isnan(RFLOAT_VALUE(self)))
 
        return self;
 
    if (f_tpositive_p(self))
 
        return INT2FIX(0);
 
    return rb_const_get(rb_mMath, id_PI);
 
}
 
</syntaxhighlight>
 
====<code>ceil([ndigits]) → integer or float</code>====
 
إعادة أصغر رقم أكبر من أو يساوي <code>float</code> مع دقة <code>ndigits</code> رقم (القيمة الافتراضية: 0).
 
  
عندما تكون الدقة سالبة، تكون القيمة المُعادة عدد صحيح متبوعًا بعدد أصفار مقداره <code>ndigits.abs</code> على الأقل.
+
===<code>[[Ruby/Float/ge|=<]]</code>===
 +
يعيد التابع <code>=<</code> القيمة <code>true</code> إن كانت قيمة العدد العشري الواقع على يساره أكبر من أو تساوي قيمة العدد الآخر الواقع على يمينه.
  
إعادة عدد عشري عندما يكون <code>ndigits</code> موجبًا، وإلا يُعاد عددٌ صحيحٌ.<syntaxhighlight lang="ruby">
+
===<code>[[Ruby/Float/abs|abs]]</code>===
1.2.ceil      #=> 2
+
يعيد التابع <code>abs</code> القيمة المطلقة للعدد العشري الذي استُدعي معه.
2.0.ceil      #=> 2
 
(-1.2).ceil  #=> -1
 
(-2.0).ceil  #=> -2
 
  
1.234567.ceil(2)  #=> 1.24
+
===<code>[[Ruby/Float/angle|angle]]</code>===
1.234567.ceil(3)  #=> 1.235
+
يعيد التابع <code>angle</code> القيمة <code>0</code> إن كان العدد العشري الذي استُدعي معه موجبًا، أو القيمة <code>[[Ruby/Math/PI|pi]]</code> خلاف ذلك.
1.234567.ceil(4)  #=> 1.2346
 
1.234567.ceil(5)  #=> 1.23457
 
  
34567.89.ceil(-5)  #=> 100000
+
===<code>[[Ruby/Float/arg|arg]]</code>===
34567.89.ceil(-4)  #=> 40000
+
يعيد التابع <code>arg</code> القيمة <code>0</code> إن كان العدد العشري الذي استُدعي معه موجبًا، أو القيمة <code>[[Ruby/Math/PI|pi]]</code> خلاف ذلك.
34567.89.ceil(-3)  #=> 35000
 
34567.89.ceil(-2)  #=> 34600
 
34567.89.ceil(-1)  #=> 34570
 
34567.89.ceil(0)  #=> 34568
 
34567.89.ceil(1)  #=> 34567.9
 
34567.89.ceil(2)  #=> 34567.89
 
34567.89.ceil(3)  #=> 34567.89
 
</syntaxhighlight>يُلاحظ أن الدقة المحدودة للنقطة العائمة الحسابية قد تؤدي إلى نتائج مُدهشة:<syntaxhighlight lang="ruby">
 
(2.1 / 0.7).ceil  #=> 4 (!)
 
  
</syntaxhighlight>
+
===<code>[[Ruby/Float/ceil|ceil]]</code>===
====<code>coerce(numeric) → array</code>====
+
يعيد التابع <code>ceil</code> أصغر عدد من الأعداد الأكبر من أو تساوي العدد العشري الذي استُدعي معه وبدقة محدَّدة.
إعادة مصفوفة يتمثَّل فيها كلٌ من <code>numeric</code> و <code>float</code> ككائنات Float.
 
  
ويتحقق ذلك عن طريق تحويل numeric إلى Float.<syntaxhighlight lang="ruby">
+
===<code>[[Ruby/Float/coerce|coerce]]</code>===
1.2.coerce(3)      #=> [3.0, 1.2]
+
يحول التابع <code>coerce</code> العدد المستدعى معها والعدد العشري المُمرَّر إليها إلى النوع <code>[[Ruby/Float|Float]]</code> ويعيدهما في مصفوفة.
2.5.coerce(1.1)    #=> [1.1, 2.5]
 
</syntaxhighlight>
 
====<code>denominator → integer</code>====
 
إعادة المقام (موجب دائمًا). والنتيجة تعتمد على الآلة.
 
  
انظر أيضا <code>‎#numerator</code>.<syntaxhighlight lang="ruby">
+
===<code>[[Ruby/Float/denominator|denominator]]</code>===
 +
يعيد التابع <code>denominator</code> المقام (denominator) للعدد الكسري الذي استدعي معه، ويكون دائمًا موجبًا.
  
              static VALUE
+
===<code>[[Ruby/Float/divmod|divmod]]</code>===
float_denominator(VALUE self)
+
===<code>[[Ruby/Float/eql-3F|eql?]]</code>===
{
+
===<code>[[Ruby/Float/fdiv|fdiv]]</code>===
    double d = RFLOAT_VALUE(self);
+
===<code>[[Ruby/Float/finite-3F|finite?]]</code>===
    VALUE r;
+
===<code>[[Ruby/Float/floor|floor]]</code>===
    if (isinf(d) || isnan(d))
+
===<code>[[Ruby/Float/hash|hash]]</code>===
        return INT2FIX(1);
+
===<code>[[Ruby/Float/infinite-3F|infinite?]]</code>===
    r = float_to_r(self);
+
===<code>[[Ruby/Float/inspect|inspect]]</code>===
    if (canonicalization && k_integer_p(r)) {
+
===<code>[[Ruby/Float/magnitude|magnitude]]</code>===
        return ONE;
+
===<code>[[Ruby/Float/modulo|modulo]]</code>===
    }
+
===<code>[[Ruby/Float/nan-3F|nan?]]</code>===
    return nurat_denominator(r);
+
===<code>[[Ruby/Float/negative-3F|negative?]]</code>===
}
+
===<code>[[Ruby/Float/next_float|next_float]]</code>===
</syntaxhighlight>
+
===<code>[[Ruby/Float/numerator|numerator]]</code>===
 +
===<code>[[Ruby/Float/phase|phase]]</code>===
 +
===<code>[[Ruby/Float/positive-3F|positive?]]</code>===
 +
===<code>[[Ruby/Float/prev_float|prev_float]]</code>===
 +
===<code>[[Ruby/Float/quo|quo]]</code>===
 +
===<code>[[Ruby/Float/rationalize|rationalize]]</code>===
 +
===<code>[[Ruby/Float/round|round]]</code>===
 +
===<code>[[Ruby/Float/to_f|to_f]]</code>===
 +
===<code>[[Ruby/Float/to_i|to_i]]</code>===
 +
===<code>[[Ruby/Float/to_int|to_int]]</code>===
 +
===<code>[[Ruby/Float/to_r|to_r]]</code>===
 +
===<code>[[Ruby/Float/to_s|to_s]]</code>===
 +
===<code>[[Ruby/Float/truncate|truncate]]</code>===
 +
===<code>[[Ruby/Float/zero-3F|zero?]]</code>===
 
====<code>divmod(numeric) → array</code>====
 
====<code>divmod(numeric) → array</code>====
 
راجع <code>Numeric#divmod</code>.<syntaxhighlight lang="ruby">
 
راجع <code>Numeric#divmod</code>.<syntaxhighlight lang="ruby">
سطر 1٬130: سطر 733:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
=مصادر=
 
=مصادر=
* <span> </span>[http://ruby-doc.org/core-2.5.1/Float.html صفحة Float في توثيق روبي الرسمي.]
+
* <span> </span>[http://ruby-doc.org/core-2.5.1/Float.html صفحة الصنف Float في توثيق روبي الرسمي.]
 
[[تصنيف:Ruby]]
 
[[تصنيف:Ruby]]
 +
[[تصنيف:Ruby Class]]
 +
[[تصنيف:Ruby Float]]

مراجعة 16:10، 23 نوفمبر 2018

تمثِّل كائنات الصنف Float أعدادًا حقيقيةً غير دقيقة (inexact real numbers) باستخدام التمثيل العشري ذي الدقة المضاعفة للبنية الأصلية.

للفاصلة العشرية حساب مختلف وهو عدد غير دقيق، لذا يجب معرفة نظامها الخاص. اطلع على الصفحات التالية:

الثوابت

DIG

الحد الأدنى لعدد الأرقام العشرية ذات الدلالة في النقطة العائمة المزدوجة الدقة.

وعادة ما تكون قيمته الافتراضية 15.

EPSILON

الفرق بين 1 و أصغر عدد أكبر من 1 من نوع النقطة العائمة المزدوجة الدقة.

وعادة ما تكون قيمته الافتراضية 2.2204460492503131e-16.

INFINITY

تعبير يمثل اللانهاية الموجبة.

MANT_DIG

عدد الأرقام الأساسية لنوع البيانات المزدوج (double).

وعادة ما تكون قيمته الافتراضية 53.

MAX

أكبر عدد صحيح في النقطة العائمة المزدوجة الدقة.

وعادة ما تكون قيمته الافتراضية 1.7976931348623157e+308.

MAX_10_EXP

أكبر أس موجب في النقطة العائمة المزدوجة الدقة حيث تكون 10 مرفوعة إلى هذا الأس ناقص 1.

وعادة ما تكون قيمته الافتراضية 308.

MAX_EXP

أكبر قيمة أس محتملة في النقطة العائمة المزدوجة الدقة.

وعادة ما تكون قيمته الافتراضية 1024.

MIN

أصغر رقم مُعيَّر موجب في النقطة العائمة المزدوجة الدقة.

وعادة ما تكون قيمته الافتراضية 2.2250738585072014e-308.

إذا كانت المنصة تدعم الأرقام غير المُعيَّرة، يكون هناك أرقام بين صفر و Float::MIN. وتعيد ‎0.0.next_float أصغر نقطة عائمة موجبة بما في ذلك الأرقام غير المُعيَّرة.

MIN_10_EXP

أصغر أس سالب في النقطة العائمة المزدوجة الدقة حيث تكون 10 مرفوعة إلى هذا الأس ناقص 1.

وعادة ما تكون قيمته الافتراضية ‎-307.

MIN_EXP

أصغر قيمة أس محتملة في النقطة العائمة المزدوجة الدقة.

وعادة ما تكون قيمته الافتراضية ‎-1021.

NAN

تعبير يمثل القيمة "ليست عددًا" (not a number).

RADIX

أساس النقطة العائمة، أو عدد الأرقام الفريدة المستخدمة لتمثيل الرقم.

وعادة ما تكون قيمته الافتراضية 2 على معظم الأنظمة، والتي تمثل النظام العشري للأساس 10.

ROUNDS

يمثل وضع التقريب لإضافة النقطة العائمة.

وعادة ما تكون قيمته الافتراضية 1، التقريب إلى أقرب عدد.

وتشمل الأوضاع الأخرى:

-1 : مُتعذِّر تحديده.

0 : التقريب نحو الصفر.

1 : التقريب إلى أقرب عدد.

2 : التقريب نحو اللانهاية الموجبة.

3 : التقريب نحو اللانهاية السالبة.

توابع المثيل العام

%

يعيد المعامل %‎ باقي عملية قسمة عدد عشري على عدد آخر.

*

يعيد المعامل *‎ ناتج عملية ضرب عدد عشري بعدد آخر.

**

يعيد المعامل **‎ ناتج عملية رفع عدد عشري (الأساس) إلى قوة عدد محدد (الأس).

+

يعيد المعامل + ناتج عملية الجمع بين عددين.

-

يعيد المعامل -‎ ناتج عملية الطرح بين عددين.

-

إن استُعمِل المعامل - بالشكل ‎-Float، فسيعيد القيمة المعاكسة للعدد Float العشري (أي القيمة السالبة إن كان Float موجبًا أو العكس بالعكس).

/

يعيد المعامل /‎ ناتج عملية القسمة بين عدد عشري وعدد آخر.

>

يعيد المعامل > القيمة true إن كانت قيمة العدد العشري الواقع على يساره أصغر من قيمة العدد المواقع على يمينه.

=>

يعيد المعامل => القيمة true إن كانت قيمة العدد العشري الواقع على يساره أصغر من أو تساوي قيمة العدد الواقع على يمينه.

<=>

يعيد معامل الموازنة <=> عددً‎ا صحيحًا (‎-1 أو 0 أو ‎+1) إذا كان العدد العشري الواقع على يساره أصغر من أو يساوي أو أكبر من العدد الآخر الواقع على يمينه على التوالي.

==

يعيد المعامل == القيمة true إن كان العدد العشري الواقع على يساره يساوي القيمة الواقعة على يمينه. 

<

يعيد المعامل < القيمة true إن كانت قيمة العدد العشري الواقع على يساره أكبر من قيمة العدد الآخر الواقع على يمينه.

=<

يعيد التابع =< القيمة true إن كانت قيمة العدد العشري الواقع على يساره أكبر من أو تساوي قيمة العدد الآخر الواقع على يمينه.

abs

يعيد التابع abs القيمة المطلقة للعدد العشري الذي استُدعي معه.

angle

يعيد التابع angle القيمة 0 إن كان العدد العشري الذي استُدعي معه موجبًا، أو القيمة pi خلاف ذلك.

arg

يعيد التابع arg القيمة 0 إن كان العدد العشري الذي استُدعي معه موجبًا، أو القيمة pi خلاف ذلك.

ceil

يعيد التابع ceil أصغر عدد من الأعداد الأكبر من أو تساوي العدد العشري الذي استُدعي معه وبدقة محدَّدة.

coerce

يحول التابع coerce العدد المستدعى معها والعدد العشري المُمرَّر إليها إلى النوع Float ويعيدهما في مصفوفة.

denominator

يعيد التابع denominator المقام (denominator) للعدد الكسري الذي استدعي معه، ويكون دائمًا موجبًا.

divmod

eql?

fdiv

finite?

floor

hash

infinite?

inspect

magnitude

modulo

nan?

negative?

next_float

numerator

phase

positive?

prev_float

quo

rationalize

round

to_f

to_i

to_int

to_r

to_s

truncate

zero?

divmod(numeric) → array

راجع Numeric#divmod.

42.0.divmod(6)   #=> [7, 0.0]
42.0.divmod(5)   #=> [8, 2.0]

eql?(obj) → true or false

إعادة true فقط إذا كانت obj من النوع Float وله نفس قيمة float. علي النقيض من ذلك مع Float#==‎، الذي يُجري تحويلات على النوع.

1.0.eql?(1)   #=> false

نتيجة NaN.eql?(NaN)‎ غير معرفة، لذا تُعاد قيمة تعتمد على التنفيذ.

               VALUE
rb_float_eql(VALUE x, VALUE y)
{
    if (RB_TYPE_P(y, T_FLOAT)) {
        double a = RFLOAT_VALUE(x);
        double b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
        if (isnan(a) || isnan(b)) return Qfalse;
#endif
        if (a == b)
            return Qtrue;
    }
    return Qfalse;
}

fdiv(numeric) → float

إعادة float / numeric، مثل Float#/‎.

               static VALUE
flo_quo(VALUE x, VALUE y)
{
    return num_funcall1(x, '/', y);
}

finite? → true or false

إعادة true إذا كان float عدد نقطة عائمة IEEE صالح، أي أنه ليس لا نهائي و ‎#nan?‎ قيمتها false.

               VALUE
rb_flo_is_finite_p(VALUE num)
{
    double value = RFLOAT_VALUE(num);

#ifdef HAVE_ISFINITE
    if (!isfinite(value))
        return Qfalse;
#else
    if (isinf(value) || isnan(value))
        return Qfalse;
#endif

    return Qtrue;
}

floor([ndigits]) → integer or float

إعادة أكبر رقم أصغر من أو يساوي float مع دقة ndigits رقم عشري (القيمة الافتراضية: 0).

عندما تكون الدقة سالبة، تكون القيمة المُعادة عدد صحيح متبوعًا بعدد أصفار مقداره ndigits.abs على الأقل.

إعادة عدد عشري عندما يكون ndigits موجبًا، وإلا يُعاد عددٌ صحيحٌ.

1.2.floor      #=> 1
2.0.floor      #=> 2
(-1.2).floor   #=> -2
(-2.0).floor   #=> -2

1.234567.floor(2)   #=> 1.23
1.234567.floor(3)   #=> 1.234
1.234567.floor(4)   #=> 1.2345
1.234567.floor(5)   #=> 1.23456

34567.89.floor(-5)  #=> 0
34567.89.floor(-4)  #=> 30000
34567.89.floor(-3)  #=> 34000
34567.89.floor(-2)  #=> 34500
34567.89.floor(-1)  #=> 34560
34567.89.floor(0)   #=> 34567
34567.89.floor(1)   #=> 34567.8
34567.89.floor(2)   #=> 34567.89
34567.89.floor(3)   #=> 34567.89

يُلاحظ أن الدقة المحدودة للنقطة العائمة الحسابية قد تؤدي إلى نتائج مُدهشة:

(0.3 / 0.1).floor  #=> 2 (!)

hash → integer

إعادة رمز التجزئة لهذا الرقم العشري.

راجع أيضًا Object#hash.

 
               static VALUE
flo_hash(VALUE num)
{
    return rb_dbl_hash(RFLOAT_VALUE(num));
}

infinite? → -1, 1, or nil

إعادة nil أو ‎-1، أو 1 اعتمادًا علي ما إذا كانت القيمة محدودة، أو ‎-Infinity، أو ‎+Infinity.

(0.0).infinite?        #=> nil
(-1.0/0.0).infinite?   #=> -1
(+1.0/0.0).infinite?   #=> 1

inspect()‎

اسم المستعار للتابع to_s

magnitude → float

إعادة القيمة المطلقة للتابع float.

(-34.56).abs   #=> 34.56
-34.56.abs     #=> 34.56
34.56.abs      #=> 34.56

‎#magnitude اسم مستعار للتابع ‎#abs.

               VALUE
rb_float_abs(VALUE flt)
{
    double val = fabs(RFLOAT_VALUE(flt));
    return DBL2NUM(val);
}

modulo(other) → float

إعادة الوحدة بعد قسمة float على other.

6543.21.modulo(137)      #=> 104.21000000000004
6543.21.modulo(137.24)   #=> 92.92999999999961
 
               static VALUE
flo_mod(VALUE x, VALUE y)
{
    double fy;

    if (RB_TYPE_P(y, T_FIXNUM)) {
        fy = (double)FIX2LONG(y);
    }
    else if (RB_TYPE_P(y, T_BIGNUM)) {
        fy = rb_big2dbl(y);
    }
    else if (RB_TYPE_P(y, T_FLOAT)) {
        fy = RFLOAT_VALUE(y);
    }
    else {
        return rb_num_coerce_bin(x, y, '%');
    }
    return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(x), fy));
}

nan? → true or false

إعادة true إذا كان float عدد نقطة عائمة IEEE غير صالح.

a = -1.0      #=> -1.0
a.nan?        #=> false
a = 0.0/0.0   #=> NaN
a.nan?        #=> true
 
               static VALUE
flo_is_nan_p(VALUE num)
{
    double value = RFLOAT_VALUE(num);

    return isnan(value) ? Qtrue : Qfalse;
}

negative? → true or false

إعادة true إذا كان float أقل من 0.

               static VALUE
flo_negative_p(VALUE num)
{
    double f = RFLOAT_VALUE(num);
    return f < 0.0 ? Qtrue : Qfalse;
}

next_float → float

إعادة عدد النقطة العائمة القابل للتمثيل التالي.

Float::MAX.next_float و Float::INFINITY.next_float هما Float::INFINITY.

Float::NAN.next_float هو Float::NAN.

فعلى سبيل المثال:

0.01.next_float    #=> 0.010000000000000002
1.0.next_float     #=> 1.0000000000000002
100.0.next_float   #=> 100.00000000000001

0.01.next_float - 0.01     #=> 1.734723475976807e-18
1.0.next_float - 1.0       #=> 2.220446049250313e-16
100.0.next_float - 100.0   #=> 1.4210854715202004e-14

f = 0.01; 20.times { printf "%-20a %s\n", f, f.to_s; f = f.next_float }
#=> 0x1.47ae147ae147bp-7 0.01
#   0x1.47ae147ae147cp-7 0.010000000000000002
#   0x1.47ae147ae147dp-7 0.010000000000000004
#   0x1.47ae147ae147ep-7 0.010000000000000005
#   0x1.47ae147ae147fp-7 0.010000000000000007
#   0x1.47ae147ae148p-7  0.010000000000000009
#   0x1.47ae147ae1481p-7 0.01000000000000001
#   0x1.47ae147ae1482p-7 0.010000000000000012
#   0x1.47ae147ae1483p-7 0.010000000000000014
#   0x1.47ae147ae1484p-7 0.010000000000000016
#   0x1.47ae147ae1485p-7 0.010000000000000018
#   0x1.47ae147ae1486p-7 0.01000000000000002
#   0x1.47ae147ae1487p-7 0.010000000000000021
#   0x1.47ae147ae1488p-7 0.010000000000000023
#   0x1.47ae147ae1489p-7 0.010000000000000024
#   0x1.47ae147ae148ap-7 0.010000000000000026
#   0x1.47ae147ae148bp-7 0.010000000000000028
#   0x1.47ae147ae148cp-7 0.01000000000000003
#   0x1.47ae147ae148dp-7 0.010000000000000031
#   0x1.47ae147ae148ep-7 0.010000000000000033

f = 0.0
100.times { f += 0.1 }
f                           #=> 9.99999999999998       # should be 10.0 in the ideal world.
10-f                        #=> 1.9539925233402755e-14 # the floating point error.
10.0.next_float-10          #=> 1.7763568394002505e-15 # 1 ulp (unit in the last place).
(10-f)/(10.0.next_float-10) #=> 11.0                   # the error is 11 ulp.
(10-f)/(10*Float::EPSILON)  #=> 8.8                    # approximation of the above.
"%a" % 10                   #=> "0x1.4p+3"
"%a" % f                    #=> "0x1.3fffffffffff5p+3" # the last hex digit is 5.  16 - 5 = 11 ulp.

numerator → integer

إعادة البسط. والنتيجة تعتمد على الآلة.

n = 0.3.numerator    #=> 5404319552844595
d = 0.3.denominator  #=> 18014398509481984
n.fdiv(d)            #=> 0.3

انظر أيضا ‎#denominator.

               static VALUE
float_numerator(VALUE self)
{
    double d = RFLOAT_VALUE(self);
    VALUE r;
    if (isinf(d) || isnan(d))
        return self;
    r = float_to_r(self);
    if (canonicalization && k_integer_p(r)) {
        return r;
    }
    return nurat_numerator(r);
}

phase → 0 or float

إعادة 0 إذا كانت القيمة موجبة، أو "ط (pi)" خلاف ذلك.

 
               static VALUE
float_arg(VALUE self)
{
    if (isnan(RFLOAT_VALUE(self)))
        return self;
    if (f_tpositive_p(self))
        return INT2FIX(0);
    return rb_const_get(rb_mMath, id_PI);
}

positive? → true or false

إعادة true إذا كان float أكبر من 0.

              static VALUE
flo_positive_p(VALUE num)
{
    double f = RFLOAT_VALUE(num);
    return f > 0.0 ? Qtrue : Qfalse;
}

prev_float → float

إعادة عدد النقطة العائمة القابل للتمثيل السابق.

(-Float::MAX).prev_float و ‎(-Float::INFINITY).prev_float هما ‎-Float::INFINITY.

Float::NAN.prev_float هو Float::NAN.

فعلى سبيل المثال:

0.01.prev_float    #=> 0.009999999999999998
1.0.prev_float     #=> 0.9999999999999999
100.0.prev_float   #=> 99.99999999999999

0.01 - 0.01.prev_float     #=> 1.734723475976807e-18
1.0 - 1.0.prev_float       #=> 1.1102230246251565e-16
100.0 - 100.0.prev_float   #=> 1.4210854715202004e-14

f = 0.01; 20.times { printf "%-20a %s\n", f, f.to_s; f = f.prev_float }
#=> 0x1.47ae147ae147bp-7 0.01
#   0x1.47ae147ae147ap-7 0.009999999999999998
#   0x1.47ae147ae1479p-7 0.009999999999999997
#   0x1.47ae147ae1478p-7 0.009999999999999995
#   0x1.47ae147ae1477p-7 0.009999999999999993
#   0x1.47ae147ae1476p-7 0.009999999999999992
#   0x1.47ae147ae1475p-7 0.00999999999999999
#   0x1.47ae147ae1474p-7 0.009999999999999988
#   0x1.47ae147ae1473p-7 0.009999999999999986
#   0x1.47ae147ae1472p-7 0.009999999999999985
#   0x1.47ae147ae1471p-7 0.009999999999999983
#   0x1.47ae147ae147p-7  0.009999999999999981
#   0x1.47ae147ae146fp-7 0.00999999999999998
#   0x1.47ae147ae146ep-7 0.009999999999999978
#   0x1.47ae147ae146dp-7 0.009999999999999976
#   0x1.47ae147ae146cp-7 0.009999999999999974
#   0x1.47ae147ae146bp-7 0.009999999999999972
#   0x1.47ae147ae146ap-7 0.00999999999999997
#   0x1.47ae147ae1469p-7 0.009999999999999969
#   0x1.47ae147ae1468p-7 0.009999999999999967

quo(numeric) → float

إعادة float / numeric، مثل Float#/‎.

               static VALUE
flo_quo(VALUE x, VALUE y)
{
    return num_funcall1(x, '/', y);
}

rationalize([eps]) → rational

إعادة تقريب ابسط للقيمة (flt-|eps| <= result <= flt+|eps|). إذا لم يتاح الوسيط الاختياري eps، سيُختار تلقائيًا.

0.3.rationalize          #=> (3/10)
1.333.rationalize        #=> (1333/1000)
1.333.rationalize(0.01)  #=> (4/3)

انظر أيضا ‎#to_r.

               static VALUE
float_rationalize(int argc, VALUE *argv, VALUE self)
{
    VALUE e;
    double d = RFLOAT_VALUE(self);

    if (d < 0.0)
        return rb_rational_uminus(float_rationalize(argc, argv, DBL2NUM(-d)));

    rb_scan_args(argc, argv, "01", &e);

    if (argc != 0) {
        return rb_flt_rationalize_with_prec(self, e);
    }
    else {
        return rb_flt_rationalize(self);
    }
}

round([ndigits] [, half: mode]) → integer or float

إعادة float مُقرَّب إلى أقرب قيمة بدقة أرقام عشرية مقدارها ndigits (القيمة الافتراضية: 0).

عندما تكون الدقة سالبة، تكون القيمة المُعادة عدد صحيح متبوعًا بعدد أصفار مقداره ndigits.abs على الأقل.

إعادة عدد عشري عندما يكون ndigits موجبًا، وإلا يُعاد عددٌا صحيحٌا.

1.4.round      #=> 1
1.5.round      #=> 2
1.6.round      #=> 2
(-1.5).round   #=> -2

1.234567.round(2)   #=> 1.23
1.234567.round(3)   #=> 1.235
1.234567.round(4)   #=> 1.2346
1.234567.round(5)   #=> 1.23457

34567.89.round(-5)  #=> 0
34567.89.round(-4)  #=> 30000
34567.89.round(-3)  #=> 35000
34567.89.round(-2)  #=> 34600
34567.89.round(-1)  #=> 34570
34567.89.round(0)   #=> 34568
34567.89.round(1)   #=> 34567.9
34567.89.round(2)   #=> 34567.89
34567.89.round(3)   #=> 34567.89

إذا أُتيح وسيط الكلمة المفتاحية half الاختياري، ستُقرَّب الأرقام التي تقع في المنتصف بين قيمتين مقرَّبتين ممكنتين وفقًا للوضع mode المُحدَّد الكاسر للعلاقة:

  • ‎:up أو nil: تقريب النصف بعيدًا عن الصفر (الوضع الافتراضي).
  • ‎:down: تقريب النصف باتجاه الصفر.
  • ‎:even: تقريب النصف باتجاه أقرب عدد زوجي.
2.5.round(half: :up)      #=> 3
2.5.round(half: :down)    #=> 2
2.5.round(half: :even)    #=> 2
3.5.round(half: :up)      #=> 4
3.5.round(half: :down)    #=> 3
3.5.round(half: :even)    #=> 4
(-2.5).round(half: :up)   #=> -3
(-2.5).round(half: :down) #=> -2
(-2.5).round(half: :even) #=> -2

to_f → self

بما أن float هو بالأصل Float، يُعيد self.

               static VALUE
flo_to_f(VALUE num)
{
    return num;
}

to_i → integer

إعادة float مبتورًا إلى Integer.

1.2.to_i      #=> 1
(-1.2).to_i   #=> -1

يُلاحظ أن الدقة المحدودة للنقطة العائمة الحسابية قد تؤدي إلى نتائج مُدهشة:

(0.3 / 0.1).to_i  #=> 2 (!)

to_int هو اسم مستعار للتابع to_i.

               static VALUE
flo_to_i(VALUE num)
{
    double f = RFLOAT_VALUE(num);

    if (f > 0.0) f = floor(f);
    if (f < 0.0) f = ceil(f);

    return dbl2ival(f);
}

to_int → integer

إعادة float مبتورًا إلى Integer.

1.2.to_i      #=> 1
(-1.2).to_i   #=> -1

يُلاحظ أن الدقة المحدودة للنقطة العائمة الحسابية قد تؤدي إلى نتائج مُدهشة:

(0.3 / 0.1).to_i  #=> 2 (!)

to_int هو اسم مستعار للتابع to_i.

               static VALUE
flo_to_i(VALUE num)
{
    double f = RFLOAT_VALUE(num);

    if (f > 0.0) f = floor(f);
    if (f < 0.0) f = ceil(f);

    return dbl2ival(f);
}

to_r → rational

إعادة قيمة نسبية.

2.0.to_r    #=> (2/1)
2.5.to_r    #=> (5/2)
-0.75.to_r  #=> (-3/4)
0.0.to_r    #=> (0/1)
0.3.to_r    #=> (5404319552844595/18014398509481984)

ملاحظة: ‎0.3.to_r ليس هي نفسه ‎“0.3”.to_r. وهذا الأخير يعادل ‎"3/10".to_r، ولكن الأول ليس كذلك.

0.3.to_r   == 3/10r  #=> false
"0.3".to_r == 3/10r  #=> true

انظر أيضا ‎#rationalize.

 
               static VALUE
float_to_r(VALUE self)
{
    VALUE f, n;

    float_decode_internal(self, &f, &n);
#if FLT_RADIX == 2
    {
        long ln = FIX2LONG(n);

        if (ln == 0)
            return rb_rational_new1(f);
        if (ln > 0)
            return rb_rational_new1(rb_int_lshift(f, n));
        ln = -ln;
        return rb_rational_new2(f, rb_int_lshift(ONE, INT2FIX(ln)));
    }
#else
    f = rb_int_mul(f, rb_int_pow(INT2FIX(FLT_RADIX), n));
    if (RB_TYPE_P(f, T_RATIONAL))
        return f;
    return rb_rational_new1(f);
#endif
}

to_s → string

إعادة سلسلة تحتوي على تمثيل self. كما هو حال الشكل الثابت أو الأسي للتابع float، قد يُعيد الاستدعاء NaN و Infinity و ‎-Infinity.

 
               static VALUE
flo_to_s(VALUE flt)
{
    enum {decimal_mant = DBL_MANT_DIG-DBL_DIG};
    enum {float_dig = DBL_DIG+1};
    char buf[float_dig + (decimal_mant + CHAR_BIT - 1) / CHAR_BIT + 10];
    double value = RFLOAT_VALUE(flt);
    VALUE s;
    char *p, *e;
    int sign, decpt, digs;

    if (isinf(value)) {
        static const char minf[] = "-Infinity";
        const int pos = (value > 0); /* skip "-" */
        return rb_usascii_str_new(minf+pos, strlen(minf)-pos);
    }
    else if (isnan(value))
        return rb_usascii_str_new2("NaN");

    p = ruby_dtoa(value, 0, 0, &decpt, &sign, &e);
    s = sign ? rb_usascii_str_new_cstr("-") : rb_usascii_str_new(0, 0);
    if ((digs = (int)(e - p)) >= (int)sizeof(buf)) digs = (int)sizeof(buf) - 1;
    memcpy(buf, p, digs);
    xfree(p);
    if (decpt > 0) {
        if (decpt < digs) {
            memmove(buf + decpt + 1, buf + decpt, digs - decpt);
            buf[decpt] = '.';
            rb_str_cat(s, buf, digs + 1);
        }
        else if (decpt <= DBL_DIG) {
            long len;
            char *ptr;
            rb_str_cat(s, buf, digs);
            rb_str_resize(s, (len = RSTRING_LEN(s)) + decpt - digs + 2);
            ptr = RSTRING_PTR(s) + len;
            if (decpt > digs) {
                memset(ptr, '0', decpt - digs);
                ptr += decpt - digs;
            }
            memcpy(ptr, ".0", 2);
        }
        else {
            goto exp;
        }
    }
    else if (decpt > -4) {
        long len;
        char *ptr;
        rb_str_cat(s, "0.", 2);
        rb_str_resize(s, (len = RSTRING_LEN(s)) - decpt + digs);
        ptr = RSTRING_PTR(s);
        memset(ptr += len, '0', -decpt);
        memcpy(ptr -= decpt, buf, digs);
    }
    else {
      exp:
        if (digs > 1) {
            memmove(buf + 2, buf + 1, digs - 1);
        }
        else {
            buf[2] = '0';
            digs++;
        }
        buf[1] = '.';
        rb_str_cat(s, buf, digs + 1);
        rb_str_catf(s, "e%+03d", decpt - 1);
    }
    return s;
}

ويُعيَّن له أيضًا الاسم المستعار: inspect.

truncate([ndigits]) → integer or float

إعادة float مبتورًا (نحو الصفر) إلى دقة أرقام عشرية ndigits (القيمة الافتراضية: 0).

عندما تكون الدقة سالبة، تكون القيمة المُعادة عدد صحيح متبوعًا بعدد أصفار مقداره ndigits.abs على الأقل.

إعادة عدد عشري عندما يكون ndigits موجبًا، وإلا يُعاد عددٌ صحيحٌ.

2.8.truncate           #=> 2
(-2.8).truncate        #=> -2
1.234567.truncate(2)   #=> 1.23
34567.89.truncate(-2)  #=> 34500

يُلاحظ أن الدقة المحدودة للنقطة العائمة الحسابية قد تؤدي إلى نتائج مُدهشة:

(0.3 / 0.1).truncate  #=> 2 (!)

zero? → true or false

إعادة true إذا كان float يساوي 0.

               static VALUE
flo_zero_p(VALUE num)
{
    if (RFLOAT_VALUE(num) == 0.0) {
        return Qtrue;
    }
    return Qfalse;
}

مصادر