ae_fast_decimal_formatter 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c8d0765a81889d9e8cb54d9961fd5bc6e7daf282e767bc10f33fb5c6660df418
4
+ data.tar.gz: 8f0064baa8132ac69a131d3c45a3917d1288672815a7bd280ff5c718e9e62b05
5
+ SHA512:
6
+ metadata.gz: ce7e446c20366f9b69bdf58285d6b960957ecbd96f88ca427d6d3e9e9c80cb5b0fa325b21f726544bb33b888c49aef309d16db76d1bee44a4ab357efbb757a0e
7
+ data.tar.gz: 55fe31c15e4a985a36cb6580685a82043407761c4c086f2da809ad6ff421a0cee776555ba712ac0190577e2abd8e8d2a08dcd017e87687095c1ddeb0651c6fb4
@@ -0,0 +1,114 @@
1
+ #include <ruby.h>
2
+ #include <float.h>
3
+
4
+ VALUE c_format_decimal(double num, int precision)
5
+ {
6
+ char numstr[100];
7
+ char str[DBL_MAX_10_EXP + 2];
8
+ int numi, numlen, stri, strl;
9
+ int maxp = 5, i;
10
+ char formatstr[10];
11
+ int digits_to_comma;
12
+ double rounding_factor, rounded_num;
13
+
14
+ if (precision > maxp) { precision = maxp; }
15
+ if (precision < 0) { precision = 0; }
16
+
17
+ snprintf(formatstr, 10, "%%.%df", precision);
18
+ formatstr[9] = 0;
19
+
20
+ if (precision > 0) {
21
+ rounding_factor = pow(10.0, precision);
22
+ rounded_num = round(num * rounding_factor) / rounding_factor;
23
+ } else {
24
+ rounded_num = round(num);
25
+ }
26
+
27
+ if (precision > 0) { precision++; } // adjust for .
28
+
29
+ numlen = snprintf(numstr, 100, formatstr, rounded_num);
30
+ digits_to_comma = numlen - precision;
31
+ if (numstr[0] == '-') { digits_to_comma--; }
32
+
33
+ strl = numlen + (digits_to_comma / 3);
34
+ if ((digits_to_comma % 3) == 0) {
35
+ strl--;
36
+ }
37
+
38
+ if (strncmp(numstr, "-0.00000", strl) == 0) {
39
+ return rb_str_new("0.00000", 1 + precision);
40
+ }
41
+
42
+ stri = strl;
43
+ str[stri] = 0;
44
+ for (i = 1; i <= (precision + 1); i++) {
45
+ str[stri - i] = numstr[numlen - i];
46
+ }
47
+
48
+ stri -= (precision + 2);
49
+ numlen -= (precision + 1);
50
+ numi = 1;
51
+
52
+ while ((numlen - numi) >= 1) {
53
+ if ((numi % 3) == 0) {
54
+ str[stri] = ',';
55
+ stri--;
56
+ }
57
+ str[stri] = numstr[numlen - numi];
58
+ stri--;
59
+ numi++;
60
+ }
61
+
62
+ if (numstr[0] == '-') {
63
+ str[0] = '-';
64
+ } else {
65
+ if ((numi % 3) == 0) {
66
+ str[1] = ',';
67
+ }
68
+ str[0] = numstr[0];
69
+ }
70
+ return rb_str_new2(str);
71
+ }
72
+
73
+ struct ae_fast_decimal_formatter {
74
+ double num;
75
+ int precision;
76
+ };
77
+
78
+ static void ae_fast_decimal_formatter_free(void *p) {}
79
+
80
+ static VALUE ae_fast_decimal_formatter_alloc(VALUE klass) {
81
+ VALUE obj;
82
+ struct ae_fast_decimal_formatter *ptr;
83
+
84
+ obj = Data_Make_Struct(klass, struct ae_fast_decimal_formatter, NULL, ae_fast_decimal_formatter_free, ptr);
85
+
86
+ ptr->num = 0.0;
87
+ ptr->precision = 0;
88
+
89
+ return obj;
90
+ }
91
+
92
+ static VALUE ae_fast_decimal_formatter_init(VALUE self, VALUE number, VALUE precision) {
93
+ struct ae_fast_decimal_formatter *ptr;
94
+ Data_Get_Struct(self, struct ae_fast_decimal_formatter, ptr);
95
+ ptr->num = NUM2DBL(number);
96
+ ptr->precision = NUM2UINT(precision);
97
+ return self;
98
+ }
99
+
100
+ static VALUE ae_fast_decimal_formatter_format(VALUE self) {
101
+ struct ae_fast_decimal_formatter *ptr;
102
+ Data_Get_Struct(self, struct ae_fast_decimal_formatter, ptr);
103
+ return c_format_decimal(ptr->num, ptr->precision);
104
+ }
105
+
106
+ void Init_ae_fast_decimal_formatter(void) {
107
+ VALUE cFastDecimalFormatter;
108
+
109
+ cFastDecimalFormatter = rb_const_get(rb_cObject, rb_intern("AeFastDecimalFormatter"));
110
+
111
+ rb_define_alloc_func(cFastDecimalFormatter, ae_fast_decimal_formatter_alloc);
112
+ rb_define_method(cFastDecimalFormatter, "initialize", ae_fast_decimal_formatter_init, 2);
113
+ rb_define_method(cFastDecimalFormatter, "format", ae_fast_decimal_formatter_format, 0);
114
+ }
@@ -0,0 +1,6 @@
1
+ require "mkmf"
2
+
3
+ abort "missing snprintf()" unless have_func "snprintf"
4
+ abort "missing strncmp()" unless have_func "strncmp"
5
+
6
+ create_makefile "ae_fast_decimal_formatter/ae_fast_decimal_formatter"
@@ -0,0 +1,4 @@
1
+ class AeFastDecimalFormatter
2
+ end
3
+
4
+ require "ae_fast_decimal_formatter/ae_fast_decimal_formatter"
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ae_fast_decimal_formatter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Appfolio Inc.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-05-14 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Efficiently format decimal number so that reports of millions of decimal
14
+ cells are fast
15
+ email: dev@appfolio.com
16
+ executables: []
17
+ extensions:
18
+ - ext/ae_fast_decimal_formatter/extconf.rb
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ext/ae_fast_decimal_formatter/ae_fast_decimal_formatter.c
22
+ - ext/ae_fast_decimal_formatter/extconf.rb
23
+ - lib/ae_fast_decimal_formatter.rb
24
+ homepage: https://www.github.com/appfolio/ae_fast_decimal_formatter
25
+ licenses:
26
+ - MIT
27
+ metadata:
28
+ allowed_push_host: https://rubygems.org
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: 2.3.3
38
+ - - "<"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.7'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.0.3
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: Efficiently format decimal number
51
+ test_files: []