Converting numbers between bases


#1

I am converting numbers between different bases with JS interop. Is there a better way to do this in Reason? I would like to get rid of the bs.raw chunk.

This is my function:

let convertNumber: (string, int, int) => string = [%bs.raw
  {| (number, fromBase, toBase) => {
    const convertedNumber = parseInt(number, fromBase).toString(toBase)
    return convertedNumber === NaN.toString()
      ? ''
      : convertedNumber.toUpperCase()
   }|}
];

For example, calling convertNumber(89, 10, 2) would return 1011001. (Number 89 from base 10 to base 2)


#2

@ollran I was able to come up with something but with a caveat, you have to pass the number type through with the string.

/*
Convert the given string to an integer. 
The string is read in decimal (by default, or if the string begins with 0u), 
in hexadecimal (if it begins with 0x or 0X), 
in octal (if it begins with 0o or 0O), 
or in binary (if it begins with 0b or 0B).
*/

let convertNum = (num: string, fromBase: int, toBase: int):string => {
  let v = int_of_string(num);
  Js.Int.toStringWithRadix(v, ~radix=toBase);
} 

Also it does not fail safely. I couldn’t use string_of_int_opt pervasive in Ocaml in the ReasonML Try REPL but it might work in a dev environment. Check out more here: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html


#3

I believe this should do the trick! Js.Int.toStringWithRadix will cause an exception if the radix is less than two or greater than 36 so this handles that exception as well :smiley:

let convertNumber = (numString, toBase) => {
  switch (int_of_string(numString), toBase >= 2 && toBase < 36) {
  | exception _ => ""
  | (_, false) => ""
  | (n, true) => Js.Int.toStringWithRadix(n, ~radix=toBase)
  };
};