Class: OraNumber

Inherits:
Numeric show all
Includes:
Comparable
Defined in:
lib/oci8/oci8.rb,
ext/oci8/ocinumber.c

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Numeric

#to_onum

Class Method Details

._load(string) ⇒ Object

Unmarshal a dumped OraNumber object.



1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
# File 'ext/oci8/ocinumber.c', line 1335

static VALUE
onum_s_load(VALUE klass, VALUE str)
{
    unsigned char *c;
    int size;
    OCINumber num;

    Check_Type(str, T_STRING);
    c = RSTRING_ORATEXT(str);
    size = RSTRING_LEN(str);
    if (size == 0 || size != c[0] + 1 || size > sizeof(num)) {
        rb_raise(rb_eTypeError, "marshaled OCI::Number format differ");
    }
    memset(&num, 0, sizeof(num));
    memcpy(&num, c, size);
    return oci8_make_ocinumber(&num, oci8_errhp);
}

Instance Method Details

#%(other) ⇒ Object

Returns the modulo after division of onum by other.



851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
# File 'ext/oci8/ocinumber.c', line 851

static VALUE onum_mod(VALUE lhs, VALUE rhs)
{
    OCIError *errhp = oci8_errhp;
    OCINumber n;
    OCINumber r;
    boolean is_zero;

    /* change to OCINumber */
    if (!set_oci_number_from_num(&n, rhs, 0, errhp))
        return rb_num_coerce_bin(lhs, rhs, '%');
    /* check whether argument is not zero. */
    oci_lc(OCINumberIsZero(errhp, &n, &is_zero));
    if (is_zero)
        rb_num_zerodiv();
    /* modulo */
    oci_lc(OCINumberMod(errhp, _NUMBER(lhs), &n, &r));
    return oci8_make_ocinumber(&r, errhp);
}

#*(other) ⇒ Numeric

Returns the product of onum and other.

Returns:



776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
# File 'ext/oci8/ocinumber.c', line 776

