g | x | w | all
Bytes Lang Time Link
020Julia150628T015123ZM L
045C141202T171458Zuser1525
138Common Lisp141202T163917Zcoredump

Julia, 20 characters

r(h)=hex2num(hex(h))

Function to test the results for correctness:

function decrep()
    tests=[0x4000CCCCCCCCCCCD 0x3DDB7CDFD9D7BDBB 0x40934A456D5CFAAD 0x3FEFFFFFFAA19C47 0xC088A8CF13CEE9DD]
    results=[2.1 1e-10 1234.5678 0.99999999 -789.101112]

    for i=1:length(tests)
        println("input   : $(hex(tests[i]))")
        println("result  : $(r(tests[i]))")
        println("expected: $(results[i])")
        println("$(r(tests[i]) == results[i])")
    end
end

Executing the test function:

julia> decrep()
input   : 4000cccccccccccd
result  : 2.1
expected: 2.1
true
input   : 3ddb7cdfd9d7bdbb
result  : 1.0e-10
expected: 1.0e-10
true
input   : 40934a456d5cfaad
result  : 1234.5678
expected: 1234.5678
true
input   : 3feffffffaa19c47
result  : 0.99999999
expected: 0.99999999
true
input   : c088a8cf13cee9dd
result  : -789.101112
expected: -789.101112
true

If the output absolutely has to be a string, then the solution would be:

s(h)=string(hex2num(hex(h)))

with 28 characters.

julia> h=0x4000cccccccccccd
0x4000cccccccccccd

julia> s(h)=string(hex2num(hex(h)))
s (generic function with 1 method)

julia> s(h)
"2.1"

Summary: Julia rocks, too ;)

C - 47 45 characters

Counting just the function f, and not including #includes and main.

In C, the %g fprintf specifier will always choose the shortest format. Add a precision specifier equal to the usual maximum precision of double and a bit of casting hocus-pocus to coerce int64 to double and Bob's your uncle.

#include <assert.h>
#include <stdint.h>
#include <stdio.h>

// The following line is what I'm counting...
f(int64_t u){printf("%.14g\n",*(double*)&u);}

int main()
{
    assert(sizeof(int64_t) == sizeof(double));

    f(0x4000CCCCCCCCCCCD);
    f(0x3DDB7CDFD9D7BDBB);
    f(0x40934A456D5CFAAD);
    f(0x3FEFFFFFFAA19C47);
    f(0xC088A8CF13CEE9DD);

    return 0;
}

Output is as per specs:

2.1
1e-10
1234.5678
0.99999999
-789.101112

Summary: C rocks!

Common Lisp - 138 bytes

 (ql:quickload'(ieee-floats cl-ppcre))(lambda(x)(#1=ppcre:regex-replace"e0$"(#1#"\\.?d"(format()"~a"(ieee-floats:decode-float64 x))"e")""))

(138 = 101 for the actual function + 37 for quickload'ing libraries)

Ungolfed

The default representation of floating-points in CL is already quite close to the requested output. However, there are some discrepancies. For example, double-precisions numbers are written with a d exponent character (e.g., 2.10d0). That is why I modify the output of the formatted string with regexes:

(ql:quickload '(ieee-floats cl-ppcre))
(lambda (x)
  (cl-ppcre:regex-replace  ; remove "e0" at end of string
     "e0$" 
     (cl-ppcre:regex-replace ; change ".d" and "d" to "e"
       "\\.?d"
       (format nil "~a" (ieee-floats:decode-float64 x))
       "e")
     ""))

Example

;; NB: * is set by the REPL to the last returned value. 
;; Here, we store the previously defined lambda:
(defparameter *fun* *) 

;; Test cases
(defparameter *sample*
  '(#x4000CCCCCCCCCCCD
    #x3DDB7CDFD9D7BDBB
    #x40934A456D5CFAAD
    #x3FEFFFFFFAA19C47
    #xC088A8CF13CEE9DD))

;; Default representation
(mapcar #'ieee-floats:decode-float64 *sample*)
=> (2.1d0 1.d-10 1234.5678d0 0.99999999d0 -789.101112d0)

;; Custom conversion
(mapcar *fun* *sample*)
=> ("2.1" "1e-10" "1234.5678" "0.99999999" "-789.101112")

Round-trip

Here, we convert the printed representations back to IEEE-754 doubles.

;; read values as double-precision numbers
(let ((*read-default-float-format* 'double-float))
  (mapcar #'read-from-string *))
=> (2.1 1.e-10 1234.5678 0.99999999 -789.101112)

;; Encode
(mapcar #'ieee-floats:encode-float64 *)
=> (4611911198408756429 4457293557087583675 4653144502051863213 4607182418709945415 13873524259458836957)

;; Check
(equal * *sample*)
=> T