Author Topic: -= {Challenge} =- convert an hexadecimal into a decimal  (Read 15937 times)

0 Members and 1 Guest are viewing this topic.

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
-= {Challenge} =- convert an hexadecimal into a decimal
« on: October 24, 2011, 10:15:33 AM »
suggesting a new challenge
need to transfer a number from hexadecimal to decimal format.
The difficulty is that the resulting decimal number may be greater than 2147483647

example:
Code: [Select]
(hex2dec "7ffffcf5c20") ;=>>      "8796089834528"
(hex2dec "1234567890abcdef") ;=>> "1311768467294899695"
(hex2dec "fedcba0987654321") ;=>> "18364757930599072545"
(hex2dec "111111111111") ;=>>     "18764998447377"
(hex2dec "ffffffffffff") ;=>>     "281474976710655"
« Last Edit: October 24, 2011, 12:19:06 PM by ElpanovEvgeniy »

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #1 on: October 24, 2011, 12:20:57 PM »
Sorry, I found a bug in my code, changed answers in the test examples!

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #2 on: October 24, 2011, 12:32:51 PM »
Hi,

I have a solution, but it doesn't display good results for very big numbers.

Code: [Select]
(defun hex2dec (hex / r c)
  (setq r 0.)
  (foreach c (vl-string->list (strcase hex))
    (setq r (+
      (* 16. r)
      (-
c
(if (<= c 57)
  48.
  55.
)
      )
    )
    )
  )
  (rtos r 2 0)
)

Quote
_$ (hex2dec "7ffffcf5c20")
"8796089834528"
_$ (hex2dec "111111111111")
"18764998447377"
_$ (hex2dec "ffffffffffff")
"281474976710655"

but:
Quote
_$ (hex2dec "1234567890abcdef")
"1E+18"
_$ (hex2dec "fedcba0987654321")
"2E+19"
Speaking English as a French Frog

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #3 on: October 24, 2011, 12:45:50 PM »
Code: [Select]
(defun hex2dec ( n )
    (defun _ascii2int ( x )
        (- x (if (< x 58) 48.0 55.0))
    )
    (defun _hex2dec ( l )
        (if l (+ (* 16.0 (_hex2dec (cdr l))) (_ascii2int (car l))) 0)
    )
    (defun _dec2str ( n x / d )
        (if (< 0 n)
            (progn
                (setq d (rem (/ n x) 1))
                (strcat (_dec2str (- n (* x d)) (* x 10.0)) (rtos (* 10 d) 2 0))
            )
            ""
        )
    )
    (_dec2str (_hex2dec (reverse (vl-string->list (strcase n)))) 10.0)
)

Code: [Select]
(hex2dec "7ffffcf5c20") ;=>>      "8796089834528"
(hex2dec "1234567890abcdef") ;=>> "1311768467294899800"
(hex2dec "fedcba0987654321") ;=>> "18364757930599073000"
(hex2dec "111111111111") ;=>>     "18764998447377"
(hex2dec "ffffffffffff") ;=>>     "281474976710655"

 :-(

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #4 on: October 24, 2011, 12:53:16 PM »
Hi gile!
You left quite a bit. :)

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #5 on: October 24, 2011, 12:55:19 PM »
Hi Lee Mac!
In your code has a bug.
See if you have
(hex2dec "1234567890abcdef"); =>> "1311768467294899800"
must
(hex2dec "1234567890abcdef"); =>> "1311768467294899695"

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #6 on: October 24, 2011, 01:04:00 PM »
An example of how to check the code if the number is not great ...

David Bethel

  • Swamp Rat
  • Posts: 656
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #7 on: October 24, 2011, 01:04:39 PM »
I hit the same stumbling block:

Code: [Select]

(defun hex2dec (s / e c l)
;;;SINGLE HEX STRING 0-F to Decimal Conversion
(defun hex2dec1 (s / n)
 (setq n (ascii (strcase s)))
 (- n (if (> n 57) 55 48)))

  (setq e 0
        s (strcase s))
  (while (> (strlen s) 0)
         (setq c (substr s (strlen s) 1)
               s (substr s 1 (1- (strlen s)))
               l (cons (* (hex2dec1 c) (expt 2 e)) l)
               e (+ e 4)))
(apply '+ l))

Anything bigger than (expt 2 30) gives bad results.  -David
R12 Dos - A2K

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #8 on: October 24, 2011, 01:07:24 PM »

I hit the same stumbling block:


source of the problem:
Code: [Select]
(1+ 2147483647) = -2147483648

JohnK

  • Administrator
  • Seagull
  • Posts: 10635
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #9 on: October 24, 2011, 01:36:30 PM »
The number 2147483647 is the largest value you can have for a signed int. In C++ you would have to use an unsigned int which would allow you to have an int with a value of 4294967295.

Code: [Select]
(defun bin? (nu / lst nu)
  (while (not (= nu 0))
         (setq lst (cons (rem nu 2) lst)
               nu (/ nu 2)))
  lst
 )

Quote
Command: (bin? 2147483647)
(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)

Command: (length (bin? 2147483647))
31

TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #10 on: October 24, 2011, 01:41:58 PM »
The number 2147483647 is the largest value you can have for a signed int. In C++ you would have to use an unsigned int which would allow you to have an int with a value of 4294967295.

but that does not stop to consider list or texts, for the storage of any size integer  :-)

JohnK

  • Administrator
  • Seagull
  • Posts: 10635
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #11 on: October 24, 2011, 01:53:22 PM »
but that does not stop to consider list or texts, for the storage of any size integer  :-)

That is what I would do too.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #12 on: October 24, 2011, 02:00:23 PM »
This is much easier with F# wich has a BigInterger type.

Code: [Select]
let hex2dec (hex : string) =
    let rec foo chrs result =
        match chrs with
        | [] -> result
        | h :: t -> foo t (16I * result + h - (if h <= 57I then 48I else 55I))
    string (foo (hex.ToUpper() |> Seq.toList |> List.map (fun c -> bigint(int c))) 0I)

Code: [Select]
> hex2dec "7ffffcf5c20" ;;
val it : string = "8796089834528"
> hex2dec "1234567890abcdef" ;;
val it : string = "1311768467294899695"
> hex2dec "fedcba0987654321" ;;
val it : string = "18364757930599072545"
> hex2dec "111111111111" ;;
val it : string = "18764998447377"
> hex2dec "ffffffffffff" ;;
val it : string = "281474976710655"
Speaking English as a French Frog

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #13 on: October 24, 2011, 02:09:58 PM »
This is much easier with F# wich has a BigInterger type.

This is a good way, if you know F # and agree to include it in your project.
My path was through the lisp ...  :-)

JohnK

  • Administrator
  • Seagull
  • Posts: 10635
Re: -= {Challenge} =- convert an hexadecimal into a decimal
« Reply #14 on: October 24, 2011, 02:16:41 PM »
Idea for calculating the list or string length:
(0 . 31) = 2147483647 = 31
(1 . 1) =  2147483648 = 32
(1 . 2) =  2147483649 = 32
...

or something like that.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org