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