# How to save and restore a Float64 value to disk

**URL:** <https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378>\
**Category:** New to Julia\
**Created:** [January 15, 2020, 5:52am UTC](https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378 "2020-01-15T05:52:46Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [January 15, 2020, 5:52am UTC](https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378/1 "2020-01-15T05:52:46Z")

</div>

```julia
n = sqrt(2.0)

"""
How do I save my Float64 value in variable n
to disk in such a way that I can

1. restore back to another variable y
2. such that y is Float64 and has the exact value as n
3. This restoration will work for FUTURE julia version 1.4, 1.5, 1.6, 1.7, 1.8, 1.9
4. Without using any packages. ie I'm not at the mercy of any packages
"""

```

And by exactness, I mean bit to bit exactness.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [January 15, 2020, 8:48am UTC](https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378/2 "2020-01-15T08:48:39Z")

</div>

```julia
julia> n = sqrt(2.0)
1.4142135623730951

julia> write("saved_value", n)
8

julia> y = read("saved_value", Float64)
1.4142135623730951

julia> y == n
true

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 15, 2020, 9:11am UTC](https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378/3 "2020-01-15T09:11:13Z")

</div>

> [@StevenSiew](#):
>
> Without using any packages. ie I’m not at the mercy of any packages

I am not sure why this is a requirement — you can always pin the exact version of the package you are using in your project, and it will work forever.

The solution above suggested by @GunnarFarneback will work on architectures with the same [endianness](https://en.wikipedia.org/wiki/Endianness). Of course in practice you may not encounter a big-endian machine, but when you do, this method will silently corrupt the value.

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [January 15, 2020, 11:14am UTC](https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378/4 "2020-01-15T11:14:08Z")

</div>

> [@GunnarFarneback](#):
>
> y = read(“saved\_value”, Float64)

```julia
$ hexedit saved_value
00000000 CD 3B 7F 66 9E A0 F6 3F .;.f...?
00000010

```

Well, looks like this thing will only work if the endingness of the physical machine is guarantee. Is there a way to store what the ending of the saving machine is so that the restoration can swap the byte order if the endingness is different?

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [January 15, 2020, 11:36am UTC](https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378/5 "2020-01-15T11:36:56Z")

</div>

```julia
n=sqrt(2.0)
s=string(n)
write("saved_value", s)
s_in=read("saved_value",String)
y=parse(Float64,s_in)
y===n

```

🤔 🤣 😉

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 15, 2020, 11:39am UTC](https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378/6 "2020-01-15T11:39:08Z")

</div>

> [@StevenSiew](#):
>
> Is there a way to store what the ending of the saving machine is so that the restoration can swap the byte order if the endingness is different?

I am assuming you mean endianness.

Yes, of course, you can just save it as a character flag or something. You are well on your way to developing your own storage format. And this is usually not a good idea. 😉

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [January 15, 2020, 11:56am UTC](https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378/7 "2020-01-15T11:56:00Z")

</div>

You can use whatever convention you like to document the endianness in the file. A common trick used in file formats is to store a chosen `UInt16` value in the header, then upon reading detect whether it reads as expected or byte-swapped.

Alternatively you just decide that you will always store in little endian format and byteswap as needed on the architecture you’re running on.

```julia
julia> n = sqrt(2.0)
1.4142135623730951

julia> write("saved_value", htol(n))
8

julia> y = ltoh(read("saved_value", Float64))
1.4142135623730951

```

---

<div class="post-metadata">

**Author:** ![lbilli](https://avatars.discourse-cdn.com/v4/letter/l/59ef9b/32.png) [@lbilli](https://discourse.julialang.org/u/lbilli)\
**Post date:** [January 15, 2020, 12:57pm UTC](https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378/8 "2020-01-15T12:57:55Z")

</div>

For a solution that is text based, unambiguous and valid across systems and languages:

```julia
using Printf

julia> n = sqrt(2.0)
1.4142135623730951

julia> @printf("%a", n)
0x1.6a09e667f3bcdp+0

julia> parse(Float64, "0x1.6a09e667f3bcdp+0") == n
true

```

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [January 16, 2020, 5:32am UTC](https://discourse.julialang.org/t/how-to-save-and-restore-a-float64-value-to-disk/33378/9 "2020-01-16T05:32:02Z")

</div>

I better do a write up to summarise all four methods

```julia
using Printf

function SavingFloat_method01(filename,x)
    write(filename, x)
end

function RestoringFloat_method01(filename)
    read(filename,Float64)
end

function SavingFloat_method02(filename,x)
    write(filename, string(x))
end

function RestoringFloat_method02(filename)
    parse(Float64,read(filename,String))
end

function SavingFloat_method03(filename,x)
    write(filename, @sprintf("%a",x))
end

function RestoringFloat_method03(filename)
    parse(Float64,read(filename,String))
end

function SavingFloat_method04(filename,x)
    write(filename, htol(x))
end

function RestoringFloat_method04(filename)
    ltoh(read(filename,Float64))
end

function read_rawbytes(filename)
    IO = open(filename,"r")
    buff = UInt8[]
    while !eof(IO)
        push!(buff,read(IO,UInt8))
    end
    buff
end

""" Value to be saved """
n = sqrt(2.0)

""" Framework for testing """

function framework_test(save_func,restore_func,version)
    save_func("SavedValue_method$(version)",n)
    y = undef
    y = restore_func("SavedValue_method$(version)")
    println("Method$(version): y === n is ",y === n," y=",y," n=",n)
    rawbytes = read_rawbytes("SavedValue_method$(version)")
    # println("typeof(rawbytes) is ",typeof(rawbytes))
    print("rawbytes: ")
    for k in rawbytes
        print(string(k,base=16)," ")
    end
    println()
end

"""
     Testing method 01
"""

framework_test(SavingFloat_method01,
               RestoringFloat_method01,
               "01")

"""
    Testing method 02
"""

framework_test(SavingFloat_method02,
               RestoringFloat_method02,
               "02")

"""
   Testing method 03
"""

framework_test(SavingFloat_method03,
               RestoringFloat_method03,
               "03")

"""
   Testing method 04
"""

framework_test(SavingFloat_method04,
               RestoringFloat_method04,
               "04")

```

The output is

```julia
Method01: y === n is true y=1.4142135623730951 n=1.4142135623730951
rawbytes: cd 3b 7f 66 9e a0 f6 3f 
Method02: y === n is true y=1.4142135623730951 n=1.4142135623730951
rawbytes: 31 2e 34 31 34 32 31 33 35 36 32 33 37 33 30 39 35 31 
Method03: y === n is true y=1.4142135623730951 n=1.4142135623730951
rawbytes: 30 78 31 2e 36 61 30 39 65 36 36 37 66 33 62 63 64 70 2b 30 
Method04: y === n is true y=1.4142135623730951 n=1.4142135623730951
rawbytes: cd 3b 7f 66 9e a0 f6 3f 

```
