lib/money/money.rb
# Allocates money between different parties without loosing pennies.
# After the mathmatically split has been performed, left over pennies will
# be distributed round-robin amongst the parties. This means that parties
# listed first will likely recieve more pennies then ones that are listed later
#
# @param [0.50, 0.25, 0.25] to give 50% of the cash to party1, 25% ot party2, and 25% to party3.
#
# @return [Array<Money, Money, Money>]
#
# @example
#   Money.new(5, "USD").allocate([0.3,0.7)) #=> [Money.new(2), Money.new(3)]
#   Money.new(100, "USD").allocate([0.33,0.33,0.33]) #=> [Money.new(34), Money.new(33), Money.new(33)]
Allocates money between different parties without loosing pennies.
After the mathmatically split has been performed, left over pennies will
be distributed round-robin amongst the parties. This means that parties
listed first will likely recieve more pennies then ones that are listed later
Allocates money between different parties without loosing pennies . After the mathmatically split has been performed left over pennies will be distributed round - robin amongst the parties . This means that parties listed first will likely recieve more pennies then ones that are listed later
def allocate(splits)
    allocations = splits.inject(BigDecimal("0")) do |sum, n|
      n = BigDecimal(n.to_s) unless n.is_a?(BigDecimal)
      sum + n
    end
    if (allocations - BigDecimal("1")) > Float::EPSILON
      raise ArgumentError, "splits add to more then 100%"
    end
    left_over = cents
    amounts = splits.map do |ratio|
      if self.class.infinite_precision
        fraction = cents * ratio
      else
        fraction = (cents * ratio / allocations).floor
        left_over -= fraction
        fraction
      end
    end
    unless self.class.infinite_precision
      left_over.to_i.times { |i| amounts[i % amounts.length] += 1 }
    end
    amounts.collect { |cents| Money.new(cents, currency) }
  end
def allocate ( splits ) allocations = splits . inject ( BigDecimal ( "0" ) ) do | sum , n | n = BigDecimal ( n . to_s ) unless n . is_a? ( BigDecimal ) sum + n end if ( allocations - BigDecimal ( "1" ) ) > Float :: EPSILON raise ArgumentError , "splits add to more then 100%" end left_over = cents amounts = splits . map do | ratio | if self . class . infinite_precision fraction = cents * ratio else fraction = ( cents * ratio / allocations ) . floor left_over -= fraction fraction end end unless self . class . infinite_precision left_over . to_i . times { | i | amounts [ i % amounts . length ] += 1 } end amounts . collect { | cents | Money . new ( cents , currency ) } end
Allocates money between different parties without loosing pennies.
Allocates money between different parties without loosing pennies .
None
Array<Money, Money, Money>
splits
<not_specific>
<not_specific>
to give 50% of the cash to party1, 25% ot party2, and 25% to party3.
to give 50% of the cash to party1 25% ot party2 and 25% to party3 .
example
None