| Bytes | Lang | Time | Link |
|---|---|---|---|
| 020 | Julia | 150628T015123Z | M L |
| 045 | C | 141202T171458Z | user1525 |
| 138 | Common Lisp | 141202T163917Z | coredump |
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