Difference between revisions of "Converting numbers"

From HaskellWiki
Jump to navigation Jump to search
m (ConvertingNumbers moved to Converting numbers)
(new markup)
Line 3: Line 3:
 
= Integral types =
 
= Integral types =
   
Integral types are ones which may only contain whole numbers and not fractions such as 'Int' and 'Integer' in the standard haskell libraries.
+
Integral types are ones which may only contain whole numbers and not fractions such as <hask>Int</hask> and <hask>Integer</hask> in the standard haskell libraries.
   
the workhorse is 'fromIntegral' which will convert any integral type into another.
+
The workhorse is <hask>fromIntegral</hask> which will convert any integral type into another.
   
 
= Rational types =
 
= Rational types =
   
toRational
+
* <hask>toRational</hask>
fromRational
+
* <hask>fromRational</hask>
   
 
= Going back and forth =
 
= Going back and forth =
Line 16: Line 16:
 
== Integral type to rational type ==
 
== Integral type to rational type ==
   
toRational
+
* <hask>toRational</hask>
   
 
== Rational to Integral ==
 
== Rational to Integral ==
Line 22: Line 22:
 
this is inherently a lossy transformation since integral types cannot express non-whole numbers. depending on how you wish to convert, you might choose one of several methods.
 
this is inherently a lossy transformation since integral types cannot express non-whole numbers. depending on how you wish to convert, you might choose one of several methods.
   
* ceiling
+
* <hask>ceiling</hask>
* floor
+
* <hask>floor</hask>
* truncate
+
* <hask>truncate</hask>
* round
+
* <hask>round</hask>
   
 
= original =
 
= original =
   
 
hi i am trying to write some funs that convert between two coordinate systems. the first coordinate system, which ill call coord1, starts in the upper left at (0, 0) and ends in the lower right at (500, 500). coords in coord1 have type (Int, Int). the second coord system, which ill call coord2, starts in the lower left at (0.0, 0.0) and ends in the upper right at (1.0, 1.0). coords in coord2 have type (Float, Float). i was hoping someone could help me figure out how i can rewrite the two funs below so that the type checker will accept them.
 
hi i am trying to write some funs that convert between two coordinate systems. the first coordinate system, which ill call coord1, starts in the upper left at (0, 0) and ends in the lower right at (500, 500). coords in coord1 have type (Int, Int). the second coord system, which ill call coord2, starts in the lower left at (0.0, 0.0) and ends in the upper right at (1.0, 1.0). coords in coord2 have type (Float, Float). i was hoping someone could help me figure out how i can rewrite the two funs below so that the type checker will accept them.
  +
<haskell>
{{{
 
 
coord1ToCoord2 :: (Int, Int) -> (Float, Float)
 
coord1ToCoord2 :: (Int, Int) -> (Float, Float)
 
coord1ToCoord2 (x, y) = (x/500, (500-y)/500)
 
coord1ToCoord2 (x, y) = (x/500, (500-y)/500)
Line 36: Line 36:
 
coord2ToCoord1 :: (Float, Float) -> (Int, Int)
 
coord2ToCoord1 :: (Float, Float) -> (Int, Int)
 
coord2ToCoord1 (x, y) = (500/(1/x), 500 - 500/(1/y))
 
coord2ToCoord1 (x, y) = (500/(1/x), 500 - 500/(1/y))
  +
</haskell>
}}}
 
 
examples of what i want. i think i have the logic right :)
 
examples of what i want. i think i have the logic right :)
  +
<haskell>
{{{
 
 
coord1ToCoord2 (0, 0) -> (0.0, 1.0)
 
coord1ToCoord2 (0, 0) -> (0.0, 1.0)
 
coord1ToCoord2 (250, 250) -> (0.5, 0.5)
 
coord1ToCoord2 (250, 250) -> (0.5, 0.5)
Line 48: Line 48:
 
coord2ToCoord1 (0.7, 0.7) -> (350, 150)
 
coord2ToCoord1 (0.7, 0.7) -> (350, 150)
 
coord2ToCoord1 (1.0, 1.0) -> (500, 0)
 
coord2ToCoord1 (1.0, 1.0) -> (500, 0)
  +
</haskell>
}}}
 
 
ah. i realize what is messing me up.
 
