@@ -9,6 +9,34 @@ import (
99 "github.com/parquet-go/bitpack"
1010)
1111
12+ // compareFloats compares two float64 values using relative error for large numbers
13+ // and absolute error for small numbers. Returns true if the values are equal within
14+ // the acceptable tolerance.
15+ func compareFloats (a , b float64 ) (equal bool , relError , absError float64 ) {
16+ absError = math .Abs (a - b )
17+
18+ // For zero values, use absolute error
19+ if a == 0 || b == 0 {
20+ equal = absError <= 1e-10
21+ relError = math .Inf (1 ) // Relative error is undefined for zero
22+ return
23+ }
24+
25+ // Calculate relative error based on the larger magnitude
26+ maxAbs := math .Max (math .Abs (a ), math .Abs (b ))
27+ relError = absError / maxAbs
28+
29+ // For small numbers (close to zero), use absolute error
30+ // For large numbers, use relative error
31+ if maxAbs < 1.0 {
32+ equal = absError <= 1e-10
33+ } else {
34+ equal = relError <= 1e-11 // Slightly more tolerant than 1e-12 to account for ALP precision
35+ }
36+
37+ return
38+ }
39+
1240func TestBitPacking (t * testing.T ) {
1341 tests := []struct {
1442 name string
@@ -130,8 +158,10 @@ func TestALPCompression(t *testing.T) {
130158
131159 // Verify values (lossless)
132160 for i := range tt .data {
133- if math .Abs (decompressed [i ]- tt .data [i ]) > 1e-10 {
134- t .Errorf ("Value mismatch at index %d: got %f, want %f" , i , decompressed [i ], tt .data [i ])
161+ equal , relErr , absErr := compareFloats (decompressed [i ], tt .data [i ])
162+ if ! equal {
163+ t .Errorf ("Value mismatch at index %d: got %f, want %f (abs err: %e, rel err: %e)" ,
164+ i , decompressed [i ], tt .data [i ], absErr , relErr )
135165 }
136166 }
137167
@@ -193,8 +223,10 @@ func TestALPLargeDataset(t *testing.T) {
193223
194224 // Check a sample of values
195225 for i := 0 ; i < len (data ); i += 100 {
196- if math .Abs (decompressed [i ]- data [i ]) > 1e-9 {
197- t .Errorf ("Value mismatch at index %d: got %f, want %f" , i , decompressed [i ], data [i ])
226+ equal , relErr , absErr := compareFloats (decompressed [i ], data [i ])
227+ if ! equal {
228+ t .Errorf ("Value mismatch at index %d: got %f, want %f (abs err: %e, rel err: %e)" ,
229+ i , decompressed [i ], data [i ], absErr , relErr )
198230 }
199231 }
200232
@@ -319,8 +351,10 @@ func TestDecodeRange(t *testing.T) {
319351
320352 // Verify values with tolerance
321353 for i := range tt .data {
322- if math .Abs (fullDecoded [i ]- tt .data [i ]) > 1e-10 {
323- t .Errorf ("value mismatch at index %d: got %f, want %f" , i , fullDecoded [i ], tt .data [i ])
354+ equal , relErr , absErr := compareFloats (fullDecoded [i ], tt .data [i ])
355+ if ! equal {
356+ t .Errorf ("value mismatch at index %d: got %f, want %f (abs err: %e, rel err: %e)" ,
357+ i , fullDecoded [i ], tt .data [i ], absErr , relErr )
324358 }
325359 }
326360 })
@@ -399,8 +433,10 @@ func TestStreamEncoderDecoder(t *testing.T) {
399433
400434 // Verify values
401435 for i := range tt .data {
402- if math .Abs (decoded [i ]- tt .data [i ]) > 1e-10 {
403- t .Errorf ("value mismatch at index %d: got %f, want %f" , i , decoded [i ], tt .data [i ])
436+ equal , relErr , absErr := compareFloats (decoded [i ], tt .data [i ])
437+ if ! equal {
438+ t .Errorf ("value mismatch at index %d: got %f, want %f (abs err: %e, rel err: %e)" ,
439+ i , decoded [i ], tt .data [i ], absErr , relErr )
404440 }
405441 }
406442 })
@@ -462,10 +498,10 @@ func FuzzStreamEncodeDecode(f *testing.F) {
462498
463499 // Verify values with appropriate tolerance
464500 for i := range src {
465- if math . Abs (decoded [i ]- src [i ]) > 1e-10 {
466- // For debugging: show the difference
467- t .Errorf ("Value mismatch at index %d: got %f, want %f (diff : %e)" ,
468- i , decoded [i ], src [i ], math . Abs ( decoded [ i ] - src [ i ]) )
501+ equal , relErr , absErr := compareFloats (decoded [i ], src [i ])
502+ if ! equal {
503+ t .Errorf ("Value mismatch at index %d: got %f, want %f (abs err: %e, rel err : %e)" ,
504+ i , decoded [i ], src [i ], absErr , relErr )
469505 }
470506 }
471507 })
0 commit comments