Non-decimal radices/Convert: Difference between revisions

Content added Content deleted
(→‎{{header|J}}: Added dual-mode function.)
(Added Haskell example)
Line 172: Line 172:
Many variants of Forth support literals in some bases, such as hex, using a prefix
Many variants of Forth support literals in some bases, such as hex, using a prefix
$ff . // 255
$ff . // 255

=={{header|Haskell}}==

It's actually more useful to represent digits internally as numbers instead of characters, because then one can define operations that work directly on this representation.

So conversion to and from digits represented as 0-9 and a-z is done in an additional step.

<pre>
import Data.List
import Data.Char

toBase :: Int -> Int -> [Int]
toBase b v = toBase' [] v where
toBase' a 0 = a
toBase' a v = toBase' (r:a) q where (q,r) = v `divMod` b

fromBase :: Int -> [Int] -> Int
fromBase b ds = foldl' (\n k -> n * b + k) 0 ds

toAlphaDigits :: [Int] -> String
toAlphaDigits = map convert where
convert n | n < 10 = chr (n + ord '0')
| otherwise = chr (n + ord 'a')

fromAlphaDigits :: String -> [Int]
fromAlphaDigits = map convert where
convert c | isDigit c = ord c - ord '0'
| isUpper c = ord c - ord 'A' + 10
| isLower c = ord c - ord 'a' + 10
</pre>

Example:

<pre>
*Main> toAlphaDigits $ toBase 16 $ 42
"2a"
*Main> fromBase 16 $ fromAlphaDigits $ "2a"
42
</pre>


=={{header|J}}==
=={{header|J}}==