philiprehberger-approx 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8ddae870e2bf316dae4d17e6328f0ac6258d1d0555e8abd1fa9968b91738cfc3
4
+ data.tar.gz: f7fd4f79dc256eaed4eb797b12ae76f42e8596aed8c9007f002edb9c8fea2049
5
+ SHA512:
6
+ metadata.gz: 78a636564c186efc79cdb832ceeebd4f43446b85f122036de671f4b656ee73858d27fe6c8ec0ac7fdb7e0615570d4a8c2ca9040bd34514259112efe71f5c741e
7
+ data.tar.gz: fc2bee9cab8c3dff75447785ba877c8579039c7906b60b5c7b24c2d1e9a1909c08360b4d9729af8cbe627e518803218b995055b00b1cb29c66622b14fcde75ef
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this gem will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-03-22
11
+
12
+ ### Added
13
+ - Initial release
14
+ - Epsilon-based approximate equality for floats
15
+ - Deep comparison for arrays and hashes
16
+ - Assert method that raises on mismatch
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 philiprehberger
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # philiprehberger-approx
2
+
3
+ [![Tests](https://github.com/philiprehberger/rb-approx/actions/workflows/ci.yml/badge.svg)](https://github.com/philiprehberger/rb-approx/actions/workflows/ci.yml)
4
+ [![Gem Version](https://badge.fury.io/rb/philiprehberger-approx.svg)](https://rubygems.org/gems/philiprehberger-approx)
5
+ [![License](https://img.shields.io/github/license/philiprehberger/rb-approx)](LICENSE)
6
+
7
+ Epsilon-based approximate equality for floats, arrays, and hashes
8
+
9
+ ## Requirements
10
+
11
+ - Ruby >= 3.1
12
+
13
+ ## Installation
14
+
15
+ Add to your Gemfile:
16
+
17
+ ```ruby
18
+ gem 'philiprehberger-approx'
19
+ ```
20
+
21
+ Or install directly:
22
+
23
+ ```bash
24
+ gem install philiprehberger-approx
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ```ruby
30
+ require 'philiprehberger/approx'
31
+
32
+ Philiprehberger::Approx.equal?(1.0, 1.0 + 1e-10)
33
+ # => true
34
+
35
+ Philiprehberger::Approx.equal?(1.0, 1.1)
36
+ # => false
37
+ ```
38
+
39
+ ### Custom Epsilon
40
+
41
+ ```ruby
42
+ Philiprehberger::Approx.equal?(1.0, 1.05, epsilon: 0.1)
43
+ # => true
44
+ ```
45
+
46
+ ### Array and Hash Comparison
47
+
48
+ ```ruby
49
+ Philiprehberger::Approx.equal?([1.0, 2.0], [1.0 + 1e-10, 2.0])
50
+ # => true
51
+
52
+ Philiprehberger::Approx.equal?({ x: 1.0 }, { x: 1.0 + 1e-10 })
53
+ # => true
54
+ ```
55
+
56
+ ### Assert Near
57
+
58
+ ```ruby
59
+ Philiprehberger::Approx.assert_near(1.0, 1.0 + 1e-10)
60
+ # => nil (no error)
61
+
62
+ Philiprehberger::Approx.assert_near(1.0, 2.0)
63
+ # => raises Philiprehberger::Approx::Error
64
+ ```
65
+
66
+ ## API
67
+
68
+ | Method | Description |
69
+ |--------|-------------|
70
+ | `.equal?(a, b, epsilon: 1e-9)` | Check approximate equality within epsilon |
71
+ | `.near?(a, b, epsilon: 1e-9)` | Alias for `.equal?` |
72
+ | `.assert_near(a, b, epsilon: 1e-9)` | Raise `Error` if values differ by more than epsilon |
73
+
74
+ ## Development
75
+
76
+ ```bash
77
+ bundle install
78
+ bundle exec rspec
79
+ bundle exec rubocop
80
+ ```
81
+
82
+ ## License
83
+
84
+ MIT
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Philiprehberger
4
+ module Approx
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'approx/version'
4
+
5
+ module Philiprehberger
6
+ module Approx
7
+ class Error < StandardError; end
8
+
9
+ # Check if two values are approximately equal within epsilon
10
+ #
11
+ # @param a [Numeric, Array, Hash] first value
12
+ # @param b [Numeric, Array, Hash] second value
13
+ # @param epsilon [Float] maximum allowed difference
14
+ # @return [Boolean] true if values are approximately equal
15
+ def self.equal?(a, b, epsilon: 1e-9)
16
+ compare(a, b, epsilon)
17
+ end
18
+
19
+ # Alias for equal? with explicit epsilon
20
+ #
21
+ # @param a [Numeric, Array, Hash] first value
22
+ # @param b [Numeric, Array, Hash] second value
23
+ # @param epsilon [Float] maximum allowed difference
24
+ # @return [Boolean] true if values are near each other
25
+ def self.near?(a, b, epsilon: 1e-9)
26
+ equal?(a, b, epsilon: epsilon)
27
+ end
28
+
29
+ # Assert that two values are approximately equal, raising on mismatch
30
+ #
31
+ # @param a [Numeric, Array, Hash] first value
32
+ # @param b [Numeric, Array, Hash] second value
33
+ # @param epsilon [Float] maximum allowed difference
34
+ # @raise [Error] if values differ by more than epsilon
35
+ def self.assert_near(a, b, epsilon: 1e-9)
36
+ return if equal?(a, b, epsilon: epsilon)
37
+
38
+ raise Error, "expected #{a.inspect} to be near #{b.inspect} (epsilon: #{epsilon})"
39
+ end
40
+
41
+ class << self
42
+ private
43
+
44
+ def compare(a, b, epsilon)
45
+ case [a, b]
46
+ in [Numeric, Numeric]
47
+ (a - b).abs <= epsilon
48
+ in [Array, Array]
49
+ return false unless a.length == b.length
50
+
51
+ a.zip(b).all? { |x, y| compare(x, y, epsilon) }
52
+ in [Hash, Hash]
53
+ return false unless a.keys.sort == b.keys.sort
54
+
55
+ a.all? { |k, v| compare(v, b[k], epsilon) }
56
+ else
57
+ a == b
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: philiprehberger-approx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Philip Rehberger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-03-22 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Compare numeric values, arrays, and hashes for approximate equality using
14
+ configurable epsilon tolerance with deep comparison support.
15
+ email:
16
+ - me@philiprehberger.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - CHANGELOG.md
22
+ - LICENSE
23
+ - README.md
24
+ - lib/philiprehberger/approx.rb
25
+ - lib/philiprehberger/approx/version.rb
26
+ homepage: https://github.com/philiprehberger/rb-approx
27
+ licenses:
28
+ - MIT
29
+ metadata:
30
+ homepage_uri: https://github.com/philiprehberger/rb-approx
31
+ source_code_uri: https://github.com/philiprehberger/rb-approx
32
+ changelog_uri: https://github.com/philiprehberger/rb-approx/blob/main/CHANGELOG.md
33
+ bug_tracker_uri: https://github.com/philiprehberger/rb-approx/issues
34
+ rubygems_mfa_required: 'true'
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 3.1.0
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubygems_version: 3.5.22
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Epsilon-based approximate equality for floats, arrays, and hashes
54
+ test_files: []