Class: Float
- Inherits:
-
Object
- Object
- Float
- Defined in:
- (unknown)
Class Method Summary collapse
-
.acos(x, rnd = :nearest) ⇒ Float
Returns the arc-cosine of x, rounded in the direction rnd.
-
.acosh(x, rnd = :nearest) ⇒ Float
Returns the inverse hyperbolic cosine of x, rounded in the direction rnd.
-
.add(a, b, rnd = :nearest) ⇒ Float
Add a and b, round according to rnd.
-
.asin(x, rnd = :nearest) ⇒ Float
Returns the arc-sine of x, rounded in the direction rnd.
-
.asinh(x, rnd = :nearest) ⇒ Float
Returns the inverse hyperbolic sine of x, rounded in the direction rnd.
-
.atan(x, rnd = :nearest) ⇒ Float
Returns the arc-tangent of x, rounded in the direction rnd.
-
.atan2(y, x, rnd = :nearest) ⇒ Float
Returns the arc-tangent2 of y and x, rounded in the direction rnd.
-
.atanh(x, rnd = :nearest) ⇒ Float
Returns the inverse hyperbolic tangent of x, rounded in the direction rnd.
-
.bits_to_f32(bits) ⇒ Float
Interpret bits (from a 32-bit integer) as a binary32 floating point number.
-
.bits_to_f64(bits) ⇒ Float
Interpret bits (from a 64-bit integer) as a binary64 floating point number.
-
.build_up(sign_bit, exponent_bits, fraction_bits) ⇒ Float
Build a float from its bit fields.
-
.cbrt(a, rnd = :nearest) ⇒ Float
Return the cubic root of a rounded in the direction rnd.
-
.cos(x, rnd = :nearest) ⇒ Float
Returns the cosine of x, rounded in the direction rnd.
-
.cosh(x, rnd = :nearest) ⇒ Float
Returns the hyperbolic cosine of x, rounded in the direction rnd.
-
.dim(a, b, rnd = :nearest) ⇒ Float
Returns the positive difference of a and b rounded in the direction rnd.
-
.div(a, b, rnd = :nearest) ⇒ Float
Divide a by b, rounding according to rnd.
-
.exp(x, rnd = :nearest) ⇒ Float
Returns the exponential of x, rounded in the direction rnd.
-
.exp10(x, rnd = :nearest) ⇒ Float
Returns the 10 power of x, rounded in the direction rnd.
-
.exp2(x, rnd = :nearest) ⇒ Float
Returns the 2 power of x, rounded in the direction rnd.
-
.expm1(x, rnd = :nearest) ⇒ Float
Returns the exp(x) - 1, rounded in the direction rnd.
-
.f32_to_bits(f, rnd = :nearest) ⇒ Integer
Converts the binary64 floating point number f to a binary32 floating point in the direction rnd, then returns the bits (as a 32-bit integer) constituting this 32-bit floating-point number.
-
.f64_to_bits(f) ⇒ Integer
Return the bits (as a 64-bit integer) constituting the binary64 floating point number f.
-
.fma(a, b, c, rnd = :nearest) ⇒ Float
Returns (a times b) + c rounded in the direction rnd.
-
.fmma(a, b, c, d, rnd = :nearest) ⇒ Float
Returns (a times b) + (c times d) rounded in the direction rnd.
-
.fmms(a, b, c, d, rnd = :nearest) ⇒ Float
Returns (a times b) - (c times d) rounded in the direction rnd.
-
.fms(a, b, c, rnd = :nearest) ⇒ Float
Returns (a times b) - c rounded in the direction rnd.
-
.hypot(a, b, rnd = :nearest) ⇒ Float
Returns the Euclidean norm of x and y, rounded in the direction rnd.
-
.log(x, rnd = :nearest) ⇒ Float
Returns the natural logarithm of x, rounded in the direction rnd.
-
.log10(x, rnd = :nearest) ⇒ Float
Returns the logarithm base 10 of x, rounded in the direction rnd.
-
.log1p(x, rnd = :nearest) ⇒ Float
Returns the natural logarithm of 1 + x, rounded in the direction rnd.
-
.log2(x, rnd = :nearest) ⇒ Float
Returns the logarithm base 2 of x, rounded in the direction rnd.
-
.mul(a, b, rnd = :nearest) ⇒ Float
Multiply a and b, rounding according to rnd.
-
.pow(x, y, rnd = :nearest) ⇒ Float
Returns x raised to y, rounded in the direction rnd.
-
.pown(x, n, rnd = :nearest) ⇒ Float
Returns x raised to the integer power n, rounded in the direction rnd.
-
.rootn(a, n, rnd = :nearest) ⇒ Float
Returns the n th root of a rounded in the direction rnd.
-
.sin(x, rnd = :nearest) ⇒ Float
Returns the sine of x, rounded in the direction rnd.
-
.sinh(x, rnd = :nearest) ⇒ Float
Returns the hyperbolic sine of x, rounded in the direction rnd.
-
.sqrt(a, rnd = :nearest) ⇒ Float
Return the square root of a rounded in the direction rnd.
-
.sub(a, b, rnd = :nearest) ⇒ Float
Subtract b from a, round according to rnd.
-
.tan(x, rnd = :nearest) ⇒ Float
Returns the tangent of x, rounded in the direction rnd.
-
.tanh(x, rnd = :nearest) ⇒ Float
Returns the hyperbolic tangent of x, rounded in the direction rnd.
Instance Method Summary collapse
-
#break_down ⇒ Hash{Symbol => Object}
Returns a hash containing the components of the float.
-
#subnormal? ⇒ Boolean
Tels if the float is subnormal.
-
#to_f32(rnd = :nearest) ⇒ Float
Round a Float to a binary32 in the direction rnd.
Class Method Details
.acos(x, rnd = :nearest) ⇒ Float
Returns the arc-cosine of x, rounded in the direction rnd.
Note that since Float.acos(-1.0)
returns the floating-point number
closest to pi according to the given rounding mode,
this number might not be in the output range 0 <= acos(x) < pi of the arc-cosine function;
still, the result lies in the image of the output range by the rounding function.
946 947 948 949 950 951 952 953 954 955 956 957 958 959 |
# File 'ext/crmf/crmf.c', line 946
static VALUE crmf_float_acos(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_acos(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.acosh(x, rnd = :nearest) ⇒ Float
Returns the inverse hyperbolic cosine of x, rounded in the direction rnd.
1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 |
# File 'ext/crmf/crmf.c', line 1138
static VALUE crmf_float_acosh(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_acosh(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.add(a, b, rnd = :nearest) ⇒ Float
Add a and b, round according to rnd.
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'ext/crmf/crmf.c', line 275
static VALUE crmf_float_add(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, b = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
MPFR_DECL_INIT(mpfra, 53);
MPFR_DECL_INIT(mpfrb, 53);
rb_scan_args(argc, argv, "21", &a, &b, &rnd);
crmf_rbfloat_to_mpfr53(a, mpfra);
crmf_rbfloat_to_mpfr53(b, mpfrb);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_add(mpfra, mpfra, mpfrb, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.asin(x, rnd = :nearest) ⇒ Float
Returns the arc-sine of x, rounded in the direction rnd.
Note that since Float.asin(1)
returns the floating-point number
closest to pi/2 according to the given rounding mode,
this number might not be in the output range -pi/2 <= asin(x) < pi/2 of the arc-sine function;
still, the result lies in the image of the output range by the rounding function.
The same holds for asin(-1).
973 974 975 976 977 978 979 980 981 982 983 984 985 986 |
# File 'ext/crmf/crmf.c', line 973
static VALUE crmf_float_asin(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_asin(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.asinh(x, rnd = :nearest) ⇒ Float
Returns the inverse hyperbolic sine of x, rounded in the direction rnd.
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 |
# File 'ext/crmf/crmf.c', line 1159
static VALUE crmf_float_asinh(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_asinh(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.atan(x, rnd = :nearest) ⇒ Float
Returns the arc-tangent of x, rounded in the direction rnd.
Note that since Float.atan(Float::INFINITY)
returns the floating-point number
closest to pi/2 according to the given rounding mode,
this number might not be in the output range -pi/2 <= atan(x) < pi/2 of the arc-tangent function;
still, the result lies in the image of the output range by the rounding function.
The same holds for atan(-Inf).
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 |
# File 'ext/crmf/crmf.c', line 1000
static VALUE crmf_float_atan(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_atan(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.atan2(y, x, rnd = :nearest) ⇒ Float
Returns the arc-tangent2 of y and x, rounded in the direction rnd.
- if x > 0, atan2(y, x) = atan(y/x);
- if x < 0, atan2(y, x) = sign(y)*(Pi - atan(abs(y/x))), thus a number from -Pi to Pi.
As for atan, in case the exact mathematical result is +Pi or -Pi, its rounded result might be outside the function output range.
Float.atan2(y, 0)
does not raise any floating-point exception.
Special values are handled as described in the ISO C99 and IEEE 754-2008 standards for the atan2 function:
- atan2(+0, -0) returns +Pi.
- atan2(-0, -0) returns -Pi.
- atan2(+0, +0) returns +0.
- atan2(-0, +0) returns -0.
- atan2(+0, x) returns +Pi for x < 0.
- atan2(-0, x) returns -Pi for x < 0.
- atan2(+0, x) returns +0 for x > 0.
- atan2(-0, x) returns -0 for x > 0.
- atan2(y, 0) returns -Pi/2 for y < 0.
- atan2(y, 0) returns +Pi/2 for y > 0.
- atan2(+Inf, -Inf) returns +3*Pi/4.
- atan2(-Inf, -Inf) returns -3*Pi/4.
- atan2(+Inf, +Inf) returns +Pi/4.
- atan2(-Inf, +Inf) returns -Pi/4.
- atan2(+Inf, x) returns +Pi/2 for finite x.
- atan2(-Inf, x) returns -Pi/2 for finite x.
- atan2(y, -Inf) returns +Pi for finite y > 0.
- atan2(y, -Inf) returns -Pi for finite y < 0.
- atan2(y, +Inf) returns +0 for finite y > 0.
- atan2(y, +Inf) returns -0 for finite y < 0.
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 |
# File 'ext/crmf/crmf.c', line 1052
static VALUE crmf_float_atan2(int argc, VALUE *argv, VALUE self)
{
VALUE y = Qnil, x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "21", &y, &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfry, 53);
crmf_rbfloat_to_mpfr53(y, mpfry);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_atan2(mpfrx, mpfry, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.atanh(x, rnd = :nearest) ⇒ Float
Returns the inverse hyperbolic tangent of x, rounded in the direction rnd.
1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 |
# File 'ext/crmf/crmf.c', line 1180
static VALUE crmf_float_atanh(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_atanh(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.bits_to_f32(bits) ⇒ Float
Interpret bits (from a 32-bit integer) as a binary32 floating point number.
1763 1764 1765 1766 1767 1768 1769 1770 1771 |
# File 'ext/crmf/crmf.c', line 1763
static VALUE crmf_float_bits_to_f32(VALUE self, VALUE bits)
{
uint32_t bts = NUM2ULL(bits);
union {
float f;
uint32_t u;
} fu = {.u=bts};
return DBL2NUM((double)fu.f);
}
|
.bits_to_f64(bits) ⇒ Float
Interpret bits (from a 64-bit integer) as a binary64 floating point number.
1778 1779 1780 1781 1782 1783 1784 1785 1786 |
# File 'ext/crmf/crmf.c', line 1778
static VALUE crmf_float_bits_to_f64(VALUE self, VALUE bits)
{
uint64_t bts = NUM2ULL(bits);
union {
double d;
uint64_t u;
} du = {.u=bts};
return DBL2NUM(du.d);
}
|
.build_up(sign_bit, exponent_bits, fraction_bits) ⇒ Float
Build a float from its bit fields.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'ext/crmf/crmf.c', line 135
static VALUE crmf_float_build_up(VALUE self, VALUE sign_bit, VALUE exponent_bits, VALUE fraction_bits)
{
long long sb, eb, fb;
union {
double d;
unsigned long long l;
} dudul;
if (!rb_integer_type_p(sign_bit))
rb_raise(rb_eTypeError, "expecting an integer as sign bit, not a %s", rb_obj_classname(sign_bit));
sb = NUM2LL(sign_bit);
if ((sb & 0xfffffffffffffffeULL) != 0)
rb_raise(rb_eArgError, "sign bit must be 0 or 1");
if (!rb_integer_type_p(exponent_bits))
rb_raise(rb_eTypeError, "expecting an integer as exponent bits, not a %s", rb_obj_classname(exponent_bits));
eb = NUM2LL(exponent_bits);
if ((eb & 0xfffffffffffff800ULL) != 0)
rb_raise(rb_eArgError, "exponent bits must be between 0 and 2047");
if (!rb_integer_type_p(fraction_bits))
rb_raise(rb_eTypeError, "expecting an integer as fraction bits, not a %s", rb_obj_classname(fraction_bits));
fb = NUM2LL(fraction_bits);
if ((fb & 0xfff0000000000000ULL) != 0)
rb_raise(rb_eArgError, "fraction bits must be between 0 and 4503599627370495");
dudul.l = (sb << 63) | (eb << 52) | fb;
return DBL2NUM(dudul.d);
}
|
.cbrt(a, rnd = :nearest) ⇒ Float
Return the cubic root of a rounded in the direction rnd.
393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'ext/crmf/crmf.c', line 393
static VALUE crmf_float_cbrt(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &a, &rnd);
MPFR_DECL_INIT(mpfra, 53);
crmf_rbfloat_to_mpfr53(a, mpfra);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_cbrt(mpfra, mpfra, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.cos(x, rnd = :nearest) ⇒ Float
Returns the cosine of x, rounded in the direction rnd.
878 879 880 881 882 883 884 885 886 887 888 889 890 891 |
# File 'ext/crmf/crmf.c', line 878
static VALUE crmf_float_cos(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_cos(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.cosh(x, rnd = :nearest) ⇒ Float
Returns the hyperbolic cosine of x, rounded in the direction rnd.
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 |
# File 'ext/crmf/crmf.c', line 1075
static VALUE crmf_float_cosh(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_cosh(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.dim(a, b, rnd = :nearest) ⇒ Float
Returns the positive difference of a and b rounded in the direction rnd. That is a - b if a > b, +0 if a <= b, and NaN if a or b is NaN.
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 |
# File 'ext/crmf/crmf.c', line 452
static VALUE crmf_float_dim(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, b = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "21", &a, &b, &rnd);
MPFR_DECL_INIT(mpfra, 53);
MPFR_DECL_INIT(mpfrb, 53);
crmf_rbfloat_to_mpfr53(a, mpfra);
crmf_rbfloat_to_mpfr53(b, mpfrb);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_dim(mpfra, mpfra, mpfrb, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.div(a, b, rnd = :nearest) ⇒ Float
Divide a by b, rounding according to rnd.
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'ext/crmf/crmf.c', line 347
static VALUE crmf_float_div(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, b = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
MPFR_DECL_INIT(mpfra, 53);
MPFR_DECL_INIT(mpfrb, 53);
rb_scan_args(argc, argv, "21", &a, &b, &rnd);
crmf_rbfloat_to_mpfr53(a, mpfra);
crmf_rbfloat_to_mpfr53(b, mpfrb);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_div(mpfra, mpfra, mpfrb, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.exp(x, rnd = :nearest) ⇒ Float
Returns the exponential of x, rounded in the direction rnd.
715 716 717 718 719 720 721 722 723 724 725 726 727 728 |
# File 'ext/crmf/crmf.c', line 715
static VALUE crmf_float_exp(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_exp(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.exp10(x, rnd = :nearest) ⇒ Float
Returns the 10 power of x, rounded in the direction rnd.
757 758 759 760 761 762 763 764 765 766 767 768 769 770 |
# File 'ext/crmf/crmf.c', line 757
static VALUE crmf_float_exp10(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_exp10(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.exp2(x, rnd = :nearest) ⇒ Float
Returns the 2 power of x, rounded in the direction rnd.
736 737 738 739 740 741 742 743 744 745 746 747 748 749 |
# File 'ext/crmf/crmf.c', line 736
static VALUE crmf_float_exp2(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_exp2(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.expm1(x, rnd = :nearest) ⇒ Float
Returns the exp(x) - 1, rounded in the direction rnd.
778 779 780 781 782 783 784 785 786 787 788 789 790 791 |
# File 'ext/crmf/crmf.c', line 778
static VALUE crmf_float_expm1(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_expm1(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.f32_to_bits(f, rnd = :nearest) ⇒ Integer
Converts the binary64 floating point number f to a binary32 floating point in the direction rnd, then returns the bits (as a 32-bit integer) constituting this 32-bit floating-point number.
1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 |
# File 'ext/crmf/crmf.c', line 1811
static VALUE crmf_float_f32_to_bits(int argc, VALUE *argv, VALUE self)
{
VALUE f;
VALUE rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &f, &rnd);
if (rnd != Qnil) {
rndt = crmf_sym_to_rnd(rnd);
}
double d = NUM2DBL(f);
MPFR_DECL_INIT(mp, 53);
mpfr_set_d(mp, d, rndt);
float flt = mpfr_get_flt(mp, rndt);
union {
float f;
uint32_t u;
} fu = {.f=flt};
return UINT2NUM(fu.u);
}
|
.f64_to_bits(f) ⇒ Integer
Return the bits (as a 64-bit integer) constituting the binary64 floating point number f.
1793 1794 1795 1796 1797 1798 1799 1800 1801 |
# File 'ext/crmf/crmf.c', line 1793
static VALUE crmf_float_f64_to_bits(VALUE self, VALUE f)
{
double d = NUM2DBL(f);
union {
double d;
uint64_t u;
} du = {.d=d};
return ULL2NUM(du.u);
}
|
.fma(a, b, c, rnd = :nearest) ⇒ Float
Returns (a times b) + c rounded in the direction rnd. Concerning special values (signed zeros, infinities, NaN), these functions behave like a multiplication followed by a separate addition or subtraction. That is, the fused operation matters only for rounding.
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
# File 'ext/crmf/crmf.c', line 479
static VALUE crmf_float_fma(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, b = Qnil, c = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "31", &a, &b, &c, &rnd);
MPFR_DECL_INIT(mpfra, 53);
MPFR_DECL_INIT(mpfrb, 53);
MPFR_DECL_INIT(mpfrc, 53);
crmf_rbfloat_to_mpfr53(a, mpfra);
crmf_rbfloat_to_mpfr53(b, mpfrb);
crmf_rbfloat_to_mpfr53(c, mpfrc);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_fma(mpfra, mpfra, mpfrb, mpfrc, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.fmma(a, b, c, d, rnd = :nearest) ⇒ Float
Returns (a times b) + (c times d) rounded in the direction rnd. In case the computation of a times b overflows or underflows (or that of c times d), the result is computed as if the two intermediate products were computed with rounding toward zero.
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 |
# File 'ext/crmf/crmf.c', line 538
static VALUE crmf_float_fmma(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, b = Qnil, c = Qnil, d = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "41", &a, &b, &c, &d, &rnd);
MPFR_DECL_INIT(mpfra, 53);
MPFR_DECL_INIT(mpfrb, 53);
MPFR_DECL_INIT(mpfrc, 53);
MPFR_DECL_INIT(mpfrd, 53);
crmf_rbfloat_to_mpfr53(a, mpfra);
crmf_rbfloat_to_mpfr53(b, mpfrb);
crmf_rbfloat_to_mpfr53(c, mpfrc);
crmf_rbfloat_to_mpfr53(d, mpfrd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_fmma(mpfra, mpfra, mpfrb, mpfrc, mpfrd, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double r = mpfr_get_d(mpfra, rndt);
return DBL2NUM(r);
}
|
.fmms(a, b, c, d, rnd = :nearest) ⇒ Float
Returns (a times b) - (c times d) rounded in the direction rnd. In case the computation of a times b overflows or underflows (or that of c times d), the result is computed as if the two intermediate products were computed with rounding toward zero.
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 |
# File 'ext/crmf/crmf.c', line 570
static VALUE crmf_float_fmms(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, b = Qnil, c = Qnil, d = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "41", &a, &b, &c, &d, &rnd);
MPFR_DECL_INIT(mpfra, 53);
MPFR_DECL_INIT(mpfrb, 53);
MPFR_DECL_INIT(mpfrc, 53);
MPFR_DECL_INIT(mpfrd, 53);
crmf_rbfloat_to_mpfr53(a, mpfra);
crmf_rbfloat_to_mpfr53(b, mpfrb);
crmf_rbfloat_to_mpfr53(c, mpfrc);
crmf_rbfloat_to_mpfr53(d, mpfrd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_fmms(mpfra, mpfra, mpfrb, mpfrc, mpfrd, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double r = mpfr_get_d(mpfra, rndt);
return DBL2NUM(r);
}
|
.fms(a, b, c, rnd = :nearest) ⇒ Float
Returns (a times b) - c rounded in the direction rnd. Concerning special values (signed zeros, infinities, NaN), these functions behave like a multiplication followed by a separate addition or subtraction. That is, the fused operation matters only for rounding.
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
# File 'ext/crmf/crmf.c', line 508
static VALUE crmf_float_fms(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, b = Qnil, c = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "31", &a, &b, &c, &rnd);
MPFR_DECL_INIT(mpfra, 53);
MPFR_DECL_INIT(mpfrb, 53);
MPFR_DECL_INIT(mpfrc, 53);
crmf_rbfloat_to_mpfr53(a, mpfra);
crmf_rbfloat_to_mpfr53(b, mpfrb);
crmf_rbfloat_to_mpfr53(c, mpfrc);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_fms(mpfra, mpfra, mpfrb, mpfrc, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.hypot(a, b, rnd = :nearest) ⇒ Float
Returns the Euclidean norm of x and y, rounded in the direction rnd. That is, the square root of the sum of the squares of x and y. Special values are handled as described in the ISO C99 (Section F.9.4.3) and IEEE 754-2008 (Section 9.2.1) standards: If x or y is an infinity, then +Inf is returned, even if the other number is NaN.
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 |
# File 'ext/crmf/crmf.c', line 601
static VALUE crmf_float_hypot(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, b = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "21", &a, &b, &rnd);
MPFR_DECL_INIT(mpfra, 53);
MPFR_DECL_INIT(mpfrb, 53);
crmf_rbfloat_to_mpfr53(a, mpfra);
crmf_rbfloat_to_mpfr53(b, mpfrb);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_hypot(mpfra, mpfra, mpfrb, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.log(x, rnd = :nearest) ⇒ Float
Returns the natural logarithm of x, rounded in the direction rnd. Returns +0 if x is 1 (in all rounding modes), for consistency with the ISO C99 and IEEE 754-2008 standards. Returns -Inf if x is ±0 (i.e., the sign of the zero has no influence on the result).
626 627 628 629 630 631 632 633 634 635 636 637 638 639 |
# File 'ext/crmf/crmf.c', line 626
static VALUE crmf_float_log(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_log(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.log10(x, rnd = :nearest) ⇒ Float
Returns the logarithm base 10 of x, rounded in the direction rnd. Returns +0 if x is 1 (in all rounding modes), for consistency with the ISO C99 and IEEE 754-2008 standards. Returns -Inf if x is ±0 (i.e., the sign of the zero has no influence on the result).
672 673 674 675 676 677 678 679 680 681 682 683 684 685 |
# File 'ext/crmf/crmf.c', line 672
static VALUE crmf_float_log10(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_log10(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.log1p(x, rnd = :nearest) ⇒ Float
Returns the natural logarithm of 1 + x, rounded in the direction rnd. Returns +0 if x is -1.
694 695 696 697 698 699 700 701 702 703 704 705 706 707 |
# File 'ext/crmf/crmf.c', line 694
static VALUE crmf_float_log1p(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_log1p(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.log2(x, rnd = :nearest) ⇒ Float
Returns the logarithm base 2 of x, rounded in the direction rnd. Returns +0 if x is 1 (in all rounding modes), for consistency with the ISO C99 and IEEE 754-2008 standards. Returns -Inf if x is ±0 (i.e., the sign of the zero has no influence on the result).
649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
# File 'ext/crmf/crmf.c', line 649
static VALUE crmf_float_log2(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_log2(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.mul(a, b, rnd = :nearest) ⇒ Float
Multiply a and b, rounding according to rnd.
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
# File 'ext/crmf/crmf.c', line 323
static VALUE crmf_float_mul(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, b = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
MPFR_DECL_INIT(mpfra, 53);
MPFR_DECL_INIT(mpfrb, 53);
rb_scan_args(argc, argv, "21", &a, &b, &rnd);
crmf_rbfloat_to_mpfr53(a, mpfra);
crmf_rbfloat_to_mpfr53(b, mpfrb);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_mul(mpfra, mpfra, mpfrb, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.pow(x, y, rnd = :nearest) ⇒ Float
Returns x raised to y, rounded in the direction rnd.
Special values are handled as described in the ISO C99 and IEEE 754-2008 standards for the pow function:
- pow(±0, y) returns plus or minus infinity for y a negative odd integer.
- pow(±0, y) returns plus infinity for y negative and not an odd integer.
- pow(±0, y) returns plus or minus zero for y a positive odd integer.
- pow(±0, y) returns plus zero for y positive and not an odd integer.
- pow(-1, ±Inf) returns 1.
- pow(+1, y) returns 1 for any y, even a NaN.
- pow(x, ±0) returns 1 for any x, even a NaN.
- pow(x, y) returns NaN for finite negative x and finite non-integer y.
- pow(x, -Inf) returns plus infinity for 0 < abs(x) < 1, and plus zero for abs(x) > 1.
- pow(x, +Inf) returns plus zero for 0 < abs(x) < 1, and plus infinity for abs(x) > 1.
- pow(-Inf, y) returns minus zero for y a negative odd integer.
- pow(-Inf, y) returns plus zero for y negative and not an odd integer.
- pow(-Inf, y) returns minus infinity for y a positive odd integer.
- pow(-Inf, y) returns plus infinity for y positive and not an odd integer.
- pow(+Inf, y) returns plus zero for y negative, and plus infinity for y positive.
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 |
# File 'ext/crmf/crmf.c', line 817
static VALUE crmf_float_pow(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, y = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "21", &x, &y, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
MPFR_DECL_INIT(mpfry, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
crmf_rbfloat_to_mpfr53(y, mpfry);
int t = mpfr_pow(mpfrx, mpfrx, mpfry, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.pown(x, n, rnd = :nearest) ⇒ Float
Returns x raised to the integer power n, rounded in the direction rnd.
Special values are handled as described in the ISO C99 and IEEE 754-2008 standards for the pow function:
- pow(±0, n) returns plus or minus infinity for n a negative odd integer.
- pow(±0, n) returns plus infinity for n negative and not an odd integer.
- pow(±0, n) returns plus or minus zero for n a positive odd integer.
- pow(±0, n) returns plus zero for n positive and not an odd integer.
- pow(+1, n) returns 1 for any n.
- pow(x, 0) returns 1 for any x, even a NaN.
- pow(-Inf, n) returns minus zero for n negative and odd.
- pow(-Inf, n) returns plus zero for n negative and even.
- pow(-Inf, n) returns minus infinity for n positive and odd.
- pow(-Inf, n) returns plus infinity for n positive and even.
- pow(+Inf, n) returns plus zero for n negative, and plus infinity for n positive.
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 |
# File 'ext/crmf/crmf.c', line 854
static VALUE crmf_float_pown(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, n = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "21", &x, &n, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
if (!rb_integer_type_p(n))
rb_raise(rb_eTypeError, "expecting an integer as second argument, not a %s", rb_obj_classname(n));
long int nn = NUM2LL(n);
int t = mpfr_pow_si(mpfrx, mpfrx, nn, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.rootn(a, n, rnd = :nearest) ⇒ Float
Returns the n th root of a rounded in the direction rnd. For n = 0, returns NaN. For n odd (resp. even) and a negative (including −Inf), returns a negative number (resp. NaN). If a is zero, returns zero with the sign obtained by the usual limit rules, i.e., the same sign as a if n is odd, and negative if n is even.
This functions agree with the rootn
function of the IEEE 754-2008 standard and
the P754/D2.41 draft of the next standard (Section 9.2).
Note that it is here restricted to n >= 0.
Functions allowing a negative n may be implemented in the future.
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 |
# File 'ext/crmf/crmf.c', line 424
static VALUE crmf_float_rootn(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, n = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "21", &a, &n, &rnd);
MPFR_DECL_INIT(mpfra, 53);
crmf_rbfloat_to_mpfr53(a, mpfra);
if (!rb_integer_type_p(n))
rb_raise(rb_eTypeError, "expecting an integer as second argument, not a %s", rb_obj_classname(n));
if (rb_funcall(n, id_syminf, 1, INT2NUM(0)) == Qtrue)
rb_raise(rb_eRangeError, "n must be >= 0, not %" PRIsVALUE, n);
unsigned long int nn = NUM2ULL(n);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_rootn_ui(mpfra, mpfra, nn, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.sin(x, rnd = :nearest) ⇒ Float
Returns the sine of x, rounded in the direction rnd.
899 900 901 902 903 904 905 906 907 908 909 910 911 912 |
# File 'ext/crmf/crmf.c', line 899
static VALUE crmf_float_sin(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_sin(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.sinh(x, rnd = :nearest) ⇒ Float
Returns the hyperbolic sine of x, rounded in the direction rnd.
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 |
# File 'ext/crmf/crmf.c', line 1096
static VALUE crmf_float_sinh(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_sinh(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.sqrt(a, rnd = :nearest) ⇒ Float
Return the square root of a rounded in the direction rnd. Returns −0 if a is −0, to be consistent with the IEEE 754 standard. Returns NaN if op is negative.
372 373 374 375 376 377 378 379 380 381 382 383 384 385 |
# File 'ext/crmf/crmf.c', line 372
static VALUE crmf_float_sqrt(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &a, &rnd);
MPFR_DECL_INIT(mpfra, 53);
crmf_rbfloat_to_mpfr53(a, mpfra);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_sqrt(mpfra, mpfra, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.sub(a, b, rnd = :nearest) ⇒ Float
Subtract b from a, round according to rnd.
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
# File 'ext/crmf/crmf.c', line 299
static VALUE crmf_float_sub(int argc, VALUE *argv, VALUE self)
{
VALUE a = Qnil, b = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
MPFR_DECL_INIT(mpfra, 53);
MPFR_DECL_INIT(mpfrb, 53);
rb_scan_args(argc, argv, "21", &a, &b, &rnd);
crmf_rbfloat_to_mpfr53(a, mpfra);
crmf_rbfloat_to_mpfr53(b, mpfrb);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
int t = mpfr_sub(mpfra, mpfra, mpfrb, rndt);
mpfr_subnormalize(mpfra, t, rndt);
double d = mpfr_get_d(mpfra, rndt);
return DBL2NUM(d);
}
|
.tan(x, rnd = :nearest) ⇒ Float
Returns the tangent of x, rounded in the direction rnd.
920 921 922 923 924 925 926 927 928 929 930 931 932 933 |
# File 'ext/crmf/crmf.c', line 920
static VALUE crmf_float_tan(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_tan(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
.tanh(x, rnd = :nearest) ⇒ Float
Returns the hyperbolic tangent of x, rounded in the direction rnd.
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 |
# File 'ext/crmf/crmf.c', line 1117
static VALUE crmf_float_tanh(int argc, VALUE *argv, VALUE self)
{
VALUE x = Qnil, rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "11", &x, &rnd);
if (rnd != Qnil)
rndt = crmf_sym_to_rnd(rnd);
MPFR_DECL_INIT(mpfrx, 53);
crmf_rbfloat_to_mpfr53(x, mpfrx);
int t = mpfr_tanh(mpfrx, mpfrx, rndt);
mpfr_subnormalize(mpfrx, t, rndt);
double d = mpfr_get_d(mpfrx, rndt);
return DBL2NUM(d);
}
|
Instance Method Details
#break_down ⇒ Hash{Symbol => Object}
Returns a hash containing the components of the float.
The returned hash contains the folowing fields:
- :sign_bit An integer: 0 for positive, 1 for negative. Corresponds to bit 63.
- :exponent_bits The biased exponent as an integer. Corresponds to bits 62 downto 52.
- :fraction_bits The stored fraction bits (without the implicit leading 1). Corresponds to bits 51 downto 0.
- :sign An integer: 1 for positive, -1 for negative
- :flag A symbol, either :nan, :infinite, :zero, :subnormal or nil.
- :exponent The unbiased exponent as an integer.
- :isignificand An integer corresponding to fraction_bits plus the leading implicit 1 if not a subnormal.
- :significand The significand part as a float, in the range [1.0, 2.0[, or less than 1.0 if the number is subnormal.
The number can be retreived with sign * 2**exponent * significand
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'ext/crmf/crmf.c', line 65
static VALUE crmf_float_break_down(VALUE self)
{
union {
double d;
unsigned long long l;
} dudul;
dudul.d = NUM2DBL(self);
unsigned long long sign = (dudul.l >> 63) & 1;
unsigned long long expo = (dudul.l >> 52) & 0x7ff;
unsigned long long frac = dudul.l & 0x000fffffffffffffULL;
VALUE h = rb_hash_new();
rb_hash_aset(h, rb_id2sym(id_sign_bit), ULL2NUM(sign));
rb_hash_aset(h, rb_id2sym(id_exponent_bits), RB_ULL2NUM(expo));
rb_hash_aset(h, rb_id2sym(id_fraction_bits), RB_ULL2NUM(frac));
rb_hash_aset(h, rb_id2sym(id_sign), INT2NUM((sign == 0) ? 1 : -1));
if (expo == 0x7ffULL) {
if (frac == 0ULL) // Infinity
rb_hash_aset(h, rb_id2sym(id_flag), rb_id2sym(id_infinity));
else // NaN
rb_hash_aset(h, rb_id2sym(id_flag), rb_id2sym(id_nan));
}
else if (expo == 0ULL) {
if (frac == 0ULL) { // Zero
rb_hash_aset(h, rb_id2sym(id_flag), rb_id2sym(id_zero));
rb_hash_aset(h, rb_id2sym(id_isignificand), INT2NUM(0));
rb_hash_aset(h, rb_id2sym(id_exponent), INT2NUM(-1022));
rb_hash_aset(h, rb_id2sym(id_significand), DBL2NUM(0.0));
}
else { // Subnormal
rb_hash_aset(h, rb_id2sym(id_flag), rb_id2sym(id_subnormal));
rb_hash_aset(h, rb_id2sym(id_isignificand), RB_ULL2NUM(frac));
rb_hash_aset(h, rb_id2sym(id_exponent), INT2NUM(-1022));
expo = 1023;
while ((frac & 0x0010000000000000ULL) == 0ULL) {
frac <<= 1;
expo -= 1;
}
dudul.l = (expo << 52) | (frac & 0x000fffffffffffffULL);
rb_hash_aset(h, rb_id2sym(id_significand), DBL2NUM(dudul.d));
}
}
else {
rb_hash_aset(h, rb_id2sym(id_flag), Qnil);
rb_hash_aset(h, rb_id2sym(id_isignificand), ULL2NUM(frac | 0x10000000000000ULL));
rb_hash_aset(h, rb_id2sym(id_exponent), INT2NUM((int)expo - 1023));
dudul.l &= 0x000fffffffffffffULL;
dudul.l |= 0x3ff0000000000000ULL;
rb_hash_aset(h, rb_id2sym(id_significand), DBL2NUM(dudul.d));
}
return h;
}
|
#subnormal? ⇒ Boolean
Tels if the float is subnormal. That is, if its biased exponent is 0 and its fraction part is not null.
171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'ext/crmf/crmf.c', line 171
static VALUE crmf_float_is_subnormal(VALUE self)
{
union dul {
double d;
unsigned long long l;
} dudul;
dudul.d = NUM2DBL(self);
unsigned long long expo = (dudul.l >> 52) & 0x7ff;
unsigned long long frac = dudul.l & 0x000fffffffffffffULL;
if (expo == 0ULL && frac != 0ULL)
return Qtrue;
return Qfalse;
}
|
#to_f32(rnd = :nearest) ⇒ Float
Round a Float to a binary32 in the direction rnd.
1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 |
# File 'ext/crmf/crmf.c', line 1744
static VALUE crmf_float_to_f32(int argc, VALUE *argv, VALUE self)
{
VALUE rnd = Qnil;
mpfr_rnd_t rndt = MPFR_RNDN;
rb_scan_args(argc, argv, "01", &rnd);
if (rnd != Qnil) {
rndt = crmf_sym_to_rnd(rnd);
}
MPFR_DECL_INIT(mp, 53);
mpfr_set_d(mp, NUM2DBL(self), rndt);
float f = mpfr_get_flt(mp, rndt);
return DBL2NUM((double)f);
}
|