File: value/core/atom/number/float.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Umu#6
  module: Value#8
  module: Core#10
has properties
function: make_float / 1 #260
function: make_nan #267
function: make_infinity #272
  module: Atom#12
  module: Number#14
has properties
constant: NAN #250
constant: INFINITY #251
  class: Float#16
inherits from
  Abstract ( Umu::Value::Core::Atom::Number )
has properties
class method: meth_make_nan / 3 #24
class method: meth_make_infinity / 3 #34
method: initialize / 1 #41
method: to_s #48
method: meth_is_nan / 3 #72
method: meth_is_infinite / 3 #82
method: meth_is_finite / 3 #92
method: meth_to_float / 3 #139
method: meth_truncate / 4 #149
method: meth_ceil / 4 #170
method: meth_floor / 4 #191

Code

   1  # coding: utf-8
   2  # frozen_string_literal: true
   3 
   4 
   5 
   6  module Umu
   7 
   8  module Value
   9 
  10  module Core
  11 
  12  module Atom
  13 
  14  module Number
  15 
  16  class Float < Abstract
  17  # Class property
  18 
  19      define_class_method(
  20          :meth_make_nan,
  21          :nan, [],
  22          [], self
  23      )
  24      def self.meth_make_nan(_loc, _env, _event)
  25          VC.make_nan
  26      end
  27 
  28 
  29      define_class_method(
  30          :meth_make_infinity,
  31          :infinity, [],
  32          [], self
  33      )
  34      def self.meth_make_infinity(_loc, _env, _event)
  35          VC.make_infinity
  36      end
  37 
  38 
  39  # Instance property
  40 
  41      def initialize(val)
  42          ASSERT.kind_of val, ::Float
  43 
  44          super
  45      end
  46 
  47 
  48      def to_s
  49          if self.val.nan?
  50              'NAN'
  51          elsif self.val.infinite?
  52              format("%sINFINITY",
  53                      if self.val < 0
  54                          '-'
  55                      else
  56                          ''
  57                      end
  58              )
  59          elsif val.finite?
  60              super
  61          else
  62              ASSERT.abort
  63          end
  64      end
  65 
  66 
  67      define_instance_method(
  68          :meth_is_nan,
  69          :nan?, [],
  70          [], VCA::Bool
  71      )
  72      def meth_is_nan(_loc, _env, _event)
  73          VC.make_bool self.val.nan?
  74      end
  75 
  76 
  77      define_instance_method(
  78          :meth_is_infinite,
  79          :infinite?, [],
  80          [], VCA::Bool
  81      )
  82      def meth_is_infinite(_loc, _env, _event)
  83          VC.make_bool self.val.infinite?.kind_of?(::Integer)
  84      end
  85 
  86 
  87      define_instance_method(
  88          :meth_is_finite,
  89          :finite?, [],
  90          [], VCA::Bool
  91      )
  92      def meth_is_finite(_loc, _env, _event)
  93          VC.make_bool self.val.finite?
  94      end
  95 
  96 
  97      define_instance_method(
  98          :meth_is_less_than,
  99          :'<', [],
 100          [self], VCA::Bool
 101      )
 102 
 103 
 104      define_instance_method(
 105          :meth_is_greater_than,
 106          :'>', [],
 107          [self], VCA::Bool
 108      )
 109 
 110 
 111      define_instance_method(
 112          :meth_is_less_equal,
 113          :'<=', [],
 114          [self], VCA::Bool
 115      )
 116 
 117 
 118      define_instance_method(
 119          :meth_is_greater_equal,
 120          :'>=', [],
 121          [self], VCA::Bool
 122      )
 123 
 124 
 125      define_instance_method(
 126          :meth_compare,
 127          :'<=>', [],
 128          [self], VCAN::Int
 129      )
 130 
 131 
 132 
 133 
 134      define_instance_method(
 135          :meth_to_float,
 136          :'to-f', [],
 137          [], VCAN::Float
 138      )
 139      def meth_to_float(_loc, _env, _event)
 140          self
 141      end
 142 
 143 
 144      define_instance_method(
 145          :meth_truncate,
 146          :truncate, [],
 147          [VCAN::Int], self
 148      )
 149      def meth_truncate(loc, env, _event, ndigits)
 150          ASSERT.kind_of ndigits, VCAN::Int
 151 
 152          unless ndigits.val >= 0
 153              raise X::ArgumentError.new(
 154                  loc,
 155                  env,
 156                  "truncate: Expected zero or positive number, but: %d",
 157                  ndigits.val.to_i
 158              )
 159          end
 160 
 161          VC.make_float self.val.truncate(ndigits.val).to_f
 162      end
 163 
 164 
 165      define_instance_method(
 166          :meth_ceil,
 167          :ceil, [],
 168          [VCAN::Int], self
 169      )
 170      def meth_ceil(loc, env, _event, ndigits)
 171          ASSERT.kind_of ndigits, VCAN::Int
 172 
 173          unless ndigits.val >= 0
 174              raise X::ArgumentError.new(
 175                  loc,
 176                  env,
 177                  "ceil: expected zero or positive for digits number: %d",
 178                  ndigits.val.to_i
 179              )
 180          end
 181 
 182          VC.make_float self.val.ceil(ndigits.val).to_f
 183      end
 184 
 185 
 186      define_instance_method(
 187          :meth_floor,
 188          :floor, [],
 189          [VCAN::Int], self
 190      )
 191      def meth_floor(loc, env, _event, ndigits)
 192          ASSERT.kind_of ndigits, VCAN::Int
 193 
 194          unless ndigits.val >= 0
 195              raise X::ArgumentError.new(
 196                  loc,
 197                  env,
 198                  "floor: expected zero or positive for digits number: %d",
 199                  ndigits.val.to_i
 200              )
 201          end
 202 
 203          VC.make_float self.val.floor(ndigits.val).to_f
 204      end
 205 
 206 
 207      define_instance_method(
 208          :meth_add,
 209          :'+', [],
 210          [self], self
 211      )
 212 
 213 
 214      define_instance_method(
 215          :meth_sub,
 216          :'-', [],
 217          [self], self
 218      )
 219 
 220 
 221      define_instance_method(
 222          :meth_multiply,
 223          :'*', [],
 224          [self], self
 225      )
 226 
 227 
 228      define_instance_method(
 229          :meth_divide,
 230          :'/', [],
 231          [self], self
 232      )
 233 
 234 
 235      define_instance_method(
 236          :meth_modulo,
 237          :mod, [],
 238          [self], self
 239      )
 240 
 241 
 242      define_instance_method(
 243          :meth_power,
 244          :pow, [],
 245          [self], self
 246      )
 247  end
 248  Float.freeze
 249 
 250  NAN         = Atom::Number::Float.new(::Float::NAN).freeze
 251  INFINITY    = Atom::Number::Float.new(::Float::INFINITY).freeze
 252 
 253  end # Umu::Value::Core::Atom::Number
 254 
 255  end # Umu::Value::Core::Atom
 256 
 257 
 258  module_function
 259 
 260      def make_float(val)
 261          ASSERT.kind_of val, ::Float
 262 
 263          Atom::Number::Float.new(val).freeze
 264      end
 265 
 266 
 267      def make_nan
 268          Atom::Number::NAN
 269      end
 270 
 271 
 272      def make_infinity
 273          Atom::Number::INFINITY
 274      end
 275 
 276  end # Umu::Value::Core
 277 
 278  end # Umu::Value
 279 
 280  end # Umu