module Nth::FloatMethods

Public Class Methods

inches_to_feet(flt, mode = :descriptive, denom=16) click to toggle source

:numeric_long … 3 feet 1 3/4 inches :numeric_short … 3ft 1 3/4in :descriptive … three feet one and three quarter inches :tics_utf … 3′ 1¾″ :tics_html … above with html codes

# File lib/nth.rb, line 843
def self.inches_to_feet(flt, mode = :descriptive, denom=16)
  neg = flt.negative? ? "-" : ""
  str = neg        
  flt = flt.abs
  num = flt.floor
  frac = flt - num
  feet = (num / 12.0)
  feet_flr = feet.floor
  feet_frac = feet - feet_flr
  inches = feet_frac * 12.0 + frac
  # copy & paste
  frac = Fraction(inches,denom).to_s(false).to_s
  ary  = frac.split(' ')     
  if [:tics_utf,:tics_html].include? mode
    if mode == :tics_utf
      inch_tic = '″'
      foot_tic = '′'
    else
      inch_tic = '″'
      foot_tic = '′'
    end
    if (feet_flr.zero?)
      if 1==ary.count
        return '0' + foot_tic if 0 == ary.first.to_i
      end
    else
      str += feet_flr.zero? ? "" : "#{feet_flr}#{foot_tic} "
    end        
    
    if 1==ary.count
      return str + ary.first + inch_tic          
    else
      str += ary.first
      utf = FRACTION_UTF[ary.last]
      if utf.nil?
        str += ' ' + ary.last + inch_tic
      else
        if mode == :tics_utf
          str += utf + inch_tic
        else
          str += '&#' + "#{utf.ord};" + inch_tic
        end
      end  
      return str        
    end       
  elsif [:numeric_long,:numeric_short].include? mode     
    if mode == :numeric_short
      inch_name = 'in'
      foot_name = 'ft'
    else
      inch_name = ' inch'
      foot_name = feet_flr==1 ? ' foot' : ' feet'
    end
    if feet_flr.zero?
      if 1==ary.count
        return '0' + foot_name if 0 == ary.first.to_i
      end
    else
      str += feet_flr.to_s + foot_name
    end
    if 1==ary.count
      str += ' ' unless str.empty?
      str += ary.first + inch_name
      if mode == :numeric_long
        str += 'es' unless ary.first.to_i == 1
      end
    else
      str += ' ' unless str.empty?
      str += ary.first + ' ' + ary.last + inch_name
      str += 'es' unless mode == :numeric_short          
    end
    return str              
  elsif :descriptive == mode
    inch_name = ' inch'
    foot_name = feet_flr==1 ? ' foot' : ' feet'
    str = "minas " unless str.empty?
    if feet_flr.zero?
      if 1==ary.count
        return 'zero' + foot_name if '0' == ary.first
      end
    else
      str += Nth::get_number_name(feet_flr, :-) + foot_name
    end
    if 1==ary.count
      ### fractional entities must not call #to_i
      ### ok unless fractional
      if ary.first.include? '/'
        ary = ary.first.split('/')
        str += ' ' unless str.empty?
        str += Nth::get_number_name(ary.first.to_i, :-) + ' ' + Nth::get_denominator_name(ary.last.to_i) + inch_name
      else
        str += ' ' unless str.empty?
        str += Nth::get_number_name(ary.first.to_i, :-) + inch_name
        str += 'es' unless ary.first == '1'
      end
    else
      str += ' ' unless str.empty?
      str += Nth::get_number_name(ary.first.to_i, :-) + ' and '
      ary = ary.last.split('/')
      str += Nth::get_number_name(ary.first.to_i, :-) + ' ' + Nth::get_denominator_name(ary.last.to_i) + inch_name + 'es'
    end
    return str                      
  else
    raise "unsupported mode #{mode}"
  end
end
inches_to_yards(flt, mode = :descriptive, denom=16) click to toggle source

this would be nice on the fraction class too…

# File lib/nth.rb, line 952
def self.inches_to_yards(flt, mode = :descriptive, denom=16)
  raise 'unsupported mode' unless [:numeric_long,:numeric_short,:descriptive].include? mode
  # try to use inches_to_feet
  neg = flt.negative? ? true : false
  pfx = neg ? "-" : ""
  flt = flt.abs
  yards = (flt / 36.0).floor
  inches = flt - (yards * 36.0)
  str = inches_to_feet(inches, mode, denom)         
  if yards==1
    if :numeric_short==mode
      return pfx + "1yd " + str
    elsif :numeric_long==mode
      return pfx + "1 yard " + str
    else
      pfx = "minas " if neg
      return pfx + "one yard " + str  
    end      
  else
    if :numeric_short==mode
      return "#{yards}yd " + str
    elsif :numeric_long==mode
      return "#{yards} yards " + str
    else
      pfx = "minas " if neg
      yy = Nth::get_number_name(yards, :-)
      return "#{yy} yards " + str  
    end      
  end  
