• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37527

pending completion
#37527

push

local

web-flow
make `IRShow.method_name` inferrable (#49607)

18 of 18 new or added lines in 3 files covered. (100.0%)

68710 of 81829 relevant lines covered (83.97%)

33068903.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.6
/base/ryu/shortest.jl
1
"""
2
    b, e10 = reduce_shortest(f[, maxsignif])
3

4
Reduce to shortest decimal representation where `abs(f) == b * 10^e10` and `b` is an
5
integer. If a `maxsignif` argument is provided, then `b < maxsignif`.
6
"""
7
@inline function reduce_shortest(f::T, maxsignif=nothing) where {T}
197,282✔
8
    U = uinttype(T)
×
9
    uf = reinterpret(U, f)
185,070✔
10
    m = uf & significand_mask(T)
185,070✔
11
    e = ((uf & exponent_mask(T)) >> significand_bits(T)) % Int
185,070✔
12

13
    ## Step 1
14
    #  mf * 2^ef == f
15
    mf = (one(U) << significand_bits(T)) | m
185,070✔
16
    ef = e - exponent_bias(T) - significand_bits(T)
185,070✔
17
    f_isinteger = mf & ((one(U) << -ef) - one(U)) == 0
185,070✔
18

19
    if ef > 0 || ef < -Base.significand_bits(T) || !f_isinteger
370,133✔
20
        # fixup subnormals
21
        if e == 0
168,177✔
22
            ef = 1 - exponent_bias(T) - significand_bits(T)
×
23
            mf = m
×
24
        end
25

26
        ## Step 2
27
        #  u * 2^e2 == (f + prevfloat(f))/2
28
        #  v * 2^e2 == f
29
        #  w * 2^e2 == (f + nextfloat(f))/2
30
        e2 = ef - 2
168,177✔
31
        mf_iseven = iseven(mf) # trailing bit of significand is zero
168,177✔
32

33
        v = U(4) * mf
168,177✔
34
        w = v + U(2)
168,177✔
35
        u_shift_half = m == 0 && e > 1 # if first element of binade, other than first normal one
168,177✔
36
        u = v - U(2) + u_shift_half
168,177✔
37

38
        ## Step 3
39
        #  a == floor(u * 2^e2 / 10^e10), exact if a_allzero
40
        #  b == floor(v * 2^e2 / 10^e10), exact if b_allzero
41
        #  c == floor(w * 2^e2 / 10^e10)
42
        a_allzero = false
×
43
        b_allzero = false
×
44
        b_lastdigit = 0x00
×
45
        if e2 >= 0
168,177✔
46
            q = log10pow2(e2) - (T == Float64 ? (e2 > 3) : 0)
7✔
47
            e10 = q
×
48
            k = pow5_inv_bitcount(T) + pow5bits(q) - 1
7✔
49
            i = -e2 + q + k
7✔
50
            a, b, c = mulshiftinvsplit(T, u, v, w, q, i)
7✔
51
            if T == Float32 || T == Float16
2✔
52
                if q != 0 && div(c - 1, 10) <= div(a, 10)
5✔
53
                    l = pow5_inv_bitcount(T) + pow5bits(q - 1) - 1
×
54
                    mul = pow5invsplit_lookup(T, q-1)
×
55
                    b_lastdigit = (mulshift(v, mul, -e2 + q - 1 + l) % 10) % UInt8
×
56
                end
57
            end
58
            if q <= qinvbound(T)
7✔
59
                if ((v % UInt32) - 5 * div(v, 5)) == 0
6✔
60
                    b_allzero = pow5(v, q)
3✔
61
                elseif mf_iseven
3✔
62
                    a_allzero = pow5(u, q)
2✔
63
                else
64
                    c -= pow5(w, q)
8✔
65
                end
66
            end
67
        else
68
            q = log10pow5(-e2) - (T == Float64 ? (-e2 > 1) : 0)
168,170✔
69
            e10 = q + e2
168,170✔
70
            i = -e2 - q
168,170✔
71
            k = pow5bits(i) - pow5_bitcount(T)
168,170✔
72
            j = q - k
168,170✔
73
            a, b, c = mulshiftsplit(T, u, v, w, i, j)
168,170✔
74
            if T == Float32 || T == Float16
×
75
                if q != 0 && div(c - 1, 10) <= div(a, 10)
61,177✔
76
                    j = q - 1 - (pow5bits(i + 1) - pow5_bitcount(T))
9,392✔
77
                    mul = pow5split_lookup(T, i+1)
9,392✔
78
                    b_lastdigit = (mulshift(v, mul, j) % 10) % UInt8
9,392✔
79
                end
80
            end
81
            if q <= 1
168,170✔
82
                b_allzero = true
×
83
                if mf_iseven
×
84
                    a_allzero = !u_shift_half
×
85
                else
86
                    c -= 1
×
87
                end
88
            elseif q < qbound(T)
168,170✔
89
                b_allzero = pow2(v, q - (T != Float64))
167,761✔
90
            end
91
        end
92

93
        ## Step 4: reduction
94
        if a_allzero || b_allzero
336,353✔
95
            # a) slow loop
96
            while true
24,333✔
97
                c_div10 = div(c, 10)
24,363✔
98
                a_div10 = div(a, 10)
24,359✔
99
                if c_div10 <= a_div10
24,363✔
100
                    break
1,413✔
101
                end
102
                a_mod10 = (a % UInt32) - UInt32(10) * (a_div10 % UInt32)
22,942✔
103
                b_div10 = div(b, 10)
22,942✔
104
                b_mod10 = (b % UInt32) - UInt32(10) * (b_div10 % UInt32)
22,942✔
105
                a_allzero &= a_mod10 == 0
22,920✔
106
                b_allzero &= b_lastdigit == 0
22,920✔
107
                b_lastdigit = b_mod10 % UInt8
22,920✔
108
                b = b_div10
×
109
                c = c_div10
×
110
                a = a_div10
×
111
                e10 += 1
22,920✔
112
            end
22,920✔
113
            if a_allzero
1,413✔
114
                while true
×
115
                    a_div10 = div(a, 10)
×
116
                    a_mod10 = (a % UInt32) - UInt32(10) * (a_div10 % UInt32)
×
117
                    if a_mod10 != 0 && (maxsignif === nothing || b < maxsignif)
×
118
                        break
×
119
                    end
120
                    c_div10 = div(c, 10)
×
121
                    b_div10 = div(b, 10)
×
122
                    b_mod10 = (b % UInt32) - UInt32(10) * (b_div10 % UInt32)
×
123
                    b_allzero &= b_lastdigit == 0
×
124
                    b_lastdigit = b_mod10 % UInt8
×
125
                    b = b_div10
×
126
                    c = c_div10
×
127
                    a = a_div10
×
128
                    e10 += 1
×
129
                end
×
130
            end
131
            if b_allzero && b_lastdigit == 5 && iseven(b)
1,413✔
132
                b_lastdigit = UInt8(4)
×
133
            end
134
            roundup = (b == a && (!mf_iseven || !a_allzero)) || b_lastdigit >= 5
2,825✔
135
        else
136
            # b) specialized for common case (99% Float64, 96% Float32)
137
            roundup = b_lastdigit >= 5
61,178✔
138
            c_div100 = div(c, 100)
227,942✔
139
            a_div100 = div(a, 100)
166,764✔
140
            if c_div100 > a_div100
227,942✔
141
                b_div100 = div(b, 100)
104,368✔
142
                b_mod100 = (b % UInt32) - UInt32(100) * (b_div100 % UInt32)
104,368✔
143
                roundup = b_mod100 >= 50
104,368✔
144
                b = b_div100
×
145
                c = c_div100
×
146
                a = a_div100
×
147
                e10 += 2
104,368✔
148
            end
149
            while true
471,061✔
150
                c_div10 = div(c, 10)
574,864✔
151
                a_div10 = div(a, 10)
526,495✔
152
                if c_div10 <= a_div10
574,864✔
153
                    break
166,764✔
154
                end
155
                b_div10 = div(b, 10)
305,894✔
156
                b_mod10 = (b % UInt32) - UInt32(10) * (b_div10 % UInt32)
305,894✔
157
                roundup = b_mod10 >= 5
304,297✔
158
                b = b_div10
×
159
                c = c_div10
×
160
                a = a_div10
×
161
                e10 += 1
304,297✔
162
            end
304,297✔
163
            roundup = (b == a || roundup)
220,601✔
164
        end
165
        if maxsignif !== nothing && b > maxsignif
220,011✔
166
            # reduce to max significant digits
167
            while true
1,094,447✔
168
                b_div10 = div(b, 10)
1,238,303✔
169
                b_mod10 = (b % UInt32) - UInt32(10) * (b_div10 % UInt32)
1,238,303✔
170
                if b <= maxsignif
1,238,303✔
171
                    break
139,237✔
172
                end
173
                b = b_div10
×
174
                roundup = (b_allzero && iseven(b)) ? b_mod10 > 5 : b_mod10 >= 5
1,910,420✔
175
                b_allzero &= b_mod10 == 0
955,210✔
176
                e10 += 1
955,210✔
177
            end
955,210✔
178
            b = b + roundup
195,217✔
179

180
            # remove trailing zeros
181
            while true
154,811✔
182
                b_div10 = div(b, 10)
217,121✔
183
                b_mod10 = (b % UInt32) - UInt32(10) * (b_div10 % UInt32)
217,121✔
184
                if b_mod10 != 0
154,811✔
185
                    break
139,237✔
186
                end
187
                b = b_div10
×
188
                e10 += 1
15,574✔
189
            end
154,811✔
190
        else
191
            b = b + roundup
173,779✔
192
        end
193
    else
194
        # c) specialized f an integer < 2^53
195
        b = mf >> -ef
16,893✔
196
        e10 = 0
×
197

198
        if maxsignif !== nothing && b > maxsignif
13,330✔
199
            b_allzero = true
×
200
            # reduce to max significant digits
201
            while true
×
202
                b_div10 = div(b, 10)
×
203
                b_mod10 = (b % UInt32) - UInt32(10) * (b_div10 % UInt32)
×
204
                if b <= maxsignif
×
205
                    break
×
206
                end
207
                b = b_div10
×
208
                roundup = (b_allzero && iseven(b)) ? b_mod10 > 5 : b_mod10 >= 5
×
209
                b_allzero &= b_mod10 == 0
×
210
                e10 += 1
×
211
            end
×
212
            b = b + roundup
×
213
        end
214
        while true
17,387✔
215
            b_div10 = div(b, 10)
17,387✔
216
            b_mod10 = (b % UInt32) - UInt32(10) * (b_div10 % UInt32)
17,387✔
217
            if b_mod10 != 0
17,387✔
218
                break
16,893✔
219
            end
220
            b = b_div10
×
221
            e10 += 1
494✔
222
        end
494✔
223
    end
224
    return b, e10
185,070✔
225
end
226

227
function writeshortest(buf::Vector{UInt8}, pos, x::T,
477,249✔
228
                       plus=false, space=false, hash=true,
229
                       precision=-1, expchar=UInt8('e'), padexp=false, decchar=UInt8('.'),
230
                       typed=false, compact=false) where {T}
231
    @assert 0 < pos <= length(buf)
477,249✔
232
    # special cases
233
    if x == 0
477,241✔
234
        if typed && x isa Float16
287,816✔
235
            buf[pos] = UInt8('F')
2✔
236
            buf[pos + 1] = UInt8('l')
2✔
237
            buf[pos + 2] = UInt8('o')
2✔
238
            buf[pos + 3] = UInt8('a')
2✔
239
            buf[pos + 4] = UInt8('t')
2✔
240
            buf[pos + 5] = UInt8('1')
2✔
241
            buf[pos + 6] = UInt8('6')
2✔
242
            buf[pos + 7] = UInt8('(')
2✔
243
            pos += 8
2✔
244
        end
245
        pos = append_sign(x, plus, space, buf, pos)
575,617✔
246
        buf[pos] = UInt8('0')
287,816✔
247
        pos += 1
287,816✔
248
        if hash
287,816✔
249
            buf[pos] = decchar
287,816✔
250
            pos += 1
287,816✔
251
        end
252
        if precision == -1
287,816✔
253
            buf[pos] = UInt8('0')
287,816✔
254
            pos += 1
287,816✔
255
            if typed && x isa Float32
287,816✔
256
                buf[pos] = UInt8('f')
361✔
257
                buf[pos + 1] = UInt8('0')
361✔
258
                pos += 2
361✔
259
            end
260
            if typed && x isa Float16
287,816✔
261
                buf[pos] = UInt8(')')
2✔
262
                pos += 1
2✔
263
            end
264
            return pos
287,816✔
265
        end
266
        while hash && precision > 1
×
267
            buf[pos] = UInt8('0')
×
268
            pos += 1
×
269
            precision -= 1
×
270
        end
×
271
        if typed && x isa Float32
×
272
            buf[pos] = UInt8('f')
×
273
            buf[pos + 1] = UInt8('0')
×
274
            pos += 2
×
275
        end
276
        if typed && x isa Float16
×
277
            buf[pos] = UInt8(')')
×
278
            pos += 1
×
279
        end
280
        return pos
×
281
    elseif isnan(x)
189,425✔
282
        pos = append_sign(x, plus, space, buf, pos)
3,582✔
283
        buf[pos] = UInt8('N')
1,791✔
284
        buf[pos + 1] = UInt8('a')
1,791✔
285
        buf[pos + 2] = UInt8('N')
1,791✔
286
        if typed
1,791✔
287
            if x isa Float32
×
288
                buf[pos + 3] = UInt8('3')
2✔
289
                buf[pos + 4] = UInt8('2')
2✔
290
            elseif x isa Float16
2✔
291
                buf[pos + 3] = UInt8('1')
2✔
292
                buf[pos + 4] = UInt8('6')
2✔
293
            end
294
        end
295
        return pos + 3 + (typed && x isa Union{Float32, Float16} ? 2 : 0)
1,791✔
296
    elseif !isfinite(x)
187,634✔
297
        pos = append_sign(x, plus, space, buf, pos)
4,336✔
298
        buf[pos] = UInt8('I')
2,564✔
299
        buf[pos + 1] = UInt8('n')
2,564✔
300
        buf[pos + 2] = UInt8('f')
2,564✔
301
        if typed
2,564✔
302
            if x isa Float32
×
303
                buf[pos + 3] = UInt8('3')
2✔
304
                buf[pos + 4] = UInt8('2')
2✔
305
            elseif x isa Float16
3✔
306
                buf[pos + 3] = UInt8('1')
3✔
307
                buf[pos + 4] = UInt8('6')
3✔
308
            end
309
        end
310
        return pos + 3 + (typed && x isa Union{Float32, Float16} ? 2 : 0)
2,564✔
311
    end
312

313
    output, nexp = reduce_shortest(x, compact ? 999_999 : nothing)
188,477✔
314

315
    if typed && x isa Float16
185,070✔
316
        buf[pos] = UInt8('F')
6✔
317
        buf[pos + 1] = UInt8('l')
6✔
318
        buf[pos + 2] = UInt8('o')
6✔
319
        buf[pos + 3] = UInt8('a')
6✔
320
        buf[pos + 4] = UInt8('t')
6✔
321
        buf[pos + 5] = UInt8('1')
6✔
322
        buf[pos + 6] = UInt8('6')
6✔
323
        buf[pos + 7] = UInt8('(')
6✔
324
        pos += 8
6✔
325
    end
326
    pos = append_sign(x, plus, space, buf, pos)
315,230✔
327

328
    olength = decimallength(output)
306,757✔
329
    exp_form = true
×
330
    pt = nexp + olength
185,070✔
331
    if -4 < pt <= (precision == -1 ? (T == Float16 ? 3 : 6) : precision) &&
201,970✔
332
        !(pt >= olength && abs(mod(x + 0.05, 10^(pt - olength)) - 0.05) > 0.05)
333
        exp_form = false
×
334
        if pt <= 0
182,291✔
335
            buf[pos] = UInt8('0')
136,301✔
336
            pos += 1
136,301✔
337
            buf[pos] = decchar
136,301✔
338
            pos += 1
136,301✔
339
            for _ = 1:abs(pt)
163,903✔
340
                buf[pos] = UInt8('0')
30,442✔
341
                pos += 1
30,442✔
342
            end
33,282✔
343
            # elseif pt >= olength
344
            # nothing to do at this point
345
            # else
346
            # nothing to do at this point
347
        end
348
    else
349
        pos += 1
2,779✔
350
    end
351
    i = 0
185,070✔
352
    ptr = pointer(buf)
185,070✔
353
    ptr2 = pointer(DIGIT_TABLE)
185,070✔
354
    if (output >> 32) != 0
245,907✔
355
        q = output ÷ 100000000
6,742✔
356
        output2 = (output % UInt32) - UInt32(100000000) * (q % UInt32)
6,742✔
357
        output = q
×
358

359
        c = output2 % UInt32(10000)
6,742✔
360
        output2 = div(output2, UInt32(10000))
6,742✔
361
        d = output2 % UInt32(10000)
6,742✔
362
        c0 = (c % 100) << 1
6,742✔
363
        c1 = (c ÷ 100) << 1
6,742✔
364
        d0 = (d % 100) << 1
6,742✔
365
        d1 = (d ÷ 100) << 1
6,742✔
366
        memcpy(ptr, pos + olength - 2, ptr2, c0 + 1, 2)
6,742✔
367
        memcpy(ptr, pos + olength - 4, ptr2, c1 + 1, 2)
6,742✔
368
        memcpy(ptr, pos + olength - 6, ptr2, d0 + 1, 2)
6,742✔
369
        memcpy(ptr, pos + olength - 8, ptr2, d1 + 1, 2)
6,742✔
370
        i += 8
×
371
    end
372
    output2 = output % UInt32
245,907✔
373
    while output2 >= 10000
337,243✔
374
        c = output2 % UInt32(10000)
152,173✔
375
        output2 = div(output2, UInt32(10000))
152,173✔
376
        c0 = (c % 100) << 1
152,173✔
377
        c1 = (c ÷ 100) << 1
152,173✔
378
        memcpy(ptr, pos + olength - i - 2, ptr2, c0 + 1, 2)
152,173✔
379
        memcpy(ptr, pos + olength - i - 4, ptr2, c1 + 1, 2)
152,173✔
380
        i += 4
152,173✔
381
    end
152,173✔
382
    if output2 >= 100
185,070✔
383
        c = (output2 % UInt32(100)) << 1
10,630✔
384
        output2 = div(output2, UInt32(100))
10,630✔
385
        memcpy(ptr, pos + olength - i - 2, ptr2, c + 1, 2)
10,630✔
386
        i += 2
×
387
    end
388
    if output2 >= 10
185,070✔
389
        c = output2 << 1
141,873✔
390
        buf[pos + 1] = DIGIT_TABLE[c + 2]
141,873✔
391
        buf[pos - exp_form] = DIGIT_TABLE[c + 1]
141,873✔
392
    else
393
        buf[pos - exp_form] = UInt8('0') + (output2 % UInt8)
43,197✔
394
    end
395

396
    if !exp_form
185,070✔
397
        if pt <= 0
182,291✔
398
            pos += olength
136,301✔
399
            precision -= olength
136,301✔
400
            while hash && precision > 0
136,301✔
401
                buf[pos] = UInt8('0')
×
402
                pos += 1
×
403
                precision -= 1
×
404
            end
×
405
        elseif pt >= olength
45,990✔
406
            pos += olength
16,896✔
407
            precision -= olength
16,896✔
408
            for _ = 1:nexp
17,263✔
409
                buf[pos] = UInt8('0')
488✔
410
                pos += 1
488✔
411
                precision -= 1
488✔
412
            end
609✔
413
            if hash
16,896✔
414
                buf[pos] = decchar
16,896✔
415
                pos += 1
16,896✔
416
                if precision < 0
16,896✔
417
                    buf[pos] = UInt8('0')
16,896✔
418
                    pos += 1
16,896✔
419
                end
420
                while precision > 0
16,896✔
421
                    buf[pos] = UInt8('0')
×
422
                    pos += 1
×
423
                    precision -= 1
×
424
                end
×
425
            end
426
        else
427
            pointoff = olength - abs(nexp)
29,094✔
428
            memmove(ptr, pos + pointoff + 1, ptr, pos + pointoff, olength - pointoff + 1)
29,094✔
429
            buf[pos + pointoff] = decchar
29,094✔
430
            pos += olength + 1
29,094✔
431
            precision -= olength
29,094✔
432
            while hash && precision > 0
29,094✔
433
                buf[pos] = UInt8('0')
×
434
                pos += 1
×
435
                precision -= 1
×
436
            end
×
437
        end
438
        if typed && x isa Float32
182,291✔
439
            buf[pos] = UInt8('f')
1,735✔
440
            buf[pos + 1] = UInt8('0')
1,735✔
441
            pos += 2
118,142✔
442
        end
443
    else
444
        if olength > 1 || hash
4,547✔
445
            buf[pos] = decchar
2,779✔
446
            pos += olength
2,779✔
447
            precision -= olength
2,779✔
448
        end
449
        if hash && olength == 1
2,779✔
450
            buf[pos] = UInt8('0')
1,768✔
451
            pos += 1
1,768✔
452
        end
453
        while hash && precision > 0
2,779✔
454
            buf[pos] = UInt8('0')
×
455
            pos += 1
×
456
            precision -= 1
×
457
        end
×
458

459
        buf[pos] = expchar
2,779✔
460
        pos += 1
2,779✔
461
        exp2 = nexp + olength - 1
2,779✔
462
        if exp2 < 0
2,779✔
463
            buf[pos] = UInt8('-')
2,763✔
464
            pos += 1
2,763✔
465
            exp2 = -exp2
2,763✔
466
        elseif padexp
16✔
467
            buf[pos] = UInt8('+')
×
468
            pos += 1
×
469
        end
470

471
        if exp2 >= 100
2,779✔
472
            c = exp2 % 10
6✔
473
            memcpy(ptr, pos, ptr2, 2 * div(exp2, 10) + 1, 2)
6✔
474
            buf[pos + 2] = UInt8('0') + (c % UInt8)
6✔
475
            pos += 3
6✔
476
        elseif exp2 >= 10
2,773✔
477
            memcpy(ptr, pos, ptr2, 2 * exp2 + 1, 2)
715✔
478
            pos += 2
715✔
479
        else
480
            if padexp
2,058✔
481
                buf[pos] = UInt8('0')
×
482
                pos += 1
×
483
            end
484
            buf[pos] = UInt8('0') + (exp2 % UInt8)
2,058✔
485
            pos += 1
2,058✔
486
        end
487
    end
488
    if typed && x isa Float16
185,070✔
489
        buf[pos] = UInt8(')')
6✔
490
        pos += 1
6✔
491
    end
492

493
    return pos
185,070✔
494
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc