Hi Daniel,
I guess I only accidentally got the right answer for c=....
For my r value of 60.0
*Main> truncate $ (+) (logBase 10.0 60.0) 10.0 11 *Main>
and subtract 11 11 == 0
Thanks for correcting me.
Also missed that 11-10=1 simplification. Forest for the trees stuff.
Your translation's definitely an improvement.
I looked for an exponential operator and grabbed the first one I found. In the Prelude (**) is under the heading Methods, while (^^) is under the heading Numeric Functions. Reasoning?
There's a lot of "automatic" stuff going on in Fortan mixed mode expressions, like variables that begin with I-N being integers by default, and the rest being real by default, so it's probably safer to keep things explicit in the Haskell translations.
Thanks
again.
Michael
--- On Sun, 10/25/09, Daniel Fischer <daniel.is.fischer@web.de> wrote:
From: Daniel Fischer <daniel.is.fischer@web.de> Subject: Re: [Haskell-cafe] Fortran mixed mode arithmetic expressions -> Haskell To: haskell-cafe@haskell.org Cc: "michael rice" <nowgate@yahoo.com> Date: Sunday, October 25, 2009, 11:41 PM
Am Montag 26 Oktober 2009 04:21:06 schrieb michael rice: > Translating Fortran mixed mode arithmetic > expressions into Haskell is quite a challenge. > Believe it or not > > c=10.**(11-int(alog10(r)+10)) > > translates to > > let c = (**) 10.0 $ fromIntegral $ subtract 11 $ truncate $ (+) (logBase > 10.0 r) 10.0
No, subtract 11 x is x-11, not 11-x.
let c = 10^^(11 -
(truncate (logBase 10 r) + 10))
or, to make it a little simpler,
let c = 10^^(1 - truncate (logBase 10 r))
Prelude> :t (^^) (^^) :: (Fractional a, Integral b) => a -> b -> a
That is probably faster and more accurate than (**).
> > I finally broke the expression below into two parts > (k1 & k2) to ease translation. I get it that Haskell is > expecting to subtract two Integers and is instead > being given an Integer and a Double. What must > I do to make this work? Are there any guidelines > for doing this kind of translation work? > > Michael > > ================ > > Prelude> let mm = 2 > Prelude> let k1 = 3*mm+2 > Prelude> let k2 = (/) 150 119 > Prelude> let k = k1 - k2 > > <interactive>:1:13: > Couldn't match expected type `Integer' >
against inferred type `Double' > In the second argument of `(-)', namely `k2' > In the expression: k1 - k2 > In the definition of `k': k = k1 - k2 > Prelude> :t 150/119 > 150/119 :: (Fractional t) => t > Prelude>
In this case,
:set -XNoMonoMorphismRestriction
does the trick. In general, you have to use fromInteg[er/ral] and other conversion functions explicitly.
let k = fromIntegral k1 - k2
|