ae_fast_decimal_formatter 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []