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.)