For the View there are lots o formats.
Writing to the file a conversion to a decimal representation is used.
There is not and cannot be a conversion between dyadic and decimal representations preserving accuracy/resolution completely, and therefore a roundtrip between these representations never can be assured to work reliably.
In addition for historical reasons the decimal representation is "mid-endian" if so-called scientific notation is (needs to be) used. First comes the most significant sign (if any), then a mantissa, and then the more significant magnitude of the amount.
Since the live representation is dyadic, it can rather easily be converted to a representation in hexadfecadic digits. The reverse conversion is also feasible (even with a bit less effort).
And mainly: Both conversions are round-trip-proof (if I not am, on error).
Some time ago I wrote raw Basic code for the mentioned conversions:
Code: Select all
REM The "Calc" representation of a number here means the default.
REM This is IEEE 754 Double in RAM, but always shown in a specific format
REM in spreadsheets, and stored to files in a rounded decimal format.
REM The "DblHEX" representation means "like in RAM", everyone of the 8 bytes
REM converted to two hexadecadic digits. Everything "more significant first".
Function calcToDblHex(pNum As Double) As String
calcToDblHex = ":fail:"
On Local Error Goto fail
amount = Abs(pNum)
sign = Sgn(pNum)
rawDyadicExponent = Int(Log(amount) / Log(2))
rawFloatCut = (amount*2^-rawDyadicExponent - 1)
currMantissa = rawFloatCut*(&H1000000)*(&H10000000)'+2^52
offsetDyaExponent = Int(rawDyadicExponent + 1023)
lead12 = IIf(sign<0, &H800, 0) + offsetDyaExponent
startH = Right(Hex(&H1000 + lead12), 3)
out = ""
For j = 0 To 5
quot = Int(currMantissa/&H100)
remi = currMantissa - (quot*&H100)
currMantissa = quot
out = Right(Hex(&H100 + remi), 2) & out
Next j
quot = currMantissa\&H10
remi = currMantissa - (quot*&H10)
currMantissa = quot
out = startH & Right(Hex(&H10 + remi), 1) & out
calcToDblHex = out
fail:
End Function
Function dblHexToCalc(pDblHex As String) As Variant
dblHexToCalc = ":fail:"
If Len(pDblHex)<>16 Then Exit Function
On Local Error Goto fail
Dim bytes(7) As Byte
For j = 0 To 7
bytes(j) = Val("&H" & Mid(pDblHex, j*2+1, 2))
Next j
signBit = (bytes(0)>127)
eLeft = bytes(0) AND &H7F
eRight = (bytes(1) AND &HF0) \ 16
dyaExponent = (eLeft*16 + eRight) - 1023
bytes(1) = (bytes(1) AND &H0F) OR &H10 REM !!!!
Dim mantissa As Double
manStart = CDbl(bytes(1)) / 16
mantissa = CDbl(0)
For k = 7 To 2 Step -1
mantissa = mantissa/256 + CDbl(bytes(k))
Next k
mantissa = (mantissa/(256*16) + manStart)
res = mantissa * (2^dyaExponent) * IIf(signBit, -1, 1)
dblHexToCalc = res
fail:
End Function
The demos below contain randomly generated examples. The AOO version uses the volatile pseudo-random-generators while the other version using the .NV versions will only run in a rather recent LibreOffice. (Of course there will be a more efficient solution with some Python module.)