Skip to content

Commit 35141f2

Browse files
authored
fix bug with percentile function (#28)
Sorting arrays of small doubles was inconsistent with the previous method
1 parent d6010d9 commit 35141f2

File tree

5 files changed

+34
-4
lines changed

5 files changed

+34
-4
lines changed

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
ruby_native_statistics (1.0.2)
4+
ruby_native_statistics (1.1.0)
55
rake-compiler (~> 1.2)
66

77
GEM

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Version 1.1.0
2+
3+
- Fix percentile bug reported by @Gbird22
4+
15
# Version 1.0.3
26

37
- Update all supported Ruby versions

ext/ruby_native_statistics/conversions.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "conversions.h"
2+
#include "float.h"
23

34
int compare_doubles(const void *a, const void *b)
45
{
@@ -8,7 +9,17 @@ int compare_doubles(const void *a, const void *b)
89
double cmp_a = *dbl_a;
910
double cmp_b = *dbl_b;
1011

11-
return (cmp_a - cmp_b);
12+
if (fabs(cmp_a - cmp_b) <= (DBL_EPSILON * fabs(cmp_a + cmp_b)))
13+
{
14+
return 0;
15+
}
16+
17+
if (cmp_a > cmp_b)
18+
{
19+
return 1;
20+
}
21+
22+
return -1;
1223
}
1324

1425
double *sorted_ruby_array(VALUE array, long array_length)
@@ -20,7 +31,7 @@ double *sorted_ruby_array(VALUE array, long array_length)
2031

2132
if (working_array == NULL)
2233
{
23-
rb_raise(rb_eStandardError, "unknown problem calculating median (possibly array is too large)");
34+
rb_raise(rb_eStandardError, "unknown problem sorting array (possibly array is too large)");
2435
}
2536

2637
for (i = 0; i < array_length; i++)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module RubyNativeStatistics
2-
VERSION = "1.0.3"
2+
VERSION = "1.1.0"
33
end

test/dispersion_test.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,19 @@ def test_percentile_floats
129129
assert_in_delta 0.73895928, array.percentile(0.333), 0.000001
130130
assert_in_delta 11.43290852, array.percentile(0.928), 0.000001
131131
end
132+
133+
def test_percentile_repeating
134+
array = [5.4, 5.3, 5.2, 5.4, 5.2].to_a.shuffle
135+
136+
assert_in_delta 5.4, array.percentile(0.9), 0.000001
137+
assert_in_delta 5.2, array.percentile(0.1), 0.000001
138+
assert_in_delta 5.3, array.percentile(0.5), 0.000001
139+
assert_in_delta 5.26, array.percentile(0.4), 0.000001
140+
end
141+
142+
def test_percentile_duplicates
143+
array = [5.2, 5.2, 5.2, 5.2, 5.2].to_a.shuffle
144+
145+
assert_in_delta 5.2, array.percentile(0.9), 0.000001
146+
end
132147
end

0 commit comments

Comments
 (0)