From: Robert Klemme Date: 2007-05-25T23:50:07+09:00 Subject: Re: Array troubles On 25.05.2007 16:26, Hakusa@gmail.com wrote: > I'm converting a Java calculator program I wrote into Ruby--which, > just so you know, has been unbelievable with how quickly the language > can be learned and implemented and how easy it made programming what > had taken months of Java (but that was during school-time so > development was, admittedly, very slow)--but I've run into a problem. > > In a term, if you have q/q^2/4/8, it turns into q^-1/.5, but I'm > getting q^-10! I've narrowed it down to one part of one function: > division in Term#simplify. > > There's a lot of code involved, so I'll only post relevant data. I > REALLY do think you'll need any more than this. Also: when I say > algebraic calculator, I mean that half the time you're working with > letters (variables), not numbers. > > Term#simplify > >>> def simplify >>> count=0 # count will keep track of iterations. >>> temp = [] # This array will be our temp for @items. >>> @items.each do |item| >>> >>> # Why check for this? >>> # The only time strings are use here is as an operator. >>> if item.class == String >>> # Defining these really just make the code easier for further on. >>> # They're the items before and after the operator. >>> num1 = @items[count-1] >>> num2 = @items[count+1] >>> >>> # So if the operator is division... >>> if item.eql?('/') >>> # You can't do much if the operands aren't of the same class. >>> if num1.class.eql?( num2.class ) >>> puts 'temp pre ' + (temp).to_s >>> # And use the / method of whatever class they are. >>> puts num1.to_s + item + num2.to_s + " = " + >>> (num1/num2).to_s You don't need all the #to_s, instead you can do print num1, item, num2, " = ", (num1/num2), "\n" or use printf or puts with string interpolation. >>> temp << num1/num2 >>> puts 'temp post ' + (temp).to_s >>> end >>> end >>> end >>> count += 1 >>> end >>> puts temp[1] >>> temp >>> end > > With q/q^2/4/8 it prints out > >>> temp pre >>> q/q^2 = q^-1 >>> temp post q^-1 >>> temp pre q^-1 >>> 4/8 = 0 >>> temp post q^-10 >>> 0 > > Interestingly enough, 4/8=0. I don't know how the hell that works. That's standard behavior for integer math in programming languages. You might want to look into mathn / Rational: irb(main):001:0> 4/8 => 0 irb(main):002:0> require 'mathn' => true irb(main):003:0> 4/8 => 1/2 irb(main):004:0> (4/8).class => Rational irb(main):005:0> (4/8).to_f => 0.5 irb(main):006:0> "%10f" % (4/8) => " 0.500000" > Also, when it goes around for the second time to get 4/8, it puts it > in the first place in the array (array[0]) and not the next space, > which is where I thought this method is supposed to put it. ri must > have this wrong too. > > I don't think you need to know how I divide variables, but just in > case you do: > >>> # Return the result of this instance and var1. >>> # Assumes that the two are like. >>> def /(var) >>> Variable.new(self.base, (self.exponent-var.exponent)) >>> end > > A variable is just a string base and integer exponent. > > PS: I would accept some criticism as long as it's productive, but I do > know that my code is lacking in certain areas (like how it doesn't > check whether or not the variables have like bases), but it is a WIP. Hope the math hint gets you started. Kind regards robert