ah. i realize what is messing me up.
   
 
when i saw an expression like
 
when i saw an expression like
  +
<haskell>
{{{
 
 
500 * 0.2
 
500 * 0.2
  +
</haskell>
}}}
 
 
i had assumed that 500 :: Integer because it didnt end in a .0. but it actually has type Double. so my problem was i would do something like this
 
i had assumed that 500 :: Integer because it didnt end in a .0. but it actually has type Double. so my problem was i would do something like this
  +
<haskell>
{{{
 
 
(toInteger (500 :: Int)) * 0.2
 
(toInteger (500 :: Int)) * 0.2
  +
</haskell>
}}}
 
 
which of course the typechecker wouldnt accept. now that i have rid myself of my incorrect assumptions i see that i should be writing
 
which of course the typechecker wouldnt accept. now that i have rid myself of my incorrect assumptions i see that i should be writing
  +
<haskell>
{{{
 
 
(fromRational (toRational (500 :: Int)) * 0.2) :: Float
 
(fromRational (toRational (500 :: Int)) * 0.2) :: Float
  +
</haskell>
}}}
 
 
now that i have a better understanding i am able to write my funs. thank you for your help :)
 
now that i have a better understanding i am able to write my funs. thank you for your help :)
  +
  +
[[Category:Mathematics]]

Revision as of 15:37, 6 November 2006

Converting between numerical types in haskell must be done explicitly, this is unlike languages like C which automatically cast between numerical types in certain situations.

Integral types

Integral types are ones which may only contain whole numbers and not fractions such as Int and Integer in the standard haskell libraries.

The workhorse is fromIntegral which will convert any integral type into another.

Rational types

* toRational
* fromRational

Going back and forth

Integral type to rational type

* toRational

Rational to Integral

this is inherently a lossy transformation since integral types cannot express non-whole numbers. depending on how you wish to convert, you might choose one of several methods.

* ceiling
* floor
* truncate
* round

original

hi i am trying to write some funs that convert between two coordinate systems. the first coordinate system, which ill call coord1, starts in the upper left at (0, 0) and ends in the lower right at (500, 500). coords in coord1 have type (Int, Int). the second coord system, which ill call coord2, starts in the lower left at (0.0, 0.0) and ends in the upper right at (1.0, 1.0). coords in coord2 have type (Float, Float). i was hoping someone could help me figure out how i can rewrite the two funs below so that the type checker will accept them.

 coord1ToCoord2 :: (Int, Int) -> (Float, Float)
 coord1ToCoord2 (x, y) = (x/500, (500-y)/500)

 coord2ToCoord1 :: (Float, Float) -> (Int, Int)
 coord2ToCoord1 (x, y) = (500/(1/x), 500 - 500/(1/y))

examples of what i want. i think i have the logic right :)

 coord1ToCoord2 (0, 0) -> (0.0, 1.0)
 coord1ToCoord2 (250, 250) -> (0.5, 0.5)
 coord1ToCoord2 (350, 350) -> (0.7, 0.3)
 coord1ToCoord2 (500, 500) -> (1.0, 0.0)

 coord2ToCoord1 (0.0, 0.0) -> (0, 500)
 coord2ToCoord1 (0.5, 0.5) -> (250, 250)
 coord2ToCoord1 (0.7, 0.7) -> (350, 150)
 coord2ToCoord1 (1.0, 1.0) -> (500, 0)

ah. i realize what is messing me up.

when i saw an expression like

 500 * 0.2

i had assumed that 500 :: Integer because it didnt end in a .0. but it actually has type Double. so my problem was i would do something like this

 (toInteger (500 :: Int)) * 0.2

which of course the typechecker wouldnt accept. now that i have rid myself of my incorrect assumptions i see that i should be writing

 (fromRational (toRational (500 :: Int)) * 0.2) :: Float

now that i have a better understanding i am able to write my funs. thank you for your help :)