1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
#!/usr/bin/env ruby -w
# encoding: UTF-8
#
# = RealFormat.rb -- The TaskJuggler III Project Management Software
#
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
# by Chris Schlaeger <cs@taskjuggler.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
class TaskJuggler
# This class provides the functionality to format a Float according to certain
# rules. These rules determine how negative values are represented, how the
# fractional part is shown and how to structure the mantissa. The result is
# always a String.
#
# The class uses the following parameters to control the formating.
# signPrefix: Prefix used for negative numbers. (String)
# signSuffix: Suffix used for negative numbers. (String)
# thousandsSeparator: Separator used after 3 integer digits. (String)
# fractionSeparator: Separator used between the inter part and the
# fractional part. (String)
# fractionDigits: Number of fractional digits to show. (Integer)
class RealFormat
attr_reader :signPrefix, :signSuffix, :thousandsSeparator,
:fractionSeparator, :fractionDigits
# Create a new RealFormat object and define the formating rules.
def initialize(args)
iVars = %w( @signPrefix @signSuffix @thousandsSeparator
@fractionSeparator @fractionDigits )
if args.is_a?(RealFormat)
# The argument is another RealFormat object.
iVars.each do |iVar|
instance_variable_set(iVar, args.instance_variable_get(iVar))
end
elsif args.length == 5
# The argument is a list of values.
args.length.times do |i|
instance_variable_set(iVars[i], args[i])
end
else
raise RuntimeError, "Bad number of parameters #{args.length}"
end
end
# Converts the Float _number_ into a String representation according to the
# formating rules.
def format(number)
# Check for negative number. Continue with the absolute part.
if number < 0
negate = true
number = -number
else
negate = false
end
# Determine the integer part.
intNumber = (number * (10 ** @fractionDigits)).round.to_i.to_s
if intNumber.length <= @fractionDigits
intNumber = '0' * (@fractionDigits - intNumber.length + 1) + intNumber
end
intPart = intNumber[0..-(@fractionDigits + 1)]
# Determinate the fractional part
fracPart =
@fractionDigits > 0 ? @fractionSeparator +
intNumber[-(@fractionDigits)..-1] : ''
if @thousandsSeparator.empty?
out = intPart
else
out = ''
1.upto(intPart.length) do |i|
out = intPart[-i, 1] + out
out = @thousandsSeparator + out if i % 3 == 0 && i < intPart.length
end
end
out += fracPart
# Now compose the result.
out = @signPrefix + out + @signSuffix if negate
out
end
def to_s
[ @signPrefix, @signSuffix, @thousandsSeparator, @fractionSeparator,
@fractionDigits ].collect { |s| "\"#{s}\"" }.join(' ')
end
end
end
|