end
to_dms(val, sec_frac=2) click to toggle source
# File lib/nth.rb, line 982
def self.to_dms(val, sec_frac=2)
  sgn = val.negative? ? -1.0 : 1.0
  num = val.abs % 360
  num *= sgn
  if num > 180.0
    num -= 360.0
  elsif num < -180.0
    num += 360.0
  end
  sgn = num.negative? ? "-" : ""
  num = num.abs
  deg = num.floor
  num = (num-deg) * 60.0
  min = num.floor
  num = (num-min) * 60.0
  if (sec_frac==0)
    sec = num.round 0
    frac = ""
  else
    sec = num.floor
    num = (num-sec) * (10 ** sec_frac)
    frac = ".#{num.floor}"
  end
  return "#{sgn}#{deg}°#{min}′#{sec}#{frac}″"
end
to_fractional_unit(flt, unit_name, mode = :descriptive, tar=0.01) click to toggle source

:numeric … 3 1/4 cups :descriptive … three and one quarter cups :utf … 3¼ cups :html … 3&amp;#188; cups

# File lib/nth.rb, line 752
def self.to_fractional_unit(flt, unit_name, mode = :descriptive, tar=0.01)  # inch, cup, teaspoon etc
  if :numeric==mode
    frac=Fraction(flt,tar).to_s(false).to_s  # work_around for now  ... bump revision on prim_wrap gem
    ary = frac.split(' ')
    if 1==ary.count
      str = ary.first
      if str.include? '/'
        return "#{str} #{unit_name}"
      else
        if '1'==str
          return "1 #{unit_name}"
        else
          return "#{str} #{Nth::pluralize(unit_name)}"
        end
      end
    else
      return "#{ary.first} #{ary.last} #{Nth::pluralize(unit_name)}"
    end
  elsif :descriptive==mode
    ##  get_denominator_name(int)   get_number_name(int, *flags)
    ##Nth::pluralize(str)
    frac=Fraction(flt,tar).to_s(false).to_s
    ary = frac.split(' ')
    
    if 1==ary.count
      str = ary.first
      if str.include? '/'
        ary = str.split('/')
        top = ary.first.to_i
        bot = ary.last.to_i
        top = Nth::get_number_name(top, :-)
        denom = Nth::get_denominator_name(bot)
        return "#{top} #{denom} #{unit_name}"
      else
        if '1'==str
          return "one #{unit_name}"
        else
          num = ary.first.to_i
          name = Nth::get_number_name(num, :-)
          return "#{name} #{Nth::pluralize(unit_name)}"
        end
      end
    else
      str   = Nth::get_number_name(ary.first.to_i, :-) + " and "
      ary   = ary.last.split('/')
      top   = ary.first.to_i
      bot   = ary.last.to_i
      denom = Nth::get_denominator_name(bot)
      # denom = Nth::pluralize(denom) unless top==1
      top   = Nth::get_number_name(top, :-)
      return str + "#{top} #{denom} #{Nth::pluralize(unit_name)}"
    end
  elsif [:utf,:html].include? mode
    frac=Fraction(flt,tar).to_s(false).to_s  # work_around for now  ... bump revision on prim_wrap gem
    ary = frac.split(' ')
    if 1==ary.count
      str = ary.first
      if str.include? '/'
        utf = FRACTION_UTF[str]
        return "#{str} #{unit_name}" if utf.nil?
        if :utf==mode
          return "#{utf} #{unit_name}"
        else
          return '&#' + "#{utf.ord}; #{unit_name}"
        end
      else
        if '1'==str
          return "1 #{unit_name}"
        else
          return "#{str} #{Nth::pluralize(unit_name)}"
        end
      end
    else
      utf = FRACTION_UTF[ary.last]
      if utf.nil?
        utf = ' ' + ary.last
      elsif :html==mode
        utf = '&#' + "#{utf.ord};"
      end
      return "#{ary.first}#{utf} #{Nth::pluralize(unit_name)}"
    end
  else
    raise "mode `#{mode.inspect}` is not defined"
  end
end