File: fixed.jl

package info (click to toggle)
julia 1.5.3%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 91,132 kB
  • sloc: lisp: 278,486; ansic: 60,186; cpp: 29,801; sh: 2,403; makefile: 1,998; pascal: 1,313; objc: 647; javascript: 516; asm: 226; python: 161; xml: 34
file content (210 lines) | stat: -rw-r--r-- 6,063 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
@inline function writefixed(buf, pos, v::T,
    precision=-1, plus=false, space=false, hash=false,
    decchar=UInt8('.'), trimtrailingzeros=false) where {T <: Base.IEEEFloat}
    @assert 0 < pos <= length(buf)
    x = Float64(v)
    neg = signbit(x)
    # special cases
    if x == 0
        if neg
            buf[pos] = UInt8('-')
            pos += 1
        elseif plus
            buf[pos] = UInt8('+')
            pos += 1
        elseif space
            buf[pos] = UInt8(' ')
            pos += 1
        end
        buf[pos] = UInt8('0')
        pos += 1
        if precision > 0
            buf[pos] = decchar
            pos += 1
            if trimtrailingzeros
                precision = 1
            end
            for _ = 1:precision
                buf[pos] = UInt8('0')
                pos += 1
            end
        elseif hash
            buf[pos] = decchar
            pos += 1
        end
        return pos
    elseif isnan(x)
        buf[pos] = UInt8('N')
        buf[pos + 1] = UInt8('a')
        buf[pos + 2] = UInt8('N')
        return pos + 3
    elseif !isfinite(x)
        if neg
            buf[pos] = UInt8('-')
            pos += 1
        elseif plus
            buf[pos] = UInt8('+')
            pos += 1
        elseif space
            buf[pos] = UInt8(' ')
            pos += 1
        end
        buf[pos] = UInt8('I')
        buf[pos + 1] = UInt8('n')
        buf[pos + 2] = UInt8('f')
        return pos + 3
    end

    bits = Core.bitcast(UInt64, x)
    mant = bits & MANTISSA_MASK
    exp = Int((bits >> 52) & EXP_MASK)

    if exp == 0
        e2 = 1 - 1023 - 52
        m2 = mant
    else
        e2 = exp - 1023 - 52
        m2 = (Int64(1) << 52) | mant
    end
    nonzero = false
    if neg
        buf[pos] = UInt8('-')
        pos += 1
    elseif plus
        buf[pos] = UInt8('+')
        pos += 1
    elseif space
        buf[pos] = UInt8(' ')
        pos += 1
    end
    if e2 >= -52
        idx = e2 < 0 ? 0 : indexforexp(e2)
        p10bits = pow10bitsforindex(idx)
        len = lengthforindex(idx)
        i = len - 1
        while i >= 0
            j = p10bits - e2
            #=@inbounds=# mula, mulb, mulc = POW10_SPLIT[POW10_OFFSET[idx + 1] + i + 1]
            digits = mulshiftmod1e9(m2 << 8, mula, mulb, mulc, j + 8)
            if nonzero
                pos = append_nine_digits(digits, buf, pos)
            elseif digits != 0
                olength = decimallength(digits)
                pos = append_n_digits(olength, digits, buf, pos)
                nonzero = true
            end
            i -= 1
        end
    end
    if !nonzero
        buf[pos] = UInt8('0')
        pos += 1
    end
    if precision > 0 || hash
        buf[pos] = decchar
        pos += 1
    end
    if e2 < 0
        idx = div(-e2, 16)
        blocks = div(precision, 9) + 1
        roundUp = 0
        i = 0
        if blocks <= MIN_BLOCK_2[idx + 1]
            i = blocks
            for _ = 1:precision
                buf[pos] = UInt8('0')
                pos += 1
            end
        elseif i < MIN_BLOCK_2[idx + 1]
            i = MIN_BLOCK_2[idx + 1]
            for _ = 1:(9 * i)
                buf[pos] = UInt8('0')
                pos += 1
            end
        end
        while i < blocks
            j = 120 + (-e2 - 16 * idx)
            p = POW10_OFFSET_2[idx + 1] + UInt32(i) - MIN_BLOCK_2[idx + 1]
            if p >= POW10_OFFSET_2[idx + 2]
                for _ = 1:(precision - 9 * i)
                    buf[pos] = UInt8('0')
                    pos += 1
                end
                break
            end
            #=@inbounds=# mula, mulb, mulc = POW10_SPLIT_2[p + 1]
            digits = mulshiftmod1e9(m2 << 8, mula, mulb, mulc, j + 8)
            if i < blocks - 1
                pos = append_nine_digits(digits, buf, pos)
            else
                maximum = precision - 9 * i
                lastDigit = 0
                k = 0
                while k < 9 - maximum
                    # global digits, lastDigit, k
                    lastDigit = digits % 10
                    digits = div(digits, 10)
                    k += 1
                end
                if lastDigit != 5
                    roundUp = lastDigit > 5
                else
                    requiredTwos = -e2 - precision - 1
                    trailingZeros = requiredTwos <= 0 || (requiredTwos < 60 && pow2(m2, requiredTwos))
                    roundUp = trailingZeros ? 2 : 1
                end
                if maximum > 0
                    pos = append_c_digits(maximum, digits, buf, pos)
                end
                break
            end
            i += 1
        end
        if roundUp != 0
            roundPos = pos
            dotPos = 1
            while true
                roundPos -= 1
                if roundPos == 0 || (buf[roundPos] == UInt8('-'))
                    buf[roundPos + 1] = UInt8('1')
                    if dotPos > 1
                        buf[dotPos] = UInt8('0')
                        buf[dotPos + 1] = decchar
                    end
                    buf[pos] = UInt8('0')
                    pos += 1
                    break
                end
                c = roundPos > 0 ? buf[roundPos] : 0x00
                if c == decchar
                    dotPos = roundPos
                    continue
                elseif c == UInt8('9')
                    buf[roundPos] = UInt8('0')
                    roundUp = 1
                    continue
                else
                    if roundUp == 2 && UInt8(c) % 2 == 0
                        break
                    end
                    buf[roundPos] = c + 1
                    break
                end
            end
        end
    else
        for _ = 1:precision
            buf[pos] = UInt8('0')
            pos += 1
        end
    end
    if trimtrailingzeros
        while buf[pos - 1] == UInt8('0')
            pos -= 1
        end
        if buf[pos - 1] == decchar && !hash
            pos -= 1
        end
    end
    return pos
end