static VALUE onum_mul(VALUE lhs, VALUE rhs)
{
    OCIError *errhp = oci8_errhp;
    OCINumber n;
    OCINumber r;

    switch (rboci8_type(rhs)) {
    case T_FIXNUM:
    case T_BIGNUM:
        if (set_oci_number_from_num(&n, rhs, 0, errhp)) {
            oci_lc(OCINumberMul(errhp, _NUMBER(lhs), &n, &r));
            return oci8_make_ocinumber(&r, errhp);
        }
        break;
    case RBOCI8_T_ORANUMBER:
        oci_lc(OCINumberMul(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
        return oci8_make_ocinumber(&r, errhp);
    case T_FLOAT:
        return rb_funcall(onum_to_f(lhs), oci8_id_mul_op, 1, rhs);
    case RBOCI8_T_RATIONAL:
        return rb_funcall(onum_to_r(lhs), oci8_id_mul_op, 1, rhs);
    case RBOCI8_T_BIGDECIMAL:
        return rb_funcall(onum_to_d(lhs), oci8_id_mul_op, 1, rhs);
    }
    return rb_num_coerce_bin(lhs, rhs, oci8_id_mul_op);
}

#**(other) ⇒ Object

Raises onum the other power.



876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
# File 'ext/oci8/ocinumber.c', line 876

static VALUE onum_power(VALUE lhs, VALUE rhs)
{
    OCIError *errhp = oci8_errhp;
    OCINumber n;
    OCINumber r;

    if (FIXNUM_P(rhs)) {
        oci_lc(OCINumberIntPower(errhp, _NUMBER(lhs), FIX2INT(rhs), &r));
    } else {
        /* change to OCINumber */
        if (!set_oci_number_from_num(&n, rhs, 0, errhp))
            return rb_num_coerce_bin(lhs, rhs, id_power);
        oci_lc(OCINumberPower(errhp, _NUMBER(lhs), &n, &r));
    }
    return oci8_make_ocinumber(&r, errhp);
}

#+(other) ⇒ Numeric

Returns the sum of onum and other.

Returns:



709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
# File 'ext/oci8/ocinumber.c', line 709

static VALUE onum_add(VALUE lhs, VALUE rhs)
{
    OCIError *errhp = oci8_errhp;
    OCINumber n;
    OCINumber r;

    switch (rboci8_type(rhs)) {
    case T_FIXNUM:
    case T_BIGNUM:
        if (set_oci_number_from_num(&n, rhs, 0, errhp)) {
            oci_lc(OCINumberAdd(errhp, _NUMBER(lhs), &n, &r));
            return oci8_make_ocinumber(&r, errhp);
        }
        break;
    case RBOCI8_T_ORANUMBER:
        oci_lc(OCINumberAdd(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
        return oci8_make_ocinumber(&r, errhp);
    case T_FLOAT:
        return rb_funcall(onum_to_f(lhs), oci8_id_add_op, 1, rhs);
    case RBOCI8_T_RATIONAL:
        return rb_funcall(onum_to_r(lhs), oci8_id_add_op, 1, rhs);
    case RBOCI8_T_BIGDECIMAL:
        return rb_funcall(onum_to_d(lhs), oci8_id_add_op, 1, rhs);
    }
    return rb_num_coerce_bin(lhs, rhs, oci8_id_add_op);
}

#-(integer) ⇒ Object #-(numeric) ⇒ Numeric

Returns the difference of onum and other.

Overloads:



743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
# File 'ext/oci8/ocinumber.c', line 743

static VALUE onum_sub(VALUE lhs, VALUE rhs)
{
    OCIError *errhp = oci8_errhp;
    OCINumber n;
    OCINumber r;

    switch (rboci8_type(rhs)) {
    case T_FIXNUM:
    case T_BIGNUM:
        if (set_oci_number_from_num(&n, rhs, 0, errhp)) {
            oci_lc(OCINumberSub(errhp, _NUMBER(lhs), &n, &r));
            return oci8_make_ocinumber(&r, errhp);
        }
        break;
    case RBOCI8_T_ORANUMBER:
        oci_lc(OCINumberSub(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
        return oci8_make_ocinumber(&r, errhp);
    case T_FLOAT:
        return rb_funcall(onum_to_f(lhs), oci8_id_sub_op, 1, rhs);
    case RBOCI8_T_RATIONAL:
        return rb_funcall(onum_to_r(lhs), oci8_id_sub_op, 1, rhs);
    case RBOCI8_T_BIGDECIMAL:
        return rb_funcall(onum_to_d(lhs), oci8_id_sub_op, 1, rhs);
    }
    return rb_num_coerce_bin(lhs, rhs, oci8_id_sub_op);
}

#-Object

Returns a negated OraNumber.



693
694
695
696
697
698
699
700
# File 'ext/oci8/ocinumber.c', line 693

static VALUE onum_neg(VALUE self)
{
    OCIError *errhp = oci8_errhp;
    OCINumber r;

    oci_lc(OCINumberNeg(errhp, _NUMBER(self), &r));
    return oci8_make_ocinumber(&r, errhp);
}

#/(integer) ⇒ Object #/(numeric) ⇒ Numeric

Returns the result of dividing onum by other.

Overloads:



810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
# File 'ext/oci8/ocinumber.c', line 810

static VALUE onum_div(VALUE lhs, VALUE rhs)
{
    OCIError *errhp = oci8_errhp;
    OCINumber n;
    OCINumber r;
    boolean is_zero;

    switch (rboci8_type(rhs)) {
    case T_FIXNUM:
        if (rhs == INT2FIX(0)) {
            rb_num_zerodiv();
        }
    case T_BIGNUM:
        if (set_oci_number_from_num(&n, rhs, 0, errhp)) {
            oci_lc(OCINumberDiv(errhp, _NUMBER(lhs), &n, &r));
            return oci8_make_ocinumber(&r, errhp);
        }
        break;
    case RBOCI8_T_ORANUMBER:
        oci_lc(OCINumberIsZero(errhp, _NUMBER(rhs), &is_zero));
        if (is_zero) {
            rb_num_zerodiv();
        }
        oci_lc(OCINumberDiv(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
        return oci8_make_ocinumber(&r, errhp);
    case T_FLOAT:
        return rb_funcall(onum_to_f(lhs), oci8_id_div_op, 1, rhs);
    case RBOCI8_T_RATIONAL:
        return rb_funcall(onum_to_r(lhs), oci8_id_div_op, 1, rhs);
    case RBOCI8_T_BIGDECIMAL:
        return rb_funcall(onum_to_d(lhs), oci8_id_div_op, 1, rhs);
    }
    return rb_num_coerce_bin(lhs, rhs, oci8_id_div_op);
}

#<=>(other) ⇒ -1, ...

Returns -1, 0, or +1 depending on whether onum is less than, equal to, or greater than other. This is the basis for the tests in Comparable.

Returns:

  • (-1, 0, +1)


901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
# File 'ext/oci8/ocinumber.c', line 901

static VALUE onum_cmp(VALUE lhs, VALUE rhs)
{
    OCIError *errhp = oci8_errhp;
    OCINumber n;
    sword r;

    /* change to OCINumber */
    if (!set_oci_number_from_num(&n, rhs, 0, errhp))
        return rb_num_coerce_cmp(lhs, rhs, id_cmp);
    /* compare */
    oci_lc(OCINumberCmp(errhp, _NUMBER(lhs), &n, &r));
    if (r > 0) {
        return INT2FIX(1);
    } else if (r == 0) {
        return INT2FIX(0);
    } else {
        return INT2FIX(-1);
    }
}

#_dumpString

Dump onum for marshaling.

Returns:



1319
1320
1321
1322
1323
1324
1325
1326
1327
# File 'ext/oci8/ocinumber.c', line 1319

static VALUE onum__dump(int argc, VALUE *argv, VALUE self)
{
    char *c  = DATA_PTR(self);
    int size = c[0] + 1;
    VALUE dummy;

    rb_scan_args(argc, argv, "01", &dummy);
    return rb_str_new(c, size);
}

#absObject

Returns the absolute value of onum.



1241
1242
1243
1244
1245
1246
1247
1248
# File 'ext/oci8/ocinumber.c', line 1241

static VALUE onum_abs(VALUE self)
{
    OCIError *errhp = oci8_errhp;
    OCINumber result;

    oci_lc(OCINumberAbs(errhp, _NUMBER(self), &result));
    return oci8_make_ocinumber(&result, errhp);
}

#ceilInteger

Returns the smallest Integer greater than or equal to onum.

Returns:

  • (Integer)


943
944
945
946
947
948
949
950
# File 'ext/oci8/ocinumber.c', line 943

static VALUE onum_ceil(VALUE self)
{
    OCIError *errhp = oci8_errhp;
    OCINumber r;

    oci_lc(OCINumberCeil(errhp, _NUMBER(self), &r));
    return oci8_make_integer(&r, errhp);
}

#dumpString

Returns internal representation whose format is same with the return value of Oracle SQL function DUMP().

OraNumber.new(100).dump  #=> "Typ=2 Len=2: 194,2"
OraNumber.new(123).dump  #=> "Typ=2 Len=3: 194,2,24"
OraNumber.new(0.1).dump  #=> "Typ=2 Len=2: 192,11"

Returns:



1277
1278
1279
1280
1281
1282
# File 'ext/oci8/ocinumber.c', line 1277

static VALUE onum_dump(VALUE self)
{
    char buf[ORANUMBER_DUMP_BUF_SIZ];
    int rv = oranumber_dump(_NUMBER(self), buf);
    return rb_usascii_str_new(buf, rv);
}

#encode_with(coder) ⇒ Object

:nodoc:



551
552
553
# File 'lib/oci8/oci8.rb', line 551

def encode_with coder # :nodoc:
  coder.scalar = self.to_s
end

#floorInteger

Returns the largest Integer less than or equal to onum.

Returns:

  • (Integer)


927
928
929
930
931
932
933
934
# File 'ext/oci8/ocinumber.c', line 927

static VALUE onum_floor(VALUE self)
{
    OCIError *errhp = oci8_errhp;
    OCINumber r;

    oci_lc(OCINumberFloor(errhp, _NUMBER(self), &r));
    return oci8_make_integer(&r, errhp);
}

#has_decimal_part?Boolean

Returns true if self has a decimal part.

OraNumber(10).has_decimal_part?   # => false
OraNumber(10.1).has_decimal_part? # => true

Returns:

  • (Boolean)


1197
1198
1199
1200
1201
1202
1203
1204
# File 'ext/oci8/ocinumber.c', line 1197

static VALUE onum_has_decimal_part_p(VALUE self)
{
    OCIError *errhp = oci8_errhp;
    boolean result;

    oci_lc(OCINumberIsInt(errhp, _NUMBER(self), &result));
    return result ? Qfalse : Qtrue;
}

#init_with(coder) ⇒ Object

:nodoc:



555
556
557
# File 'lib/oci8/oci8.rb', line 555

def init_with coder # :nodoc:
  initialize(coder.scalar)
end

#roundInteger #round(decplace) ⇒ Object

Rounds onum to the nearest Integer when no argument. Rounds onum to a specified decimal place decplace when one argument.

OraNumber.new(1.234).round(1)  #=> 1.2
OraNumber.new(1.234).round(2)  #=> 1.23
OraNumber.new(1.234).round(3)  #=> 1.234

Overloads:

  • #roundInteger

    Returns:

    • (Integer)


964
965
966
967
968
969
970
971
972
973
974
975
976
977
# File 'ext/oci8/ocinumber.c', line 964

static VALUE onum_round(int argc, VALUE *argv, VALUE self)
{
    OCIError *errhp = oci8_errhp;
    VALUE decplace;
    OCINumber r;

    rb_scan_args(argc, argv, "01", &decplace /* 0 */);
    oci_lc(OCINumberRound(errhp, _NUMBER(self), NIL_P(decplace) ? 0 : NUM2INT(decplace), &r));
    if (argc == 0) {
        return oci8_make_integer(&r, errhp);
    } else {
        return oci8_make_ocinumber(&r, errhp);
    }
}

#round_prec(digits) ⇒ Object

Rounds onum to a specified number of decimal digits. This method is available on Oracle 8.1 client or upper.

OraNumber.new(1.234).round_prec(2)  #=> 1.2
OraNumber.new(12.34).round_prec(2)  #=> 12
OraNumber.new(123.4).round_prec(2)  #=> 120


1009
1010
1011
1012
1013
1014
1015
1016
# File 'ext/oci8/ocinumber.c', line 1009

static VALUE onum_round_prec(VALUE self, VALUE ndigs)
{
    OCIError *errhp = oci8_errhp;
    OCINumber r;

    oci_lc(OCINumberPrec(errhp, _NUMBER(self), NUM2INT(ndigs), &r));
    return oci8_make_ocinumber(&r, errhp);
}

#shift(fixnum) ⇒ Object

Returns onum * 10**fixnum This method is available on Oracle 8.1 client or upper.



1257
1258
1259
1260
1261
1262
1263
1264
# File 'ext/oci8/ocinumber.c', line 1257

static VALUE onum_shift(VALUE self, VALUE exp)
{
    OCIError *errhp = oci8_errhp;
    OCINumber result;

    oci_lc(OCINumberShift(errhp, _NUMBER(self), NUM2INT(exp), &result));
    return oci8_make_ocinumber(&result, errhp);
}

#to_char(fmt = nil, nls_params = nil) ⇒ String

Returns a string containing a representation of self. fmt and nls_params are same meanings with TO_CHAR of Oracle function.

Returns:



1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
# File 'ext/oci8/ocinumber.c', line 1026

static VALUE onum_to_char(int argc, VALUE *argv, VALUE self)
{
    OCIError *errhp = oci8_errhp;
    VALUE fmt;
    VALUE nls_params;
    char buf[512];
    ub4 buf_size = sizeof(buf);
    oratext *fmt_ptr;
    oratext *nls_params_ptr;
    ub4 fmt_len;
    ub4 nls_params_len;
    sword rv;

    rb_scan_args(argc, argv, "02", &fmt /* nil */, &nls_params /* nil */);
    if (NIL_P(fmt)) {
        rv = oranumber_to_str(_NUMBER(self), buf, sizeof(buf));
        if (rv > 0) {
            return rb_usascii_str_new(buf, rv);
        }
        oranumber_dump(_NUMBER(self), buf);
        rb_raise(eOCIException, "Invalid internal number format: %s", buf);
    }
    StringValue(fmt);
    fmt_ptr = RSTRING_ORATEXT(fmt);
    fmt_len = RSTRING_LEN(fmt);
    if (NIL_P(nls_params)) {
        nls_params_ptr = NULL;
        nls_params_len = 0;
    } else {
        StringValue(nls_params);
        nls_params_ptr = RSTRING_ORATEXT(nls_params);
        nls_params_len = RSTRING_LEN(nls_params);
    }
    rv = OCINumberToText(errhp, _NUMBER(self),
                         fmt_ptr, fmt_len, nls_params_ptr, nls_params_len,
                         &buf_size, TO_ORATEXT(buf));
    if (rv == OCI_ERROR) {
        sb4 errcode;
        OCIErrorGet(errhp, 1, NULL, &errcode, NULL, 0, OCI_HTYPE_ERROR);
        if (errcode == 22065) {
            /* OCI-22065: number to text translation for the given format causes overflow */
            if (NIL_P(fmt)) /* implicit conversion */
                return rb_usascii_str_new_cstr("overflow");
        }
        oci8_raise(errhp, rv, NULL);
    }
    return rb_usascii_str_new(buf, buf_size);
}

#to_dObject

Return the value as a BigDecimal.



1167
1168
1169
1170
# File 'ext/oci8/ocinumber.c', line 1167

static VALUE onum_to_d(VALUE self)
{
    return onum_to_d_real(_NUMBER(self), oci8_errhp);
}

#to_fFloat

Return the value as a Float.

Returns:

  • (Float)


1108
1109
1110
1111
1112
1113
1114
1115
# File 'ext/oci8/ocinumber.c', line 1108

static VALUE onum_to_f(VALUE self)
{
    OCIError *errhp = oci8_errhp;
    double dbl;

    oci_lc(OCINumberToReal(errhp, _NUMBER(self), sizeof(dbl), &dbl));
    return rb_float_new(dbl);
}

#to_iInteger

Returns onum truncated to an Integer.

Returns:

  • (Integer)


1092
1093
1094
1095
1096
1097
1098
1099
# File 'ext/oci8/ocinumber.c', line 1092

static VALUE onum_to_i(VALUE self)
{
    OCIError *errhp = oci8_errhp;
    OCINumber num;

    oci_lc(OCINumberTrunc(errhp, _NUMBER(self), 0, &num));
    return oci8_make_integer(&num, errhp);
}

#to_json(options = nil) ⇒ Object

:nodoc:



572
573
574
# File 'lib/oci8/oci8.rb', line 572

def to_json(options=nil) # :nodoc:
  to_s
end

#to_rObject

Return the value as a Rational.



1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
# File 'ext/oci8/ocinumber.c', line 1124

static VALUE onum_to_r(VALUE self)
{
    VALUE x, y;
    int nshift = 0;
    OCINumber onum[2];
    int current = 0;
    boolean is_int;

    oci_lc(OCINumberAssign(oci8_errhp, _NUMBER(self), &onum[0]));

    for (;;) {
        oci_lc(OCINumberIsInt(oci8_errhp, &onum[current], &is_int));
        if (is_int) {
            break;
        }
        nshift++;
        oci_lc(OCINumberShift(oci8_errhp, &onum[current], 1, &onum[1 - current]));
        current = 1 - current;
    }
    x = oci8_make_integer(&onum[current], oci8_errhp);
    if (nshift == 0) {
        y = INT2FIX(1);
    } else {
        y = rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(nshift));
    }
#ifdef T_RATIONAL
    return rb_Rational(x, y);
#else
    if (!cRational) {
        rb_require("rational");
        cRational = rb_const_get(rb_cObject, id_Rational);
    }
    return rb_funcall(rb_cObject, id_Rational, 2, x, y);
#endif
}

#to_sString

Returns a string containing a representation of self.

Returns:



1081
1082
1083
1084
# File 'ext/oci8/ocinumber.c', line 1081

static VALUE onum_to_s(VALUE self)
{
    return onum_to_char(0, NULL, self);
}

#to_yaml(opts = {}) ⇒ Object

:nodoc:



565
566
567
568
569
# File 'lib/oci8/oci8.rb', line 565

def to_yaml(opts = {}) # :nodoc:
  YAML.quick_emit(object_id, opts) do |out|
    out.scalar(taguri, self.to_s, :plain)
  end
end

#truncateInteger #truncate(decplace) ⇒ Object

Truncates onum to the Integer when no argument. Truncates onum to a specified decimal place decplace when one argument.

Overloads:

  • #truncateInteger

    Returns:

    • (Integer)


987
988
989
990
991
992
993
994
995
996
# File 'ext/oci8/ocinumber.c', line 987

static VALUE onum_trunc(int argc, VALUE *argv, VALUE self)
{
    OCIError *errhp = oci8_errhp;
    VALUE decplace;
    OCINumber r;

    rb_scan_args(argc, argv, "01", &decplace /* 0 */);
    oci_lc(OCINumberTrunc(errhp, _NUMBER(self), NIL_P(decplace) ? 0 : NUM2INT(decplace), &r));
    return oci8_make_ocinumber(&r, errhp);
}

#yaml_initialize(type, val) ⇒ Object

:nodoc:



561
562
563
# File 'lib/oci8/oci8.rb', line 561

def yaml_initialize(type, val) # :nodoc:
  initialize(val)
end

#zero?Boolean

Returns true if onum is zero.

Returns:

  • (Boolean)


1225
1226
1227
1228
1229
1230
1231
1232
# File 'ext/oci8/ocinumber.c', line 1225

static VALUE onum_zero_p(VALUE self)
{
    OCIError *errhp = oci8_errhp;
    boolean result;

    oci_lc(OCINumberIsZero(errhp, _NUMBER(self), &result));
    return result ? Qtrue : Qfalse;
}