Class: Nio::BigTolerance

Inherits:
Object
  • Object
show all
Includes:
StateEquivalent
Defined in:
lib/nio/flttol.rb

Overview

This class represents floating point tolerances for BigDecimal numbers and allows comparison within the specified tolerance.

Defined Under Namespace

Modules: BgMth

Class Method Summary collapse

Instance Method Summary collapse

Methods included from StateEquivalent

#==, #===, #eql?, #hash

Constructor Details

#initialize(t = BigDecimal('0'), mode = :abs, decmode = false) ⇒ BigTolerance

The tolerance mode is either :abs (absolute) :rel (relative) or :sig



393
394
395
# File 'lib/nio/flttol.rb', line 393

def initialize(t=BigDecimal('0'), mode=:abs, decmode=false)
  set t, mode, decmode
end

Class Method Details

.decimals(d = 0, mode = :abs) ⇒ Object



566
567
568
# File 'lib/nio/flttol.rb', line 566

def BigTolerance.decimals(d=0, mode=:abs)
  BigTolerance.new.decimals(d,mode)
end

.fraction(f) ⇒ Object



572
573
574
# File 'lib/nio/flttol.rb', line 572

def BigTolerance.fraction(f)
  BigTolerance.new.fraction(f)
end

.percent(p) ⇒ Object



575
576
577
# File 'lib/nio/flttol.rb', line 575

def BigTolerance.percent(p)
  BigTolerance.new.percent(p)
end

.permille(p) ⇒ Object



578
579
580
# File 'lib/nio/flttol.rb', line 578

def BigTolerance.permille(p)
  BigTolerance.new.permille(p)
end

.sig_decimals(d = 0, mode = :abs) ⇒ Object



569
570
571
# File 'lib/nio/flttol.rb', line 569

def BigTolerance.sig_decimals(d=0, mode=:abs)
  BigTolerance.new.sig_decimals(d)
end

Instance Method Details

#[](x) ⇒ Object

Shortcut notation for get_value



431
432
433
# File 'lib/nio/flttol.rb', line 431

def [](x)
  return x.nil? ? @t : get_value(x)
end

#apprx_i(x, result = Integer) ⇒ Object

If the argument is close to an integer it rounds it and returns it as an object of the specified class (by default, Integer)



511
512
513
514
# File 'lib/nio/flttol.rb', line 511

def apprx_i(x,result=Integer)
  r = x.round
  return equals?(x,r) ? Nio.numeric_cast(r,result) : x
end

#apprx_i?(x) ⇒ Boolean

Returns true if the argument is approximately an integer

Returns:

  • (Boolean)


506
507
508
# File 'lib/nio/flttol.rb', line 506

def apprx_i?(x)
  equals?(x,x.round)
end

#aprx_equals?(x, y) ⇒ Boolean

Approximate equality within tolerance

Returns:

  • (Boolean)


458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'lib/nio/flttol.rb', line 458

def aprx_equals?(x,y)
  
  case @mode
    when :sig
      
      x_exp = x.exponent
      y_exp = y.exponent  
      (y-x).abs <= @t*BigDecimal("1E#{[x_exp,y_exp].max-@ref_exp}")
      
    when :rel
      
      (y-x).abs <= @t*([x.abs,y.abs].max) #reference value is 1
      
    when :abs
      (x-y).abs<=@t
  end
         
end

#decimal?Boolean

Returns true for decimal-mode tolerance

Returns:

  • (Boolean)


526
527
528
# File 'lib/nio/flttol.rb', line 526

def decimal?
  @decimal_mode
end

#decimals(d, mode = :abs, rounded = true) ⇒ Object

This initializes a BigTolerance with a given number of decimals



399
400
401
402
403
404
405
406
407
408
409
410
411
412
# File 'lib/nio/flttol.rb', line 399

def decimals(d, mode=:abs, rounded=true)
  
  @mode = mode
  @decimal_mode = true
  @d = d==0 ? 16 : d
  if rounded
    @t = BigDecimal("0.5E#{-d}") # HALF*(BigDecimal(10)**(-d))
  else
    @t = BigDecimal("1E#{-d}") # BigDecimal(10)**(-d)
  end
  @ref_exp = BigDecimal('0.1').exponent # reference for significative mode: [0.1,1)
  
  self
end

#equals?(x, y) ⇒ Boolean

Essential equality within tolerance

Returns:

  • (Boolean)


439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File 'lib/nio/flttol.rb', line 439

def equals?(x,y)
  
  case @mode
    when :sig
      
      x_exp = x.exponent
      y_exp = y.exponent  
      (y-x).abs <= @t*BigDecimal("1E#{[x_exp,y_exp].min-@ref_exp}")
      
    when :rel
      
      (y-x).abs <= @t*([x.abs,y.abs].min) #reference value is 1
      
    when :abs
      (x-y).abs<@t
  end
         
end

#fraction(f) ⇒ Object



419
420
421
# File 'lib/nio/flttol.rb', line 419

def fraction(f)
  set f, :rel
end

#get_value(x) ⇒ Object

Return tolerance relative to a magnitude



435
436
437
# File 'lib/nio/flttol.rb', line 435

def get_value(x)  
  rel(x)
end

#greater_than?(x, y) ⇒ Boolean

Comparison within tolerance

Returns:

  • (Boolean)


477
478
479
# File 'lib/nio/flttol.rb', line 477

def greater_than?(x,y)
  less_than?(y,x)
end

#less_than?(x, y) ⇒ Boolean

Comparison within tolerance

Returns:

  • (Boolean)


481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
# File 'lib/nio/flttol.rb', line 481

def less_than?(x,y)
 
 case @mode
   when :sig
     
     x_exp = x.exponent
     y_exp = y.exponent  
     y-x > @t*BigDecimal("1E#{[x_exp,y_exp].max-@ref_exp}")
     
   when :rel
     
     y-x > @t*([x.abs,y.abs].max) #reference value is 1
     
   when :abs
     x-y<@t
 end
    
end

#magnitudeObject

Returns the magnitude of the tolerance



518
519
520
# File 'lib/nio/flttol.rb', line 518

def magnitude
  @t
end

#modeObject

Returns the mode (:abs, :rel, :sig) of the tolerance



530
531
532
# File 'lib/nio/flttol.rb', line 530

def mode
  @mode
end

#num_classObject

The numeric class this tolerance applies to.



388
389
390
# File 'lib/nio/flttol.rb', line 388

def num_class
  BigDecimal
end

#num_decimalsObject

Returns the number of decimal digits of the tolerance



522
523
524
# File 'lib/nio/flttol.rb', line 522

def num_decimals  
  @d
end

#percent(x) ⇒ Object



422
423
424
# File 'lib/nio/flttol.rb', line 422

def percent(x)
  fraction x*BigDecimal('0.01')
end

#permille(x) ⇒ Object



425
426
427
# File 'lib/nio/flttol.rb', line 425

def permille(x)
  fraction x*BigDecimal('0.001')
end

#sig_decimals(d, rounded = true) ⇒ Object

This initializes a BigTolerance with a number of significative decimal digits



415
416
417
# File 'lib/nio/flttol.rb', line 415

def sig_decimals(d, rounded=true)
  decimals d, :sig, rounded
end

#zero?(x, compared_with = nil) ⇒ Boolean

Comparison within tolerance

Returns:

  • (Boolean)


500
501
502
# File 'lib/nio/flttol.rb', line 500

def zero?(x,compared_with=nil)
  compared_with.nil? ? x.abs<@t : x.abs<rel(compared_with)
end