Class: Reqif::ReqifFloat
- Inherits:
-
Lutaml::Model::Type::Float
- Object
- Lutaml::Model::Type::Float
- Reqif::ReqifFloat
- Defined in:
- lib/reqif/reqif_float.rb
Overview
Custom Float type that handles ReqIF float serialization. Preserves decimal notation for simple values and uses scientific notation only when necessary (very large/small numbers).
Class Method Summary collapse
- .cast(value, options = {}) ⇒ Object
-
.format_float_as_decimal(float_value) ⇒ Object
Format as decimal if it can be done cleanly.
-
.format_scientific(float_value) ⇒ Object
Format in scientific notation.
-
.reqif_format(float_value) ⇒ String
Format a float value for ReqIF.
- .to_xml(value) ⇒ Object
Instance Method Summary collapse
Class Method Details
.cast(value, options = {}) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/reqif/reqif_float.rb', line 68 def self.cast(value, = {}) return nil if value.nil? return value if Lutaml::Model::Utils.uninitialized?(value) unless .equal?(EMPTY_OPTIONS) Lutaml::Model::Services::Type::Validator::Number.validate!(value, ) end case value when String then BigDecimal(value).to_f when Float then value when BigDecimal then value.to_f else Float(value.to_s) end end |
.format_float_as_decimal(float_value) ⇒ Object
Format as decimal if it can be done cleanly
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/reqif/reqif_float.rb', line 27 def self.format_float_as_decimal(float_value) # Use a reasonable precision to avoid floating point artifacts # Check if the value can be represented cleanly in decimal decimal_str = format("%.10g", float_value) # Skip if it's in scientific notation (contains 'e' or 'E') return nil if decimal_str.include?("e") || decimal_str.include?("E") # Verify round-trip: parse back and check if we get the same value parsed = BigDecimal(decimal_str).to_f return decimal_str if parsed == float_value # Try with higher precision decimal_str = format("%.15g", float_value) return nil if decimal_str.include?("e") || decimal_str.include?("E") parsed = BigDecimal(decimal_str).to_f return decimal_str if parsed == float_value nil # Couldn't represent cleanly end |
.format_scientific(float_value) ⇒ Object
Format in scientific notation
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/reqif/reqif_float.rb', line 50 def self.format_scientific(float_value) formatted = format("%.15e", float_value).upcase mantissa, exp = formatted.split("E") # Strip trailing zeros from mantissa mantissa = mantissa.sub(/\.?0+$/, "") mantissa = "0" if mantissa.empty? # Remove decimal point if it becomes trailing (e.g. "1.") mantissa = mantissa.chomp(".") # Handle exponent sign and strip leading zeros sign = exp.start_with?("-") ? "-" : "" digits = exp.sub(/^[+-]/, "").sub(/\A0+/, "") digits = "0" if digits.empty? "#{mantissa}E#{sign}#{digits}" end |
.reqif_format(float_value) ⇒ String
Format a float value for ReqIF. Uses decimal notation for values that can be represented cleanly, otherwise uses scientific notation with uppercase E.
17 18 19 20 21 22 23 24 |
# File 'lib/reqif/reqif_float.rb', line 17 def self.reqif_format(float_value) # Try to represent as a clean decimal first decimal_str = format_float_as_decimal(float_value) return decimal_str if decimal_str # Fall back to scientific notation format_scientific(float_value) end |
.to_xml(value) ⇒ Object
85 86 87 88 89 90 91 92 |
# File 'lib/reqif/reqif_float.rb', line 85 def self.to_xml(value) return nil if value.nil? result = cast(value) return nil if result.nil? reqif_format(result) end |
Instance Method Details
#to_xml ⇒ Object
94 95 96 |
# File 'lib/reqif/reqif_float.rb', line 94 def to_xml self.class.to_xml(value) end |